hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/sctp/stream_sched_prio.c
....@@ -1,25 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* SCTP kernel implementation
23 * (C) Copyright Red Hat Inc. 2017
34 *
45 * This file is part of the SCTP kernel implementation
56 *
67 * These functions manipulate sctp stream queue/scheduling.
7
- *
8
- * This SCTP implementation is free software;
9
- * you can redistribute it and/or modify it under the terms of
10
- * the GNU General Public License as published by
11
- * the Free Software Foundation; either version 2, or (at your option)
12
- * any later version.
13
- *
14
- * This SCTP implementation is distributed in the hope that it
15
- * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16
- * ************************
17
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
- * See the GNU General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU General Public License
21
- * along with GNU CC; see the file COPYING. If not, see
22
- * <http://www.gnu.org/licenses/>.
238 *
249 * Please send any bug reports or fixes you make to the
2510 * email addresched(es):
....@@ -40,6 +25,18 @@
4025
4126 static void sctp_sched_prio_unsched_all(struct sctp_stream *stream);
4227
28
+static struct sctp_stream_priorities *sctp_sched_prio_head_get(struct sctp_stream_priorities *p)
29
+{
30
+ p->users++;
31
+ return p;
32
+}
33
+
34
+static void sctp_sched_prio_head_put(struct sctp_stream_priorities *p)
35
+{
36
+ if (p && --p->users == 0)
37
+ kfree(p);
38
+}
39
+
4340 static struct sctp_stream_priorities *sctp_sched_prio_new_head(
4441 struct sctp_stream *stream, int prio, gfp_t gfp)
4542 {
....@@ -53,6 +50,7 @@
5350 INIT_LIST_HEAD(&p->active);
5451 p->next = NULL;
5552 p->prio = prio;
53
+ p->users = 1;
5654
5755 return p;
5856 }
....@@ -68,7 +66,7 @@
6866 */
6967 list_for_each_entry(p, &stream->prio_list, prio_sched) {
7068 if (p->prio == prio)
71
- return p;
69
+ return sctp_sched_prio_head_get(p);
7270 if (p->prio > prio)
7371 break;
7472 }
....@@ -85,7 +83,7 @@
8583 */
8684 break;
8785 if (p->prio == prio)
88
- return p;
86
+ return sctp_sched_prio_head_get(p);
8987 }
9088
9189 /* If not even there, allocate a new one. */
....@@ -169,32 +167,21 @@
169167 struct sctp_stream_out_ext *soute = sout->ext;
170168 struct sctp_stream_priorities *prio_head, *old;
171169 bool reschedule = false;
172
- int i;
170
+
171
+ old = soute->prio_head;
172
+ if (old && old->prio == prio)
173
+ return 0;
173174
174175 prio_head = sctp_sched_prio_get_head(stream, prio, gfp);
175176 if (!prio_head)
176177 return -ENOMEM;
177178
178179 reschedule = sctp_sched_prio_unsched(soute);
179
- old = soute->prio_head;
180180 soute->prio_head = prio_head;
181181 if (reschedule)
182182 sctp_sched_prio_sched(stream, soute);
183183
184
- if (!old)
185
- /* Happens when we set the priority for the first time */
186
- return 0;
187
-
188
- for (i = 0; i < stream->outcnt; i++) {
189
- soute = SCTP_SO(stream, i)->ext;
190
- if (soute && soute->prio_head == old)
191
- /* It's still in use, nothing else to do here. */
192
- return 0;
193
- }
194
-
195
- /* No hits, we are good to free it. */
196
- kfree(old);
197
-
184
+ sctp_sched_prio_head_put(old);
198185 return 0;
199186 }
200187
....@@ -217,6 +204,12 @@
217204 {
218205 INIT_LIST_HEAD(&SCTP_SO(stream, sid)->ext->prio_list);
219206 return sctp_sched_prio_set(stream, sid, 0, gfp);
207
+}
208
+
209
+static void sctp_sched_prio_free_sid(struct sctp_stream *stream, __u16 sid)
210
+{
211
+ sctp_sched_prio_head_put(SCTP_SO(stream, sid)->ext->prio_head);
212
+ SCTP_SO(stream, sid)->ext->prio_head = NULL;
220213 }
221214
222215 static void sctp_sched_prio_free(struct sctp_stream *stream)
....@@ -338,6 +331,7 @@
338331 .get = sctp_sched_prio_get,
339332 .init = sctp_sched_prio_init,
340333 .init_sid = sctp_sched_prio_init_sid,
334
+ .free_sid = sctp_sched_prio_free_sid,
341335 .free = sctp_sched_prio_free,
342336 .enqueue = sctp_sched_prio_enqueue,
343337 .dequeue = sctp_sched_prio_dequeue,