sctp: delete free member from struct sctp_sched_ops
After commit 9ed7bfc795
("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>
This commit is contained in:
Родитель
e6a34faf31
Коммит
7d802c8098
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче