^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* SCTP kernel implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * (C) Copyright Red Hat Inc. 2017
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file is part of the SCTP kernel implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * These functions manipulate sctp stream queue/scheduling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Please send any bug reports or fixes you make to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * email addresched(es):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * lksctp developers <linux-sctp@vger.kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Written or modified by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <net/sctp/sctp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <net/sctp/sm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/sctp/stream_sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* First Come First Serve (a.k.a. FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * RFC DRAFT ndata Section 3.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static int sctp_sched_fcfs_set(struct sctp_stream *stream, __u16 sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) __u16 value, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static int sctp_sched_fcfs_get(struct sctp_stream *stream, __u16 sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) __u16 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int sctp_sched_fcfs_init(struct sctp_stream *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static int sctp_sched_fcfs_init_sid(struct sctp_stream *stream, __u16 sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static void sctp_sched_fcfs_free(struct sctp_stream *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void sctp_sched_fcfs_enqueue(struct sctp_outq *q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct sctp_datamsg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static struct sctp_chunk *sctp_sched_fcfs_dequeue(struct sctp_outq *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct sctp_stream *stream = &q->asoc->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct sctp_chunk *ch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct list_head *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (list_empty(&q->out_chunk_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (stream->out_curr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ch = list_entry(stream->out_curr->ext->outq.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct sctp_chunk, stream_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) entry = q->out_chunk_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ch = list_entry(entry, struct sctp_chunk, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) sctp_sched_dequeue_common(q, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static void sctp_sched_fcfs_dequeue_done(struct sctp_outq *q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static void sctp_sched_fcfs_sched_all(struct sctp_stream *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static void sctp_sched_fcfs_unsched_all(struct sctp_stream *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static struct sctp_sched_ops sctp_sched_fcfs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .set = sctp_sched_fcfs_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .get = sctp_sched_fcfs_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .init = sctp_sched_fcfs_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .init_sid = sctp_sched_fcfs_init_sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .free = sctp_sched_fcfs_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .enqueue = sctp_sched_fcfs_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .dequeue = sctp_sched_fcfs_dequeue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .dequeue_done = sctp_sched_fcfs_dequeue_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .sched_all = sctp_sched_fcfs_sched_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .unsched_all = sctp_sched_fcfs_unsched_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void sctp_sched_ops_fcfs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) sctp_sched_ops_register(SCTP_SS_FCFS, &sctp_sched_fcfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* API to other parts of the stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static struct sctp_sched_ops *sctp_sched_ops[SCTP_SS_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void sctp_sched_ops_register(enum sctp_sched_type sched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct sctp_sched_ops *sched_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) sctp_sched_ops[sched] = sched_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) void sctp_sched_ops_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sctp_sched_ops_fcfs_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) sctp_sched_ops_prio_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) sctp_sched_ops_rr_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int sctp_sched_set_sched(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) enum sctp_sched_type sched)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct sctp_sched_ops *n = sctp_sched_ops[sched];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct sctp_sched_ops *old = asoc->outqueue.sched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct sctp_datamsg *msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct sctp_chunk *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (old == n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (sched > SCTP_SS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (old) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) old->free(&asoc->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* Give the next scheduler a clean slate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) for (i = 0; i < asoc->stream.outcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) void *p = SCTP_SO(&asoc->stream, i)->ext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) p += offsetofend(struct sctp_stream_out_ext, outq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) memset(p, 0, sizeof(struct sctp_stream_out_ext) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) offsetofend(struct sctp_stream_out_ext, outq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) asoc->outqueue.sched = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) n->init(&asoc->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) for (i = 0; i < asoc->stream.outcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!SCTP_SO(&asoc->stream, i)->ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ret = n->init_sid(&asoc->stream, i, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* We have to requeue all chunks already queued. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) list_for_each_entry(ch, &asoc->outqueue.out_chunk_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (ch->msg == msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) msg = ch->msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) n->enqueue(&asoc->outqueue, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) n->free(&asoc->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) asoc->outqueue.sched = &sctp_sched_fcfs; /* Always safe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int sctp_sched_get_sched(struct sctp_association *asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) for (i = 0; i <= SCTP_SS_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (asoc->outqueue.sched == sctp_sched_ops[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int sctp_sched_set_value(struct sctp_association *asoc, __u16 sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) __u16 value, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (sid >= asoc->stream.outcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (!SCTP_SO(&asoc->stream, sid)->ext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ret = sctp_stream_init_ext(&asoc->stream, sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return asoc->outqueue.sched->set(&asoc->stream, sid, value, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int sctp_sched_get_value(struct sctp_association *asoc, __u16 sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) __u16 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (sid >= asoc->stream.outcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (!SCTP_SO(&asoc->stream, sid)->ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return asoc->outqueue.sched->get(&asoc->stream, sid, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) void sctp_sched_dequeue_done(struct sctp_outq *q, struct sctp_chunk *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!list_is_last(&ch->frag_list, &ch->msg->chunks) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) !q->asoc->peer.intl_capable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct sctp_stream_out *sout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) __u16 sid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* datamsg is not finish, so save it as current one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * in case application switch scheduler or a higher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * priority stream comes in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) sid = sctp_chunk_stream_no(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) sout = SCTP_SO(&q->asoc->stream, sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) q->asoc->stream.out_curr = sout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) q->asoc->stream.out_curr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) q->sched->dequeue_done(q, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* Auxiliary functions for the schedulers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) void sctp_sched_dequeue_common(struct sctp_outq *q, struct sctp_chunk *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) list_del_init(&ch->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) list_del_init(&ch->stream_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) q->out_qlen -= ch->skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int sctp_sched_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct sctp_stream_out_ext *ext = SCTP_SO(stream, sid)->ext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) INIT_LIST_HEAD(&ext->outq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return sched->init_sid(stream, sid, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct sctp_sched_ops *sctp_sched_ops_from_stream(struct sctp_stream *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct sctp_association *asoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) asoc = container_of(stream, struct sctp_association, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return asoc->outqueue.sched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }