OSDN Git Service

sctp: delete free member from struct sctp_sched_ops
authorXin Long <lucien.xin@gmail.com>
Wed, 30 Nov 2022 23:04:31 +0000 (18:04 -0500)
committerJakub Kicinski <kuba@kernel.org>
Fri, 2 Dec 2022 04:14:23 +0000 (20:14 -0800)
After commit 9ed7bfc79542 ("sctp: fix memory leak in
sctp_stream_outq_migrate()"), sctp_sched_set_sched() is the only
place calling sched->free(), and it can actually be replaced by
sched->free_sid() on each stream, and yet there's already a loop
to traverse all streams in sctp_sched_set_sched().

This patch adds a function sctp_sched_free_sched() where it calls
sched->free_sid() for each stream to replace sched->free() calls
in sctp_sched_set_sched() and then deletes the unused free member
from struct sctp_sched_ops.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Link: https://lore.kernel.org/r/e10aac150aca2686cb0bd0570299ec716da5a5c0.1669849471.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/sctp/stream_sched.h
net/sctp/stream_sched.c
net/sctp/stream_sched_prio.c
net/sctp/stream_sched_rr.c

index 65058fa..fa00dc2 100644 (file)
@@ -28,8 +28,6 @@ struct sctp_sched_ops {
        int (*init_sid)(struct sctp_stream *stream, __u16 sid, gfp_t gfp);
        /* free a stream */
        void (*free_sid)(struct sctp_stream *stream, __u16 sid);
-       /* Frees the entire thing */
-       void (*free)(struct sctp_stream *stream);
 
        /* Enqueue a chunk */
        void (*enqueue)(struct sctp_outq *q, struct sctp_datamsg *msg);
index 7c8f9d8..3300670 100644 (file)
@@ -50,10 +50,6 @@ static void sctp_sched_fcfs_free_sid(struct sctp_stream *stream, __u16 sid)
 {
 }
 
-static void sctp_sched_fcfs_free(struct sctp_stream *stream)
-{
-}
-
 static void sctp_sched_fcfs_enqueue(struct sctp_outq *q,
                                    struct sctp_datamsg *msg)
 {
@@ -101,7 +97,6 @@ static struct sctp_sched_ops sctp_sched_fcfs = {
        .init = sctp_sched_fcfs_init,
        .init_sid = sctp_sched_fcfs_init_sid,
        .free_sid = sctp_sched_fcfs_free_sid,
-       .free = sctp_sched_fcfs_free,
        .enqueue = sctp_sched_fcfs_enqueue,
        .dequeue = sctp_sched_fcfs_dequeue,
        .dequeue_done = sctp_sched_fcfs_dequeue_done,
@@ -131,6 +126,23 @@ void sctp_sched_ops_init(void)
        sctp_sched_ops_rr_init();
 }
 
+static void sctp_sched_free_sched(struct sctp_stream *stream)
+{
+       struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
+       struct sctp_stream_out_ext *soute;
+       int i;
+
+       sched->unsched_all(stream);
+       for (i = 0; i < stream->outcnt; i++) {
+               soute = SCTP_SO(stream, i)->ext;
+               if (!soute)
+                       continue;
+               sched->free_sid(stream, i);
+               /* Give the next scheduler a clean slate. */
+               memset_after(soute, 0, outq);
+       }
+}
+
 int sctp_sched_set_sched(struct sctp_association *asoc,
                         enum sctp_sched_type sched)
 {
@@ -146,18 +158,8 @@ int sctp_sched_set_sched(struct sctp_association *asoc,
        if (sched > SCTP_SS_MAX)
                return -EINVAL;
 
-       if (old) {
-               old->free(&asoc->stream);
-
-               /* Give the next scheduler a clean slate. */
-               for (i = 0; i < asoc->stream.outcnt; i++) {
-                       struct sctp_stream_out_ext *ext = SCTP_SO(&asoc->stream, i)->ext;
-
-                       if (!ext)
-                               continue;
-                       memset_after(ext, 0, outq);
-               }
-       }
+       if (old)
+               sctp_sched_free_sched(&asoc->stream);
 
        asoc->outqueue.sched = n;
        n->init(&asoc->stream);
@@ -181,7 +183,7 @@ int sctp_sched_set_sched(struct sctp_association *asoc,
        return ret;
 
 err:
-       n->free(&asoc->stream);
+       sctp_sched_free_sched(&asoc->stream);
        asoc->outqueue.sched = &sctp_sched_fcfs; /* Always safe */
 
        return ret;
index 4fc9f29..42d4800 100644 (file)
@@ -222,32 +222,6 @@ static void sctp_sched_prio_free_sid(struct sctp_stream *stream, __u16 sid)
        kfree(prio);
 }
 
-static void sctp_sched_prio_free(struct sctp_stream *stream)
-{
-       struct sctp_stream_priorities *prio, *n;
-       LIST_HEAD(list);
-       int i;
-
-       /* As we don't keep a list of priorities, to avoid multiple
-        * frees we have to do it in 3 steps:
-        *   1. unsched everyone, so the lists are free to use in 2.
-        *   2. build the list of the priorities
-        *   3. free the list
-        */
-       sctp_sched_prio_unsched_all(stream);
-       for (i = 0; i < stream->outcnt; i++) {
-               if (!SCTP_SO(stream, i)->ext)
-                       continue;
-               prio = SCTP_SO(stream, i)->ext->prio_head;
-               if (prio && list_empty(&prio->prio_sched))
-                       list_add(&prio->prio_sched, &list);
-       }
-       list_for_each_entry_safe(prio, n, &list, prio_sched) {
-               list_del_init(&prio->prio_sched);
-               kfree(prio);
-       }
-}
-
 static void sctp_sched_prio_enqueue(struct sctp_outq *q,
                                    struct sctp_datamsg *msg)
 {
@@ -342,7 +316,6 @@ static struct sctp_sched_ops sctp_sched_prio = {
        .init = sctp_sched_prio_init,
        .init_sid = sctp_sched_prio_init_sid,
        .free_sid = sctp_sched_prio_free_sid,
-       .free = sctp_sched_prio_free,
        .enqueue = sctp_sched_prio_enqueue,
        .dequeue = sctp_sched_prio_dequeue,
        .dequeue_done = sctp_sched_prio_dequeue_done,
index cc444fe..1f235e7 100644 (file)
@@ -94,11 +94,6 @@ static void sctp_sched_rr_free_sid(struct sctp_stream *stream, __u16 sid)
 {
 }
 
-static void sctp_sched_rr_free(struct sctp_stream *stream)
-{
-       sctp_sched_rr_unsched_all(stream);
-}
-
 static void sctp_sched_rr_enqueue(struct sctp_outq *q,
                                  struct sctp_datamsg *msg)
 {
@@ -182,7 +177,6 @@ static struct sctp_sched_ops sctp_sched_rr = {
        .init = sctp_sched_rr_init,
        .init_sid = sctp_sched_rr_init_sid,
        .free_sid = sctp_sched_rr_free_sid,
-       .free = sctp_sched_rr_free,
        .enqueue = sctp_sched_rr_enqueue,
        .dequeue = sctp_sched_rr_dequeue,
        .dequeue_done = sctp_sched_rr_dequeue_done,