xref: /openbmc/linux/net/sctp/stream_sched.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
147505b8bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
25bbbbe32SMarcelo Ricardo Leitner /* SCTP kernel implementation
35bbbbe32SMarcelo Ricardo Leitner  * (C) Copyright Red Hat Inc. 2017
45bbbbe32SMarcelo Ricardo Leitner  *
55bbbbe32SMarcelo Ricardo Leitner  * This file is part of the SCTP kernel implementation
65bbbbe32SMarcelo Ricardo Leitner  *
75bbbbe32SMarcelo Ricardo Leitner  * These functions manipulate sctp stream queue/scheduling.
85bbbbe32SMarcelo Ricardo Leitner  *
95bbbbe32SMarcelo Ricardo Leitner  * Please send any bug reports or fixes you make to the
105bbbbe32SMarcelo Ricardo Leitner  * email addresched(es):
115bbbbe32SMarcelo Ricardo Leitner  *    lksctp developers <linux-sctp@vger.kernel.org>
125bbbbe32SMarcelo Ricardo Leitner  *
135bbbbe32SMarcelo Ricardo Leitner  * Written or modified by:
145bbbbe32SMarcelo Ricardo Leitner  *    Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
155bbbbe32SMarcelo Ricardo Leitner  */
165bbbbe32SMarcelo Ricardo Leitner 
175bbbbe32SMarcelo Ricardo Leitner #include <linux/list.h>
185bbbbe32SMarcelo Ricardo Leitner #include <net/sctp/sctp.h>
195bbbbe32SMarcelo Ricardo Leitner #include <net/sctp/sm.h>
205bbbbe32SMarcelo Ricardo Leitner #include <net/sctp/stream_sched.h>
215bbbbe32SMarcelo Ricardo Leitner 
225bbbbe32SMarcelo Ricardo Leitner /* First Come First Serve (a.k.a. FIFO)
235bbbbe32SMarcelo Ricardo Leitner  * RFC DRAFT ndata Section 3.1
245bbbbe32SMarcelo Ricardo Leitner  */
sctp_sched_fcfs_set(struct sctp_stream * stream,__u16 sid,__u16 value,gfp_t gfp)255bbbbe32SMarcelo Ricardo Leitner static int sctp_sched_fcfs_set(struct sctp_stream *stream, __u16 sid,
265bbbbe32SMarcelo Ricardo Leitner 			       __u16 value, gfp_t gfp)
275bbbbe32SMarcelo Ricardo Leitner {
285bbbbe32SMarcelo Ricardo Leitner 	return 0;
295bbbbe32SMarcelo Ricardo Leitner }
305bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_fcfs_get(struct sctp_stream * stream,__u16 sid,__u16 * value)315bbbbe32SMarcelo Ricardo Leitner static int sctp_sched_fcfs_get(struct sctp_stream *stream, __u16 sid,
325bbbbe32SMarcelo Ricardo Leitner 			       __u16 *value)
335bbbbe32SMarcelo Ricardo Leitner {
345bbbbe32SMarcelo Ricardo Leitner 	*value = 0;
355bbbbe32SMarcelo Ricardo Leitner 	return 0;
365bbbbe32SMarcelo Ricardo Leitner }
375bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_fcfs_init(struct sctp_stream * stream)385bbbbe32SMarcelo Ricardo Leitner static int sctp_sched_fcfs_init(struct sctp_stream *stream)
395bbbbe32SMarcelo Ricardo Leitner {
405bbbbe32SMarcelo Ricardo Leitner 	return 0;
415bbbbe32SMarcelo Ricardo Leitner }
425bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_fcfs_init_sid(struct sctp_stream * stream,__u16 sid,gfp_t gfp)435bbbbe32SMarcelo Ricardo Leitner static int sctp_sched_fcfs_init_sid(struct sctp_stream *stream, __u16 sid,
445bbbbe32SMarcelo Ricardo Leitner 				    gfp_t gfp)
455bbbbe32SMarcelo Ricardo Leitner {
465bbbbe32SMarcelo Ricardo Leitner 	return 0;
475bbbbe32SMarcelo Ricardo Leitner }
485bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_fcfs_free_sid(struct sctp_stream * stream,__u16 sid)499ed7bfc7SZhengchao Shao static void sctp_sched_fcfs_free_sid(struct sctp_stream *stream, __u16 sid)
509ed7bfc7SZhengchao Shao {
519ed7bfc7SZhengchao Shao }
529ed7bfc7SZhengchao Shao 
sctp_sched_fcfs_enqueue(struct sctp_outq * q,struct sctp_datamsg * msg)535bbbbe32SMarcelo Ricardo Leitner static void sctp_sched_fcfs_enqueue(struct sctp_outq *q,
545bbbbe32SMarcelo Ricardo Leitner 				    struct sctp_datamsg *msg)
555bbbbe32SMarcelo Ricardo Leitner {
565bbbbe32SMarcelo Ricardo Leitner }
575bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_fcfs_dequeue(struct sctp_outq * q)585bbbbe32SMarcelo Ricardo Leitner static struct sctp_chunk *sctp_sched_fcfs_dequeue(struct sctp_outq *q)
595bbbbe32SMarcelo Ricardo Leitner {
605bbbbe32SMarcelo Ricardo Leitner 	struct sctp_stream *stream = &q->asoc->stream;
615bbbbe32SMarcelo Ricardo Leitner 	struct sctp_chunk *ch = NULL;
625bbbbe32SMarcelo Ricardo Leitner 	struct list_head *entry;
635bbbbe32SMarcelo Ricardo Leitner 
645bbbbe32SMarcelo Ricardo Leitner 	if (list_empty(&q->out_chunk_list))
655bbbbe32SMarcelo Ricardo Leitner 		goto out;
665bbbbe32SMarcelo Ricardo Leitner 
675bbbbe32SMarcelo Ricardo Leitner 	if (stream->out_curr) {
685bbbbe32SMarcelo Ricardo Leitner 		ch = list_entry(stream->out_curr->ext->outq.next,
695bbbbe32SMarcelo Ricardo Leitner 				struct sctp_chunk, stream_list);
705bbbbe32SMarcelo Ricardo Leitner 	} else {
715bbbbe32SMarcelo Ricardo Leitner 		entry = q->out_chunk_list.next;
725bbbbe32SMarcelo Ricardo Leitner 		ch = list_entry(entry, struct sctp_chunk, list);
735bbbbe32SMarcelo Ricardo Leitner 	}
745bbbbe32SMarcelo Ricardo Leitner 
755bbbbe32SMarcelo Ricardo Leitner 	sctp_sched_dequeue_common(q, ch);
765bbbbe32SMarcelo Ricardo Leitner 
775bbbbe32SMarcelo Ricardo Leitner out:
785bbbbe32SMarcelo Ricardo Leitner 	return ch;
795bbbbe32SMarcelo Ricardo Leitner }
805bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_fcfs_dequeue_done(struct sctp_outq * q,struct sctp_chunk * chunk)815bbbbe32SMarcelo Ricardo Leitner static void sctp_sched_fcfs_dequeue_done(struct sctp_outq *q,
825bbbbe32SMarcelo Ricardo Leitner 					 struct sctp_chunk *chunk)
835bbbbe32SMarcelo Ricardo Leitner {
845bbbbe32SMarcelo Ricardo Leitner }
855bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_fcfs_sched_all(struct sctp_stream * stream)865bbbbe32SMarcelo Ricardo Leitner static void sctp_sched_fcfs_sched_all(struct sctp_stream *stream)
875bbbbe32SMarcelo Ricardo Leitner {
885bbbbe32SMarcelo Ricardo Leitner }
895bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_fcfs_unsched_all(struct sctp_stream * stream)905bbbbe32SMarcelo Ricardo Leitner static void sctp_sched_fcfs_unsched_all(struct sctp_stream *stream)
915bbbbe32SMarcelo Ricardo Leitner {
925bbbbe32SMarcelo Ricardo Leitner }
935bbbbe32SMarcelo Ricardo Leitner 
945bbbbe32SMarcelo Ricardo Leitner static struct sctp_sched_ops sctp_sched_fcfs = {
955bbbbe32SMarcelo Ricardo Leitner 	.set = sctp_sched_fcfs_set,
965bbbbe32SMarcelo Ricardo Leitner 	.get = sctp_sched_fcfs_get,
975bbbbe32SMarcelo Ricardo Leitner 	.init = sctp_sched_fcfs_init,
985bbbbe32SMarcelo Ricardo Leitner 	.init_sid = sctp_sched_fcfs_init_sid,
999ed7bfc7SZhengchao Shao 	.free_sid = sctp_sched_fcfs_free_sid,
1005bbbbe32SMarcelo Ricardo Leitner 	.enqueue = sctp_sched_fcfs_enqueue,
1015bbbbe32SMarcelo Ricardo Leitner 	.dequeue = sctp_sched_fcfs_dequeue,
1025bbbbe32SMarcelo Ricardo Leitner 	.dequeue_done = sctp_sched_fcfs_dequeue_done,
1035bbbbe32SMarcelo Ricardo Leitner 	.sched_all = sctp_sched_fcfs_sched_all,
1045bbbbe32SMarcelo Ricardo Leitner 	.unsched_all = sctp_sched_fcfs_unsched_all,
1055bbbbe32SMarcelo Ricardo Leitner };
1065bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_ops_fcfs_init(void)1071ba896f6SXin Long static void sctp_sched_ops_fcfs_init(void)
1081ba896f6SXin Long {
1091ba896f6SXin Long 	sctp_sched_ops_register(SCTP_SS_FCFS, &sctp_sched_fcfs);
1101ba896f6SXin Long }
1111ba896f6SXin Long 
1125bbbbe32SMarcelo Ricardo Leitner /* API to other parts of the stack */
1135bbbbe32SMarcelo Ricardo Leitner 
1141ba896f6SXin Long static struct sctp_sched_ops *sctp_sched_ops[SCTP_SS_MAX + 1];
115637784adSMarcelo Ricardo Leitner 
sctp_sched_ops_register(enum sctp_sched_type sched,struct sctp_sched_ops * sched_ops)1161ba896f6SXin Long void sctp_sched_ops_register(enum sctp_sched_type sched,
1171ba896f6SXin Long 			     struct sctp_sched_ops *sched_ops)
1181ba896f6SXin Long {
1191ba896f6SXin Long 	sctp_sched_ops[sched] = sched_ops;
1201ba896f6SXin Long }
1211ba896f6SXin Long 
sctp_sched_ops_init(void)1221ba896f6SXin Long void sctp_sched_ops_init(void)
1231ba896f6SXin Long {
1241ba896f6SXin Long 	sctp_sched_ops_fcfs_init();
1251ba896f6SXin Long 	sctp_sched_ops_prio_init();
1261ba896f6SXin Long 	sctp_sched_ops_rr_init();
1274821a076SXin Long 	sctp_sched_ops_fc_init();
128*42d452e7SXin Long 	sctp_sched_ops_wfq_init();
1291ba896f6SXin Long }
1305bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_free_sched(struct sctp_stream * stream)1317d802c80SXin Long static void sctp_sched_free_sched(struct sctp_stream *stream)
1327d802c80SXin Long {
1337d802c80SXin Long 	struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
1347d802c80SXin Long 	struct sctp_stream_out_ext *soute;
1357d802c80SXin Long 	int i;
1367d802c80SXin Long 
1377d802c80SXin Long 	sched->unsched_all(stream);
1387d802c80SXin Long 	for (i = 0; i < stream->outcnt; i++) {
1397d802c80SXin Long 		soute = SCTP_SO(stream, i)->ext;
1407d802c80SXin Long 		if (!soute)
1417d802c80SXin Long 			continue;
1427d802c80SXin Long 		sched->free_sid(stream, i);
1437d802c80SXin Long 		/* Give the next scheduler a clean slate. */
1447d802c80SXin Long 		memset_after(soute, 0, outq);
1457d802c80SXin Long 	}
1467d802c80SXin Long }
1477d802c80SXin Long 
sctp_sched_set_sched(struct sctp_association * asoc,enum sctp_sched_type sched)1485bbbbe32SMarcelo Ricardo Leitner int sctp_sched_set_sched(struct sctp_association *asoc,
1495bbbbe32SMarcelo Ricardo Leitner 			 enum sctp_sched_type sched)
1505bbbbe32SMarcelo Ricardo Leitner {
1515bbbbe32SMarcelo Ricardo Leitner 	struct sctp_sched_ops *old = asoc->outqueue.sched;
1525bbbbe32SMarcelo Ricardo Leitner 	struct sctp_datamsg *msg = NULL;
1535bbbbe32SMarcelo Ricardo Leitner 	struct sctp_sched_ops *n;
1545bbbbe32SMarcelo Ricardo Leitner 	struct sctp_chunk *ch;
1555bbbbe32SMarcelo Ricardo Leitner 	int i, ret = 0;
1565bbbbe32SMarcelo Ricardo Leitner 
1575bbbbe32SMarcelo Ricardo Leitner 	if (sched > SCTP_SS_MAX)
1585bbbbe32SMarcelo Ricardo Leitner 		return -EINVAL;
1595bbbbe32SMarcelo Ricardo Leitner 
1605bbbbe32SMarcelo Ricardo Leitner 	n = sctp_sched_ops[sched];
1615bbbbe32SMarcelo Ricardo Leitner 	if (old == n)
1625bbbbe32SMarcelo Ricardo Leitner 		return ret;
1637d802c80SXin Long 
1647d802c80SXin Long 	if (old)
1655bbbbe32SMarcelo Ricardo Leitner 		sctp_sched_free_sched(&asoc->stream);
1665bbbbe32SMarcelo Ricardo Leitner 
1675bbbbe32SMarcelo Ricardo Leitner 	asoc->outqueue.sched = n;
1685bbbbe32SMarcelo Ricardo Leitner 	n->init(&asoc->stream);
16905364ca0SKonstantin Khorenko 	for (i = 0; i < asoc->stream.outcnt; i++) {
1705bbbbe32SMarcelo Ricardo Leitner 		if (!SCTP_SO(&asoc->stream, i)->ext)
1715bbbbe32SMarcelo Ricardo Leitner 			continue;
172b89fc26fSDuoming Zhou 
1735bbbbe32SMarcelo Ricardo Leitner 		ret = n->init_sid(&asoc->stream, i, GFP_ATOMIC);
1745bbbbe32SMarcelo Ricardo Leitner 		if (ret)
1755bbbbe32SMarcelo Ricardo Leitner 			goto err;
1765bbbbe32SMarcelo Ricardo Leitner 	}
1775bbbbe32SMarcelo Ricardo Leitner 
1785bbbbe32SMarcelo Ricardo Leitner 	/* We have to requeue all chunks already queued. */
1795bbbbe32SMarcelo Ricardo Leitner 	list_for_each_entry(ch, &asoc->outqueue.out_chunk_list, list) {
1805bbbbe32SMarcelo Ricardo Leitner 		if (ch->msg == msg)
1815bbbbe32SMarcelo Ricardo Leitner 			continue;
1825bbbbe32SMarcelo Ricardo Leitner 		msg = ch->msg;
1835bbbbe32SMarcelo Ricardo Leitner 		n->enqueue(&asoc->outqueue, msg);
1845bbbbe32SMarcelo Ricardo Leitner 	}
1855bbbbe32SMarcelo Ricardo Leitner 
1865bbbbe32SMarcelo Ricardo Leitner 	return ret;
1875bbbbe32SMarcelo Ricardo Leitner 
1887d802c80SXin Long err:
1895bbbbe32SMarcelo Ricardo Leitner 	sctp_sched_free_sched(&asoc->stream);
1905bbbbe32SMarcelo Ricardo Leitner 	asoc->outqueue.sched = &sctp_sched_fcfs; /* Always safe */
1915bbbbe32SMarcelo Ricardo Leitner 
1925bbbbe32SMarcelo Ricardo Leitner 	return ret;
1935bbbbe32SMarcelo Ricardo Leitner }
1945bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_get_sched(struct sctp_association * asoc)1955bbbbe32SMarcelo Ricardo Leitner int sctp_sched_get_sched(struct sctp_association *asoc)
1965bbbbe32SMarcelo Ricardo Leitner {
1975bbbbe32SMarcelo Ricardo Leitner 	int i;
1985bbbbe32SMarcelo Ricardo Leitner 
1995bbbbe32SMarcelo Ricardo Leitner 	for (i = 0; i <= SCTP_SS_MAX; i++)
2005bbbbe32SMarcelo Ricardo Leitner 		if (asoc->outqueue.sched == sctp_sched_ops[i])
2015bbbbe32SMarcelo Ricardo Leitner 			return i;
2025bbbbe32SMarcelo Ricardo Leitner 
2035bbbbe32SMarcelo Ricardo Leitner 	return 0;
2045bbbbe32SMarcelo Ricardo Leitner }
2055bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_set_value(struct sctp_association * asoc,__u16 sid,__u16 value,gfp_t gfp)2065bbbbe32SMarcelo Ricardo Leitner int sctp_sched_set_value(struct sctp_association *asoc, __u16 sid,
2075bbbbe32SMarcelo Ricardo Leitner 			 __u16 value, gfp_t gfp)
2085bbbbe32SMarcelo Ricardo Leitner {
2095bbbbe32SMarcelo Ricardo Leitner 	if (sid >= asoc->stream.outcnt)
2105bbbbe32SMarcelo Ricardo Leitner 		return -EINVAL;
21105364ca0SKonstantin Khorenko 
2125bbbbe32SMarcelo Ricardo Leitner 	if (!SCTP_SO(&asoc->stream, sid)->ext) {
2135bbbbe32SMarcelo Ricardo Leitner 		int ret;
2145bbbbe32SMarcelo Ricardo Leitner 
2155bbbbe32SMarcelo Ricardo Leitner 		ret = sctp_stream_init_ext(&asoc->stream, sid);
2165bbbbe32SMarcelo Ricardo Leitner 		if (ret)
2175bbbbe32SMarcelo Ricardo Leitner 			return ret;
2185bbbbe32SMarcelo Ricardo Leitner 	}
2195bbbbe32SMarcelo Ricardo Leitner 
2205bbbbe32SMarcelo Ricardo Leitner 	return asoc->outqueue.sched->set(&asoc->stream, sid, value, gfp);
2215bbbbe32SMarcelo Ricardo Leitner }
2225bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_get_value(struct sctp_association * asoc,__u16 sid,__u16 * value)2235bbbbe32SMarcelo Ricardo Leitner int sctp_sched_get_value(struct sctp_association *asoc, __u16 sid,
2245bbbbe32SMarcelo Ricardo Leitner 			 __u16 *value)
2255bbbbe32SMarcelo Ricardo Leitner {
2265bbbbe32SMarcelo Ricardo Leitner 	if (sid >= asoc->stream.outcnt)
2275bbbbe32SMarcelo Ricardo Leitner 		return -EINVAL;
22805364ca0SKonstantin Khorenko 
2295bbbbe32SMarcelo Ricardo Leitner 	if (!SCTP_SO(&asoc->stream, sid)->ext)
2305bbbbe32SMarcelo Ricardo Leitner 		return 0;
2315bbbbe32SMarcelo Ricardo Leitner 
2325bbbbe32SMarcelo Ricardo Leitner 	return asoc->outqueue.sched->get(&asoc->stream, sid, value);
2335bbbbe32SMarcelo Ricardo Leitner }
2345bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_dequeue_done(struct sctp_outq * q,struct sctp_chunk * ch)2355bbbbe32SMarcelo Ricardo Leitner void sctp_sched_dequeue_done(struct sctp_outq *q, struct sctp_chunk *ch)
236ef4775e3SXin Long {
237da1f6d4dSXin Long 	if (!list_is_last(&ch->frag_list, &ch->msg->chunks) &&
2385bbbbe32SMarcelo Ricardo Leitner 	    !q->asoc->peer.intl_capable) {
2395bbbbe32SMarcelo Ricardo Leitner 		struct sctp_stream_out *sout;
2405bbbbe32SMarcelo Ricardo Leitner 		__u16 sid;
2415bbbbe32SMarcelo Ricardo Leitner 
2425bbbbe32SMarcelo Ricardo Leitner 		/* datamsg is not finish, so save it as current one,
2435bbbbe32SMarcelo Ricardo Leitner 		 * in case application switch scheduler or a higher
2445bbbbe32SMarcelo Ricardo Leitner 		 * priority stream comes in.
2455bbbbe32SMarcelo Ricardo Leitner 		 */
24605364ca0SKonstantin Khorenko 		sid = sctp_chunk_stream_no(ch);
2475bbbbe32SMarcelo Ricardo Leitner 		sout = SCTP_SO(&q->asoc->stream, sid);
2485bbbbe32SMarcelo Ricardo Leitner 		q->asoc->stream.out_curr = sout;
2495bbbbe32SMarcelo Ricardo Leitner 		return;
2505bbbbe32SMarcelo Ricardo Leitner 	}
2515bbbbe32SMarcelo Ricardo Leitner 
2525bbbbe32SMarcelo Ricardo Leitner 	q->asoc->stream.out_curr = NULL;
2535bbbbe32SMarcelo Ricardo Leitner 	q->sched->dequeue_done(q, ch);
2545bbbbe32SMarcelo Ricardo Leitner }
2555bbbbe32SMarcelo Ricardo Leitner 
2565bbbbe32SMarcelo Ricardo Leitner /* Auxiliary functions for the schedulers */
sctp_sched_dequeue_common(struct sctp_outq * q,struct sctp_chunk * ch)2575bbbbe32SMarcelo Ricardo Leitner void sctp_sched_dequeue_common(struct sctp_outq *q, struct sctp_chunk *ch)
2585bbbbe32SMarcelo Ricardo Leitner {
2595bbbbe32SMarcelo Ricardo Leitner 	list_del_init(&ch->list);
2605bbbbe32SMarcelo Ricardo Leitner 	list_del_init(&ch->stream_list);
2615bbbbe32SMarcelo Ricardo Leitner 	q->out_qlen -= ch->skb->len;
2625bbbbe32SMarcelo Ricardo Leitner }
2635bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_init_sid(struct sctp_stream * stream,__u16 sid,gfp_t gfp)2645bbbbe32SMarcelo Ricardo Leitner int sctp_sched_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp)
2655bbbbe32SMarcelo Ricardo Leitner {
26605364ca0SKonstantin Khorenko 	struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
2675bbbbe32SMarcelo Ricardo Leitner 	struct sctp_stream_out_ext *ext = SCTP_SO(stream, sid)->ext;
26805364ca0SKonstantin Khorenko 
2695bbbbe32SMarcelo Ricardo Leitner 	INIT_LIST_HEAD(&ext->outq);
2705bbbbe32SMarcelo Ricardo Leitner 	return sched->init_sid(stream, sid, gfp);
2715bbbbe32SMarcelo Ricardo Leitner }
2725bbbbe32SMarcelo Ricardo Leitner 
sctp_sched_ops_from_stream(struct sctp_stream * stream)2735bbbbe32SMarcelo Ricardo Leitner struct sctp_sched_ops *sctp_sched_ops_from_stream(struct sctp_stream *stream)
2745bbbbe32SMarcelo Ricardo Leitner {
2755bbbbe32SMarcelo Ricardo Leitner 	struct sctp_association *asoc;
2765bbbbe32SMarcelo Ricardo Leitner 
2775bbbbe32SMarcelo Ricardo Leitner 	asoc = container_of(stream, struct sctp_association, stream);
2785bbbbe32SMarcelo Ricardo Leitner 
2795bbbbe32SMarcelo Ricardo Leitner 	return asoc->outqueue.sched;
280 }
281