hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/sctp/stream_sched_prio.c
....@@ -25,6 +25,18 @@
2525
2626 static void sctp_sched_prio_unsched_all(struct sctp_stream *stream);
2727
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
+
2840 static struct sctp_stream_priorities *sctp_sched_prio_new_head(
2941 struct sctp_stream *stream, int prio, gfp_t gfp)
3042 {
....@@ -38,6 +50,7 @@
3850 INIT_LIST_HEAD(&p->active);
3951 p->next = NULL;
4052 p->prio = prio;
53
+ p->users = 1;
4154
4255 return p;
4356 }
....@@ -53,7 +66,7 @@
5366 */
5467 list_for_each_entry(p, &stream->prio_list, prio_sched) {
5568 if (p->prio == prio)
56
- return p;
69
+ return sctp_sched_prio_head_get(p);
5770 if (p->prio > prio)
5871 break;
5972 }
....@@ -70,7 +83,7 @@
7083 */
7184 break;
7285 if (p->prio == prio)
73
- return p;
86
+ return sctp_sched_prio_head_get(p);
7487 }
7588
7689 /* If not even there, allocate a new one. */
....@@ -154,32 +167,21 @@
154167 struct sctp_stream_out_ext *soute = sout->ext;
155168 struct sctp_stream_priorities *prio_head, *old;
156169 bool reschedule = false;
157
- int i;
170
+
171
+ old = soute->prio_head;
172
+ if (old && old->prio == prio)
173
+ return 0;
158174
159175 prio_head = sctp_sched_prio_get_head(stream, prio, gfp);
160176 if (!prio_head)
161177 return -ENOMEM;
162178
163179 reschedule = sctp_sched_prio_unsched(soute);
164
- old = soute->prio_head;
165180 soute->prio_head = prio_head;
166181 if (reschedule)
167182 sctp_sched_prio_sched(stream, soute);
168183
169
- if (!old)
170
- /* Happens when we set the priority for the first time */
171
- return 0;
172
-
173
- for (i = 0; i < stream->outcnt; i++) {
174
- soute = SCTP_SO(stream, i)->ext;
175
- if (soute && soute->prio_head == old)
176
- /* It's still in use, nothing else to do here. */
177
- return 0;
178
- }
179
-
180
- /* No hits, we are good to free it. */
181
- kfree(old);
182
-
184
+ sctp_sched_prio_head_put(old);
183185 return 0;
184186 }
185187
....@@ -206,20 +208,8 @@
206208
207209 static void sctp_sched_prio_free_sid(struct sctp_stream *stream, __u16 sid)
208210 {
209
- struct sctp_stream_priorities *prio = SCTP_SO(stream, sid)->ext->prio_head;
210
- int i;
211
-
212
- if (!prio)
213
- return;
214
-
211
+ sctp_sched_prio_head_put(SCTP_SO(stream, sid)->ext->prio_head);
215212 SCTP_SO(stream, sid)->ext->prio_head = NULL;
216
- for (i = 0; i < stream->outcnt; i++) {
217
- if (SCTP_SO(stream, i)->ext &&
218
- SCTP_SO(stream, i)->ext->prio_head == prio)
219
- return;
220
- }
221
-
222
- kfree(prio);
223213 }
224214
225215 static void sctp_sched_prio_free(struct sctp_stream *stream)