stream_sched.c (552c69b36ebd966186573b9c7a286b390935cce1) | stream_sched.c (05364ca03cfd419caecb292fede20eb39667eaae) |
---|---|
1/* SCTP kernel implementation 2 * (C) Copyright Red Hat Inc. 2017 3 * 4 * This file is part of the SCTP kernel implementation 5 * 6 * These functions manipulate sctp stream queue/scheduling. 7 * 8 * This SCTP implementation is free software; --- 147 unchanged lines hidden (view full) --- 156 if (sched > SCTP_SS_MAX) 157 return -EINVAL; 158 159 if (old) { 160 old->free(&asoc->stream); 161 162 /* Give the next scheduler a clean slate. */ 163 for (i = 0; i < asoc->stream.outcnt; i++) { | 1/* SCTP kernel implementation 2 * (C) Copyright Red Hat Inc. 2017 3 * 4 * This file is part of the SCTP kernel implementation 5 * 6 * These functions manipulate sctp stream queue/scheduling. 7 * 8 * This SCTP implementation is free software; --- 147 unchanged lines hidden (view full) --- 156 if (sched > SCTP_SS_MAX) 157 return -EINVAL; 158 159 if (old) { 160 old->free(&asoc->stream); 161 162 /* Give the next scheduler a clean slate. */ 163 for (i = 0; i < asoc->stream.outcnt; i++) { |
164 void *p = asoc->stream.out[i].ext; | 164 void *p = SCTP_SO(&asoc->stream, i)->ext; |
165 166 if (!p) 167 continue; 168 169 p += offsetofend(struct sctp_stream_out_ext, outq); 170 memset(p, 0, sizeof(struct sctp_stream_out_ext) - 171 offsetofend(struct sctp_stream_out_ext, outq)); 172 } 173 } 174 175 asoc->outqueue.sched = n; 176 n->init(&asoc->stream); 177 for (i = 0; i < asoc->stream.outcnt; i++) { | 165 166 if (!p) 167 continue; 168 169 p += offsetofend(struct sctp_stream_out_ext, outq); 170 memset(p, 0, sizeof(struct sctp_stream_out_ext) - 171 offsetofend(struct sctp_stream_out_ext, outq)); 172 } 173 } 174 175 asoc->outqueue.sched = n; 176 n->init(&asoc->stream); 177 for (i = 0; i < asoc->stream.outcnt; i++) { |
178 if (!asoc->stream.out[i].ext) | 178 if (!SCTP_SO(&asoc->stream, i)->ext) |
179 continue; 180 181 ret = n->init_sid(&asoc->stream, i, GFP_KERNEL); 182 if (ret) 183 goto err; 184 } 185 186 /* We have to requeue all chunks already queued. */ --- 25 unchanged lines hidden (view full) --- 212} 213 214int sctp_sched_set_value(struct sctp_association *asoc, __u16 sid, 215 __u16 value, gfp_t gfp) 216{ 217 if (sid >= asoc->stream.outcnt) 218 return -EINVAL; 219 | 179 continue; 180 181 ret = n->init_sid(&asoc->stream, i, GFP_KERNEL); 182 if (ret) 183 goto err; 184 } 185 186 /* We have to requeue all chunks already queued. */ --- 25 unchanged lines hidden (view full) --- 212} 213 214int sctp_sched_set_value(struct sctp_association *asoc, __u16 sid, 215 __u16 value, gfp_t gfp) 216{ 217 if (sid >= asoc->stream.outcnt) 218 return -EINVAL; 219 |
220 if (!asoc->stream.out[sid].ext) { | 220 if (!SCTP_SO(&asoc->stream, sid)->ext) { |
221 int ret; 222 223 ret = sctp_stream_init_ext(&asoc->stream, sid); 224 if (ret) 225 return ret; 226 } 227 228 return asoc->outqueue.sched->set(&asoc->stream, sid, value, gfp); 229} 230 231int sctp_sched_get_value(struct sctp_association *asoc, __u16 sid, 232 __u16 *value) 233{ 234 if (sid >= asoc->stream.outcnt) 235 return -EINVAL; 236 | 221 int ret; 222 223 ret = sctp_stream_init_ext(&asoc->stream, sid); 224 if (ret) 225 return ret; 226 } 227 228 return asoc->outqueue.sched->set(&asoc->stream, sid, value, gfp); 229} 230 231int sctp_sched_get_value(struct sctp_association *asoc, __u16 sid, 232 __u16 *value) 233{ 234 if (sid >= asoc->stream.outcnt) 235 return -EINVAL; 236 |
237 if (!asoc->stream.out[sid].ext) | 237 if (!SCTP_SO(&asoc->stream, sid)->ext) |
238 return 0; 239 240 return asoc->outqueue.sched->get(&asoc->stream, sid, value); 241} 242 243void sctp_sched_dequeue_done(struct sctp_outq *q, struct sctp_chunk *ch) 244{ 245 if (!list_is_last(&ch->frag_list, &ch->msg->chunks) && 246 !q->asoc->intl_enable) { 247 struct sctp_stream_out *sout; 248 __u16 sid; 249 250 /* datamsg is not finish, so save it as current one, 251 * in case application switch scheduler or a higher 252 * priority stream comes in. 253 */ 254 sid = sctp_chunk_stream_no(ch); | 238 return 0; 239 240 return asoc->outqueue.sched->get(&asoc->stream, sid, value); 241} 242 243void sctp_sched_dequeue_done(struct sctp_outq *q, struct sctp_chunk *ch) 244{ 245 if (!list_is_last(&ch->frag_list, &ch->msg->chunks) && 246 !q->asoc->intl_enable) { 247 struct sctp_stream_out *sout; 248 __u16 sid; 249 250 /* datamsg is not finish, so save it as current one, 251 * in case application switch scheduler or a higher 252 * priority stream comes in. 253 */ 254 sid = sctp_chunk_stream_no(ch); |
255 sout = &q->asoc->stream.out[sid]; | 255 sout = SCTP_SO(&q->asoc->stream, sid); |
256 q->asoc->stream.out_curr = sout; 257 return; 258 } 259 260 q->asoc->stream.out_curr = NULL; 261 q->sched->dequeue_done(q, ch); 262} 263 264/* Auxiliary functions for the schedulers */ 265void sctp_sched_dequeue_common(struct sctp_outq *q, struct sctp_chunk *ch) 266{ 267 list_del_init(&ch->list); 268 list_del_init(&ch->stream_list); 269 q->out_qlen -= ch->skb->len; 270} 271 272int sctp_sched_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp) 273{ 274 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream); | 256 q->asoc->stream.out_curr = sout; 257 return; 258 } 259 260 q->asoc->stream.out_curr = NULL; 261 q->sched->dequeue_done(q, ch); 262} 263 264/* Auxiliary functions for the schedulers */ 265void sctp_sched_dequeue_common(struct sctp_outq *q, struct sctp_chunk *ch) 266{ 267 list_del_init(&ch->list); 268 list_del_init(&ch->stream_list); 269 q->out_qlen -= ch->skb->len; 270} 271 272int sctp_sched_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp) 273{ 274 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream); |
275 struct sctp_stream_out_ext *ext = SCTP_SO(stream, sid)->ext; |
|
275 | 276 |
276 INIT_LIST_HEAD(&stream->out[sid].ext->outq); | 277 INIT_LIST_HEAD(&ext->outq); |
277 return sched->init_sid(stream, sid, gfp); 278} 279 280struct sctp_sched_ops *sctp_sched_ops_from_stream(struct sctp_stream *stream) 281{ 282 struct sctp_association *asoc; 283 284 asoc = container_of(stream, struct sctp_association, stream); 285 286 return asoc->outqueue.sched; 287} | 278 return sched->init_sid(stream, sid, gfp); 279} 280 281struct sctp_sched_ops *sctp_sched_ops_from_stream(struct sctp_stream *stream) 282{ 283 struct sctp_association *asoc; 284 285 asoc = container_of(stream, struct sctp_association, stream); 286 287 return asoc->outqueue.sched; 288} |