aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Khorenko <khorenko@virtuozzo.com>2018-08-10 13:11:42 -0400
committerDavid S. Miller <davem@davemloft.net>2018-08-11 15:25:15 -0400
commit05364ca03cfd419caecb292fede20eb39667eaae (patch)
tree134bb5ed07d0dccfb47220d5b760c5e2be8a673f
parentb70f1f3af47f4a21a25678f9ee587ed7986d62f8 (diff)
net/sctp: Make wrappers for accessing in/out streams
This patch introduces wrappers for accessing in/out streams indirectly. This will enable to replace physically contiguous memory arrays of streams with flexible arrays (or maybe any other appropriate mechanism) which do memory allocation on a per-page basis. Signed-off-by: Oleg Babin <obabin@virtuozzo.com> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/sctp/structs.h35
-rw-r--r--net/sctp/chunk.c6
-rw-r--r--net/sctp/outqueue.c11
-rw-r--r--net/sctp/socket.c4
-rw-r--r--net/sctp/stream.c65
-rw-r--r--net/sctp/stream_interleave.c20
-rw-r--r--net/sctp/stream_sched.c13
-rw-r--r--net/sctp/stream_sched_prio.c22
-rw-r--r--net/sctp/stream_sched_rr.c8
9 files changed, 103 insertions, 81 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index ab869e0d8326..6b2b8df8a1d2 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -398,37 +398,35 @@ void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new);
398 398
399/* What is the current SSN number for this stream? */ 399/* What is the current SSN number for this stream? */
400#define sctp_ssn_peek(stream, type, sid) \ 400#define sctp_ssn_peek(stream, type, sid) \
401 ((stream)->type[sid].ssn) 401 (sctp_stream_##type((stream), (sid))->ssn)
402 402
403/* Return the next SSN number for this stream. */ 403/* Return the next SSN number for this stream. */
404#define sctp_ssn_next(stream, type, sid) \ 404#define sctp_ssn_next(stream, type, sid) \
405 ((stream)->type[sid].ssn++) 405 (sctp_stream_##type((stream), (sid))->ssn++)
406 406
407/* Skip over this ssn and all below. */ 407/* Skip over this ssn and all below. */
408#define sctp_ssn_skip(stream, type, sid, ssn) \ 408#define sctp_ssn_skip(stream, type, sid, ssn) \
409 ((stream)->type[sid].ssn = ssn + 1) 409 (sctp_stream_##type((stream), (sid))->ssn = ssn + 1)
410 410
411/* What is the current MID number for this stream? */ 411/* What is the current MID number for this stream? */
412#define sctp_mid_peek(stream, type, sid) \ 412#define sctp_mid_peek(stream, type, sid) \
413 ((stream)->type[sid].mid) 413 (sctp_stream_##type((stream), (sid))->mid)
414 414
415/* Return the next MID number for this stream. */ 415/* Return the next MID number for this stream. */
416#define sctp_mid_next(stream, type, sid) \ 416#define sctp_mid_next(stream, type, sid) \
417 ((stream)->type[sid].mid++) 417 (sctp_stream_##type((stream), (sid))->mid++)
418 418
419/* Skip over this mid and all below. */ 419/* Skip over this mid and all below. */
420#define sctp_mid_skip(stream, type, sid, mid) \ 420#define sctp_mid_skip(stream, type, sid, mid) \
421 ((stream)->type[sid].mid = mid + 1) 421 (sctp_stream_##type((stream), (sid))->mid = mid + 1)
422
423#define sctp_stream_in(asoc, sid) (&(asoc)->stream.in[sid])
424 422
425/* What is the current MID_uo number for this stream? */ 423/* What is the current MID_uo number for this stream? */
426#define sctp_mid_uo_peek(stream, type, sid) \ 424#define sctp_mid_uo_peek(stream, type, sid) \
427 ((stream)->type[sid].mid_uo) 425 (sctp_stream_##type((stream), (sid))->mid_uo)
428 426
429/* Return the next MID_uo number for this stream. */ 427/* Return the next MID_uo number for this stream. */
430#define sctp_mid_uo_next(stream, type, sid) \ 428#define sctp_mid_uo_next(stream, type, sid) \
431 ((stream)->type[sid].mid_uo++) 429 (sctp_stream_##type((stream), (sid))->mid_uo++)
432 430
433/* 431/*
434 * Pointers to address related SCTP functions. 432 * Pointers to address related SCTP functions.
@@ -1463,6 +1461,23 @@ struct sctp_stream {
1463 struct sctp_stream_interleave *si; 1461 struct sctp_stream_interleave *si;
1464}; 1462};
1465 1463
1464static inline struct sctp_stream_out *sctp_stream_out(
1465 const struct sctp_stream *stream,
1466 __u16 sid)
1467{
1468 return ((struct sctp_stream_out *)(stream->out)) + sid;
1469}
1470
1471static inline struct sctp_stream_in *sctp_stream_in(
1472 const struct sctp_stream *stream,
1473 __u16 sid)
1474{
1475 return ((struct sctp_stream_in *)(stream->in)) + sid;
1476}
1477
1478#define SCTP_SO(s, i) sctp_stream_out((s), (i))
1479#define SCTP_SI(s, i) sctp_stream_in((s), (i))
1480
1466#define SCTP_STREAM_CLOSED 0x00 1481#define SCTP_STREAM_CLOSED 0x00
1467#define SCTP_STREAM_OPEN 0x01 1482#define SCTP_STREAM_OPEN 0x01
1468 1483
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index bfb9f812e2ef..ce8087846f05 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -325,7 +325,8 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
325 if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && 325 if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
326 time_after(jiffies, chunk->msg->expires_at)) { 326 time_after(jiffies, chunk->msg->expires_at)) {
327 struct sctp_stream_out *streamout = 327 struct sctp_stream_out *streamout =
328 &chunk->asoc->stream.out[chunk->sinfo.sinfo_stream]; 328 SCTP_SO(&chunk->asoc->stream,
329 chunk->sinfo.sinfo_stream);
329 330
330 if (chunk->sent_count) { 331 if (chunk->sent_count) {
331 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++; 332 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++;
@@ -339,7 +340,8 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
339 } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && 340 } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
340 chunk->sent_count > chunk->sinfo.sinfo_timetolive) { 341 chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
341 struct sctp_stream_out *streamout = 342 struct sctp_stream_out *streamout =
342 &chunk->asoc->stream.out[chunk->sinfo.sinfo_stream]; 343 SCTP_SO(&chunk->asoc->stream,
344 chunk->sinfo.sinfo_stream);
343 345
344 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; 346 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
345 streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++; 347 streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index d68aa33485a9..d74d00b29942 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -80,7 +80,7 @@ static inline void sctp_outq_head_data(struct sctp_outq *q,
80 q->out_qlen += ch->skb->len; 80 q->out_qlen += ch->skb->len;
81 81
82 stream = sctp_chunk_stream_no(ch); 82 stream = sctp_chunk_stream_no(ch);
83 oute = q->asoc->stream.out[stream].ext; 83 oute = SCTP_SO(&q->asoc->stream, stream)->ext;
84 list_add(&ch->stream_list, &oute->outq); 84 list_add(&ch->stream_list, &oute->outq);
85} 85}
86 86
@@ -101,7 +101,7 @@ static inline void sctp_outq_tail_data(struct sctp_outq *q,
101 q->out_qlen += ch->skb->len; 101 q->out_qlen += ch->skb->len;
102 102
103 stream = sctp_chunk_stream_no(ch); 103 stream = sctp_chunk_stream_no(ch);
104 oute = q->asoc->stream.out[stream].ext; 104 oute = SCTP_SO(&q->asoc->stream, stream)->ext;
105 list_add_tail(&ch->stream_list, &oute->outq); 105 list_add_tail(&ch->stream_list, &oute->outq);
106} 106}
107 107
@@ -372,7 +372,7 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
372 sctp_insert_list(&asoc->outqueue.abandoned, 372 sctp_insert_list(&asoc->outqueue.abandoned,
373 &chk->transmitted_list); 373 &chk->transmitted_list);
374 374
375 streamout = &asoc->stream.out[chk->sinfo.sinfo_stream]; 375 streamout = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
376 asoc->sent_cnt_removable--; 376 asoc->sent_cnt_removable--;
377 asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; 377 asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
378 streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; 378 streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
@@ -416,7 +416,7 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
416 asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; 416 asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
417 if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) { 417 if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) {
418 struct sctp_stream_out *streamout = 418 struct sctp_stream_out *streamout =
419 &asoc->stream.out[chk->sinfo.sinfo_stream]; 419 SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
420 420
421 streamout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; 421 streamout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
422 } 422 }
@@ -1082,6 +1082,7 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx,
1082 /* Finally, transmit new packets. */ 1082 /* Finally, transmit new packets. */
1083 while ((chunk = sctp_outq_dequeue_data(ctx->q)) != NULL) { 1083 while ((chunk = sctp_outq_dequeue_data(ctx->q)) != NULL) {
1084 __u32 sid = ntohs(chunk->subh.data_hdr->stream); 1084 __u32 sid = ntohs(chunk->subh.data_hdr->stream);
1085 __u8 stream_state = SCTP_SO(&ctx->asoc->stream, sid)->state;
1085 1086
1086 /* Has this chunk expired? */ 1087 /* Has this chunk expired? */
1087 if (sctp_chunk_abandoned(chunk)) { 1088 if (sctp_chunk_abandoned(chunk)) {
@@ -1091,7 +1092,7 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx,
1091 continue; 1092 continue;
1092 } 1093 }
1093 1094
1094 if (ctx->asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { 1095 if (stream_state == SCTP_STREAM_CLOSED) {
1095 sctp_outq_head_data(ctx->q, chunk); 1096 sctp_outq_head_data(ctx->q, chunk);
1096 break; 1097 break;
1097 } 1098 }
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 502c0d7cb105..e96b15a66aba 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1911,7 +1911,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
1911 goto err; 1911 goto err;
1912 } 1912 }
1913 1913
1914 if (unlikely(!asoc->stream.out[sinfo->sinfo_stream].ext)) { 1914 if (unlikely(!SCTP_SO(&asoc->stream, sinfo->sinfo_stream)->ext)) {
1915 err = sctp_stream_init_ext(&asoc->stream, sinfo->sinfo_stream); 1915 err = sctp_stream_init_ext(&asoc->stream, sinfo->sinfo_stream);
1916 if (err) 1916 if (err)
1917 goto err; 1917 goto err;
@@ -7154,7 +7154,7 @@ static int sctp_getsockopt_pr_streamstatus(struct sock *sk, int len,
7154 if (!asoc || params.sprstat_sid >= asoc->stream.outcnt) 7154 if (!asoc || params.sprstat_sid >= asoc->stream.outcnt)
7155 goto out; 7155 goto out;
7156 7156
7157 streamoute = asoc->stream.out[params.sprstat_sid].ext; 7157 streamoute = SCTP_SO(&asoc->stream, params.sprstat_sid)->ext;
7158 if (!streamoute) { 7158 if (!streamoute) {
7159 /* Not allocated yet, means all stats are 0 */ 7159 /* Not allocated yet, means all stats are 0 */
7160 params.sprstat_abandoned_unsent = 0; 7160 params.sprstat_abandoned_unsent = 0;
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index f1f1d1b232ba..7ca6fe4e7882 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -162,7 +162,7 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt,
162 162
163 stream->outcnt = outcnt; 163 stream->outcnt = outcnt;
164 for (i = 0; i < stream->outcnt; i++) 164 for (i = 0; i < stream->outcnt; i++)
165 stream->out[i].state = SCTP_STREAM_OPEN; 165 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
166 166
167 sched->init(stream); 167 sched->init(stream);
168 168
@@ -193,7 +193,7 @@ int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid)
193 soute = kzalloc(sizeof(*soute), GFP_KERNEL); 193 soute = kzalloc(sizeof(*soute), GFP_KERNEL);
194 if (!soute) 194 if (!soute)
195 return -ENOMEM; 195 return -ENOMEM;
196 stream->out[sid].ext = soute; 196 SCTP_SO(stream, sid)->ext = soute;
197 197
198 return sctp_sched_init_sid(stream, sid, GFP_KERNEL); 198 return sctp_sched_init_sid(stream, sid, GFP_KERNEL);
199} 199}
@@ -205,7 +205,7 @@ void sctp_stream_free(struct sctp_stream *stream)
205 205
206 sched->free(stream); 206 sched->free(stream);
207 for (i = 0; i < stream->outcnt; i++) 207 for (i = 0; i < stream->outcnt; i++)
208 kfree(stream->out[i].ext); 208 kfree(SCTP_SO(stream, i)->ext);
209 kfree(stream->out); 209 kfree(stream->out);
210 kfree(stream->in); 210 kfree(stream->in);
211} 211}
@@ -215,12 +215,12 @@ void sctp_stream_clear(struct sctp_stream *stream)
215 int i; 215 int i;
216 216
217 for (i = 0; i < stream->outcnt; i++) { 217 for (i = 0; i < stream->outcnt; i++) {
218 stream->out[i].mid = 0; 218 SCTP_SO(stream, i)->mid = 0;
219 stream->out[i].mid_uo = 0; 219 SCTP_SO(stream, i)->mid_uo = 0;
220 } 220 }
221 221
222 for (i = 0; i < stream->incnt; i++) 222 for (i = 0; i < stream->incnt; i++)
223 stream->in[i].mid = 0; 223 SCTP_SI(stream, i)->mid = 0;
224} 224}
225 225
226void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new) 226void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new)
@@ -273,8 +273,8 @@ static bool sctp_stream_outq_is_empty(struct sctp_stream *stream,
273 for (i = 0; i < str_nums; i++) { 273 for (i = 0; i < str_nums; i++) {
274 __u16 sid = ntohs(str_list[i]); 274 __u16 sid = ntohs(str_list[i]);
275 275
276 if (stream->out[sid].ext && 276 if (SCTP_SO(stream, sid)->ext &&
277 !list_empty(&stream->out[sid].ext->outq)) 277 !list_empty(&SCTP_SO(stream, sid)->ext->outq))
278 return false; 278 return false;
279 } 279 }
280 280
@@ -361,11 +361,11 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
361 if (out) { 361 if (out) {
362 if (str_nums) 362 if (str_nums)
363 for (i = 0; i < str_nums; i++) 363 for (i = 0; i < str_nums; i++)
364 stream->out[str_list[i]].state = 364 SCTP_SO(stream, str_list[i])->state =
365 SCTP_STREAM_CLOSED; 365 SCTP_STREAM_CLOSED;
366 else 366 else
367 for (i = 0; i < stream->outcnt; i++) 367 for (i = 0; i < stream->outcnt; i++)
368 stream->out[i].state = SCTP_STREAM_CLOSED; 368 SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
369 } 369 }
370 370
371 asoc->strreset_chunk = chunk; 371 asoc->strreset_chunk = chunk;
@@ -380,11 +380,11 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
380 380
381 if (str_nums) 381 if (str_nums)
382 for (i = 0; i < str_nums; i++) 382 for (i = 0; i < str_nums; i++)
383 stream->out[str_list[i]].state = 383 SCTP_SO(stream, str_list[i])->state =
384 SCTP_STREAM_OPEN; 384 SCTP_STREAM_OPEN;
385 else 385 else
386 for (i = 0; i < stream->outcnt; i++) 386 for (i = 0; i < stream->outcnt; i++)
387 stream->out[i].state = SCTP_STREAM_OPEN; 387 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
388 388
389 goto out; 389 goto out;
390 } 390 }
@@ -418,7 +418,7 @@ int sctp_send_reset_assoc(struct sctp_association *asoc)
418 418
419 /* Block further xmit of data until this request is completed */ 419 /* Block further xmit of data until this request is completed */
420 for (i = 0; i < stream->outcnt; i++) 420 for (i = 0; i < stream->outcnt; i++)
421 stream->out[i].state = SCTP_STREAM_CLOSED; 421 SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
422 422
423 asoc->strreset_chunk = chunk; 423 asoc->strreset_chunk = chunk;
424 sctp_chunk_hold(asoc->strreset_chunk); 424 sctp_chunk_hold(asoc->strreset_chunk);
@@ -429,7 +429,7 @@ int sctp_send_reset_assoc(struct sctp_association *asoc)
429 asoc->strreset_chunk = NULL; 429 asoc->strreset_chunk = NULL;
430 430
431 for (i = 0; i < stream->outcnt; i++) 431 for (i = 0; i < stream->outcnt; i++)
432 stream->out[i].state = SCTP_STREAM_OPEN; 432 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
433 433
434 return retval; 434 return retval;
435 } 435 }
@@ -609,10 +609,10 @@ struct sctp_chunk *sctp_process_strreset_outreq(
609 } 609 }
610 610
611 for (i = 0; i < nums; i++) 611 for (i = 0; i < nums; i++)
612 stream->in[ntohs(str_p[i])].mid = 0; 612 SCTP_SI(stream, ntohs(str_p[i]))->mid = 0;
613 } else { 613 } else {
614 for (i = 0; i < stream->incnt; i++) 614 for (i = 0; i < stream->incnt; i++)
615 stream->in[i].mid = 0; 615 SCTP_SI(stream, i)->mid = 0;
616 } 616 }
617 617
618 result = SCTP_STRRESET_PERFORMED; 618 result = SCTP_STRRESET_PERFORMED;
@@ -683,11 +683,11 @@ struct sctp_chunk *sctp_process_strreset_inreq(
683 683
684 if (nums) 684 if (nums)
685 for (i = 0; i < nums; i++) 685 for (i = 0; i < nums; i++)
686 stream->out[ntohs(str_p[i])].state = 686 SCTP_SO(stream, ntohs(str_p[i]))->state =
687 SCTP_STREAM_CLOSED; 687 SCTP_STREAM_CLOSED;
688 else 688 else
689 for (i = 0; i < stream->outcnt; i++) 689 for (i = 0; i < stream->outcnt; i++)
690 stream->out[i].state = SCTP_STREAM_CLOSED; 690 SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
691 691
692 asoc->strreset_chunk = chunk; 692 asoc->strreset_chunk = chunk;
693 asoc->strreset_outstanding = 1; 693 asoc->strreset_outstanding = 1;
@@ -786,11 +786,11 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
786 * incoming and outgoing streams. 786 * incoming and outgoing streams.
787 */ 787 */
788 for (i = 0; i < stream->outcnt; i++) { 788 for (i = 0; i < stream->outcnt; i++) {
789 stream->out[i].mid = 0; 789 SCTP_SO(stream, i)->mid = 0;
790 stream->out[i].mid_uo = 0; 790 SCTP_SO(stream, i)->mid_uo = 0;
791 } 791 }
792 for (i = 0; i < stream->incnt; i++) 792 for (i = 0; i < stream->incnt; i++)
793 stream->in[i].mid = 0; 793 SCTP_SI(stream, i)->mid = 0;
794 794
795 result = SCTP_STRRESET_PERFORMED; 795 result = SCTP_STRRESET_PERFORMED;
796 796
@@ -979,15 +979,18 @@ struct sctp_chunk *sctp_process_strreset_resp(
979 sizeof(__u16); 979 sizeof(__u16);
980 980
981 if (result == SCTP_STRRESET_PERFORMED) { 981 if (result == SCTP_STRRESET_PERFORMED) {
982 struct sctp_stream_out *sout;
982 if (nums) { 983 if (nums) {
983 for (i = 0; i < nums; i++) { 984 for (i = 0; i < nums; i++) {
984 stream->out[ntohs(str_p[i])].mid = 0; 985 sout = SCTP_SO(stream, ntohs(str_p[i]));
985 stream->out[ntohs(str_p[i])].mid_uo = 0; 986 sout->mid = 0;
987 sout->mid_uo = 0;
986 } 988 }
987 } else { 989 } else {
988 for (i = 0; i < stream->outcnt; i++) { 990 for (i = 0; i < stream->outcnt; i++) {
989 stream->out[i].mid = 0; 991 sout = SCTP_SO(stream, i);
990 stream->out[i].mid_uo = 0; 992 sout->mid = 0;
993 sout->mid_uo = 0;
991 } 994 }
992 } 995 }
993 996
@@ -995,7 +998,7 @@ struct sctp_chunk *sctp_process_strreset_resp(
995 } 998 }
996 999
997 for (i = 0; i < stream->outcnt; i++) 1000 for (i = 0; i < stream->outcnt; i++)
998 stream->out[i].state = SCTP_STREAM_OPEN; 1001 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
999 1002
1000 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags, 1003 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
1001 nums, str_p, GFP_ATOMIC); 1004 nums, str_p, GFP_ATOMIC);
@@ -1050,15 +1053,15 @@ struct sctp_chunk *sctp_process_strreset_resp(
1050 asoc->adv_peer_ack_point = asoc->ctsn_ack_point; 1053 asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
1051 1054
1052 for (i = 0; i < stream->outcnt; i++) { 1055 for (i = 0; i < stream->outcnt; i++) {
1053 stream->out[i].mid = 0; 1056 SCTP_SO(stream, i)->mid = 0;
1054 stream->out[i].mid_uo = 0; 1057 SCTP_SO(stream, i)->mid_uo = 0;
1055 } 1058 }
1056 for (i = 0; i < stream->incnt; i++) 1059 for (i = 0; i < stream->incnt; i++)
1057 stream->in[i].mid = 0; 1060 SCTP_SI(stream, i)->mid = 0;
1058 } 1061 }
1059 1062
1060 for (i = 0; i < stream->outcnt; i++) 1063 for (i = 0; i < stream->outcnt; i++)
1061 stream->out[i].state = SCTP_STREAM_OPEN; 1064 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
1062 1065
1063 *evp = sctp_ulpevent_make_assoc_reset_event(asoc, flags, 1066 *evp = sctp_ulpevent_make_assoc_reset_event(asoc, flags,
1064 stsn, rtsn, GFP_ATOMIC); 1067 stsn, rtsn, GFP_ATOMIC);
@@ -1072,7 +1075,7 @@ struct sctp_chunk *sctp_process_strreset_resp(
1072 1075
1073 if (result == SCTP_STRRESET_PERFORMED) 1076 if (result == SCTP_STRRESET_PERFORMED)
1074 for (i = number; i < stream->outcnt; i++) 1077 for (i = number; i < stream->outcnt; i++)
1075 stream->out[i].state = SCTP_STREAM_OPEN; 1078 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
1076 else 1079 else
1077 stream->outcnt = number; 1080 stream->outcnt = number;
1078 1081
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
index d3764c181299..0a78cdf86463 100644
--- a/net/sctp/stream_interleave.c
+++ b/net/sctp/stream_interleave.c
@@ -197,7 +197,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_partial(
197 __u32 next_fsn = 0; 197 __u32 next_fsn = 0;
198 int is_last = 0; 198 int is_last = 0;
199 199
200 sin = sctp_stream_in(ulpq->asoc, event->stream); 200 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream);
201 201
202 skb_queue_walk(&ulpq->reasm, pos) { 202 skb_queue_walk(&ulpq->reasm, pos) {
203 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 203 struct sctp_ulpevent *cevent = sctp_skb2event(pos);
@@ -278,7 +278,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_reassembled(
278 __u32 pd_len = 0; 278 __u32 pd_len = 0;
279 __u32 mid = 0; 279 __u32 mid = 0;
280 280
281 sin = sctp_stream_in(ulpq->asoc, event->stream); 281 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream);
282 282
283 skb_queue_walk(&ulpq->reasm, pos) { 283 skb_queue_walk(&ulpq->reasm, pos) {
284 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 284 struct sctp_ulpevent *cevent = sctp_skb2event(pos);
@@ -368,7 +368,7 @@ static struct sctp_ulpevent *sctp_intl_reasm(struct sctp_ulpq *ulpq,
368 368
369 sctp_intl_store_reasm(ulpq, event); 369 sctp_intl_store_reasm(ulpq, event);
370 370
371 sin = sctp_stream_in(ulpq->asoc, event->stream); 371 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream);
372 if (sin->pd_mode && event->mid == sin->mid && 372 if (sin->pd_mode && event->mid == sin->mid &&
373 event->fsn == sin->fsn) 373 event->fsn == sin->fsn)
374 retval = sctp_intl_retrieve_partial(ulpq, event); 374 retval = sctp_intl_retrieve_partial(ulpq, event);
@@ -575,7 +575,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_partial_uo(
575 __u32 next_fsn = 0; 575 __u32 next_fsn = 0;
576 int is_last = 0; 576 int is_last = 0;
577 577
578 sin = sctp_stream_in(ulpq->asoc, event->stream); 578 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream);
579 579
580 skb_queue_walk(&ulpq->reasm_uo, pos) { 580 skb_queue_walk(&ulpq->reasm_uo, pos) {
581 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 581 struct sctp_ulpevent *cevent = sctp_skb2event(pos);
@@ -659,7 +659,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_reassembled_uo(
659 __u32 pd_len = 0; 659 __u32 pd_len = 0;
660 __u32 mid = 0; 660 __u32 mid = 0;
661 661
662 sin = sctp_stream_in(ulpq->asoc, event->stream); 662 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream);
663 663
664 skb_queue_walk(&ulpq->reasm_uo, pos) { 664 skb_queue_walk(&ulpq->reasm_uo, pos) {
665 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 665 struct sctp_ulpevent *cevent = sctp_skb2event(pos);
@@ -750,7 +750,7 @@ static struct sctp_ulpevent *sctp_intl_reasm_uo(struct sctp_ulpq *ulpq,
750 750
751 sctp_intl_store_reasm_uo(ulpq, event); 751 sctp_intl_store_reasm_uo(ulpq, event);
752 752
753 sin = sctp_stream_in(ulpq->asoc, event->stream); 753 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream);
754 if (sin->pd_mode_uo && event->mid == sin->mid_uo && 754 if (sin->pd_mode_uo && event->mid == sin->mid_uo &&
755 event->fsn == sin->fsn_uo) 755 event->fsn == sin->fsn_uo)
756 retval = sctp_intl_retrieve_partial_uo(ulpq, event); 756 retval = sctp_intl_retrieve_partial_uo(ulpq, event);
@@ -774,7 +774,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_first_uo(struct sctp_ulpq *ulpq)
774 skb_queue_walk(&ulpq->reasm_uo, pos) { 774 skb_queue_walk(&ulpq->reasm_uo, pos) {
775 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 775 struct sctp_ulpevent *cevent = sctp_skb2event(pos);
776 776
777 csin = sctp_stream_in(ulpq->asoc, cevent->stream); 777 csin = sctp_stream_in(&ulpq->asoc->stream, cevent->stream);
778 if (csin->pd_mode_uo) 778 if (csin->pd_mode_uo)
779 continue; 779 continue;
780 780
@@ -875,7 +875,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_first(struct sctp_ulpq *ulpq)
875 skb_queue_walk(&ulpq->reasm, pos) { 875 skb_queue_walk(&ulpq->reasm, pos) {
876 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 876 struct sctp_ulpevent *cevent = sctp_skb2event(pos);
877 877
878 csin = sctp_stream_in(ulpq->asoc, cevent->stream); 878 csin = sctp_stream_in(&ulpq->asoc->stream, cevent->stream);
879 if (csin->pd_mode) 879 if (csin->pd_mode)
880 continue; 880 continue;
881 881
@@ -1053,7 +1053,7 @@ static void sctp_intl_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp)
1053 __u16 sid; 1053 __u16 sid;
1054 1054
1055 for (sid = 0; sid < stream->incnt; sid++) { 1055 for (sid = 0; sid < stream->incnt; sid++) {
1056 struct sctp_stream_in *sin = &stream->in[sid]; 1056 struct sctp_stream_in *sin = SCTP_SI(stream, sid);
1057 __u32 mid; 1057 __u32 mid;
1058 1058
1059 if (sin->pd_mode_uo) { 1059 if (sin->pd_mode_uo) {
@@ -1247,7 +1247,7 @@ static void sctp_handle_fwdtsn(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk)
1247static void sctp_intl_skip(struct sctp_ulpq *ulpq, __u16 sid, __u32 mid, 1247static void sctp_intl_skip(struct sctp_ulpq *ulpq, __u16 sid, __u32 mid,
1248 __u8 flags) 1248 __u8 flags)
1249{ 1249{
1250 struct sctp_stream_in *sin = sctp_stream_in(ulpq->asoc, sid); 1250 struct sctp_stream_in *sin = sctp_stream_in(&ulpq->asoc->stream, sid);
1251 struct sctp_stream *stream = &ulpq->asoc->stream; 1251 struct sctp_stream *stream = &ulpq->asoc->stream;
1252 1252
1253 if (flags & SCTP_FTSN_U_BIT) { 1253 if (flags & SCTP_FTSN_U_BIT) {
diff --git a/net/sctp/stream_sched.c b/net/sctp/stream_sched.c
index f5fcd425232a..a6c04a94b08f 100644
--- a/net/sctp/stream_sched.c
+++ b/net/sctp/stream_sched.c
@@ -161,7 +161,7 @@ int sctp_sched_set_sched(struct sctp_association *asoc,
161 161
162 /* Give the next scheduler a clean slate. */ 162 /* Give the next scheduler a clean slate. */
163 for (i = 0; i < asoc->stream.outcnt; i++) { 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 165
166 if (!p) 166 if (!p)
167 continue; 167 continue;
@@ -175,7 +175,7 @@ int sctp_sched_set_sched(struct sctp_association *asoc,
175 asoc->outqueue.sched = n; 175 asoc->outqueue.sched = n;
176 n->init(&asoc->stream); 176 n->init(&asoc->stream);
177 for (i = 0; i < asoc->stream.outcnt; i++) { 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; 179 continue;
180 180
181 ret = n->init_sid(&asoc->stream, i, GFP_KERNEL); 181 ret = n->init_sid(&asoc->stream, i, GFP_KERNEL);
@@ -217,7 +217,7 @@ int sctp_sched_set_value(struct sctp_association *asoc, __u16 sid,
217 if (sid >= asoc->stream.outcnt) 217 if (sid >= asoc->stream.outcnt)
218 return -EINVAL; 218 return -EINVAL;
219 219
220 if (!asoc->stream.out[sid].ext) { 220 if (!SCTP_SO(&asoc->stream, sid)->ext) {
221 int ret; 221 int ret;
222 222
223 ret = sctp_stream_init_ext(&asoc->stream, sid); 223 ret = sctp_stream_init_ext(&asoc->stream, sid);
@@ -234,7 +234,7 @@ int sctp_sched_get_value(struct sctp_association *asoc, __u16 sid,
234 if (sid >= asoc->stream.outcnt) 234 if (sid >= asoc->stream.outcnt)
235 return -EINVAL; 235 return -EINVAL;
236 236
237 if (!asoc->stream.out[sid].ext) 237 if (!SCTP_SO(&asoc->stream, sid)->ext)
238 return 0; 238 return 0;
239 239
240 return asoc->outqueue.sched->get(&asoc->stream, sid, value); 240 return asoc->outqueue.sched->get(&asoc->stream, sid, value);
@@ -252,7 +252,7 @@ void sctp_sched_dequeue_done(struct sctp_outq *q, struct sctp_chunk *ch)
252 * priority stream comes in. 252 * priority stream comes in.
253 */ 253 */
254 sid = sctp_chunk_stream_no(ch); 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; 256 q->asoc->stream.out_curr = sout;
257 return; 257 return;
258 } 258 }
@@ -272,8 +272,9 @@ void sctp_sched_dequeue_common(struct sctp_outq *q, struct sctp_chunk *ch)
272int sctp_sched_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp) 272int sctp_sched_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp)
273{ 273{
274 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream); 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 return sched->init_sid(stream, sid, gfp);
278} 279}
279 280
diff --git a/net/sctp/stream_sched_prio.c b/net/sctp/stream_sched_prio.c
index 7997d35dd0fd..2245083a98f2 100644
--- a/net/sctp/stream_sched_prio.c
+++ b/net/sctp/stream_sched_prio.c
@@ -75,10 +75,10 @@ static struct sctp_stream_priorities *sctp_sched_prio_get_head(
75 75
76 /* No luck. So we search on all streams now. */ 76 /* No luck. So we search on all streams now. */
77 for (i = 0; i < stream->outcnt; i++) { 77 for (i = 0; i < stream->outcnt; i++) {
78 if (!stream->out[i].ext) 78 if (!SCTP_SO(stream, i)->ext)
79 continue; 79 continue;
80 80
81 p = stream->out[i].ext->prio_head; 81 p = SCTP_SO(stream, i)->ext->prio_head;
82 if (!p) 82 if (!p)
83 /* Means all other streams won't be initialized 83 /* Means all other streams won't be initialized
84 * as well. 84 * as well.
@@ -165,7 +165,7 @@ static void sctp_sched_prio_sched(struct sctp_stream *stream,
165static int sctp_sched_prio_set(struct sctp_stream *stream, __u16 sid, 165static int sctp_sched_prio_set(struct sctp_stream *stream, __u16 sid,
166 __u16 prio, gfp_t gfp) 166 __u16 prio, gfp_t gfp)
167{ 167{
168 struct sctp_stream_out *sout = &stream->out[sid]; 168 struct sctp_stream_out *sout = SCTP_SO(stream, sid);
169 struct sctp_stream_out_ext *soute = sout->ext; 169 struct sctp_stream_out_ext *soute = sout->ext;
170 struct sctp_stream_priorities *prio_head, *old; 170 struct sctp_stream_priorities *prio_head, *old;
171 bool reschedule = false; 171 bool reschedule = false;
@@ -186,7 +186,7 @@ static int sctp_sched_prio_set(struct sctp_stream *stream, __u16 sid,
186 return 0; 186 return 0;
187 187
188 for (i = 0; i < stream->outcnt; i++) { 188 for (i = 0; i < stream->outcnt; i++) {
189 soute = stream->out[i].ext; 189 soute = SCTP_SO(stream, i)->ext;
190 if (soute && soute->prio_head == old) 190 if (soute && soute->prio_head == old)
191 /* It's still in use, nothing else to do here. */ 191 /* It's still in use, nothing else to do here. */
192 return 0; 192 return 0;
@@ -201,7 +201,7 @@ static int sctp_sched_prio_set(struct sctp_stream *stream, __u16 sid,
201static int sctp_sched_prio_get(struct sctp_stream *stream, __u16 sid, 201static int sctp_sched_prio_get(struct sctp_stream *stream, __u16 sid,
202 __u16 *value) 202 __u16 *value)
203{ 203{
204 *value = stream->out[sid].ext->prio_head->prio; 204 *value = SCTP_SO(stream, sid)->ext->prio_head->prio;
205 return 0; 205 return 0;
206} 206}
207 207
@@ -215,7 +215,7 @@ static int sctp_sched_prio_init(struct sctp_stream *stream)
215static int sctp_sched_prio_init_sid(struct sctp_stream *stream, __u16 sid, 215static int sctp_sched_prio_init_sid(struct sctp_stream *stream, __u16 sid,
216 gfp_t gfp) 216 gfp_t gfp)
217{ 217{
218 INIT_LIST_HEAD(&stream->out[sid].ext->prio_list); 218 INIT_LIST_HEAD(&SCTP_SO(stream, sid)->ext->prio_list);
219 return sctp_sched_prio_set(stream, sid, 0, gfp); 219 return sctp_sched_prio_set(stream, sid, 0, gfp);
220} 220}
221 221
@@ -233,9 +233,9 @@ static void sctp_sched_prio_free(struct sctp_stream *stream)
233 */ 233 */
234 sctp_sched_prio_unsched_all(stream); 234 sctp_sched_prio_unsched_all(stream);
235 for (i = 0; i < stream->outcnt; i++) { 235 for (i = 0; i < stream->outcnt; i++) {
236 if (!stream->out[i].ext) 236 if (!SCTP_SO(stream, i)->ext)
237 continue; 237 continue;
238 prio = stream->out[i].ext->prio_head; 238 prio = SCTP_SO(stream, i)->ext->prio_head;
239 if (prio && list_empty(&prio->prio_sched)) 239 if (prio && list_empty(&prio->prio_sched))
240 list_add(&prio->prio_sched, &list); 240 list_add(&prio->prio_sched, &list);
241 } 241 }
@@ -255,7 +255,7 @@ static void sctp_sched_prio_enqueue(struct sctp_outq *q,
255 ch = list_first_entry(&msg->chunks, struct sctp_chunk, frag_list); 255 ch = list_first_entry(&msg->chunks, struct sctp_chunk, frag_list);
256 sid = sctp_chunk_stream_no(ch); 256 sid = sctp_chunk_stream_no(ch);
257 stream = &q->asoc->stream; 257 stream = &q->asoc->stream;
258 sctp_sched_prio_sched(stream, stream->out[sid].ext); 258 sctp_sched_prio_sched(stream, SCTP_SO(stream, sid)->ext);
259} 259}
260 260
261static struct sctp_chunk *sctp_sched_prio_dequeue(struct sctp_outq *q) 261static struct sctp_chunk *sctp_sched_prio_dequeue(struct sctp_outq *q)
@@ -297,7 +297,7 @@ static void sctp_sched_prio_dequeue_done(struct sctp_outq *q,
297 * this priority. 297 * this priority.
298 */ 298 */
299 sid = sctp_chunk_stream_no(ch); 299 sid = sctp_chunk_stream_no(ch);
300 soute = q->asoc->stream.out[sid].ext; 300 soute = SCTP_SO(&q->asoc->stream, sid)->ext;
301 prio = soute->prio_head; 301 prio = soute->prio_head;
302 302
303 sctp_sched_prio_next_stream(prio); 303 sctp_sched_prio_next_stream(prio);
@@ -317,7 +317,7 @@ static void sctp_sched_prio_sched_all(struct sctp_stream *stream)
317 __u16 sid; 317 __u16 sid;
318 318
319 sid = sctp_chunk_stream_no(ch); 319 sid = sctp_chunk_stream_no(ch);
320 sout = &stream->out[sid]; 320 sout = SCTP_SO(stream, sid);
321 if (sout->ext) 321 if (sout->ext)
322 sctp_sched_prio_sched(stream, sout->ext); 322 sctp_sched_prio_sched(stream, sout->ext);
323 } 323 }
diff --git a/net/sctp/stream_sched_rr.c b/net/sctp/stream_sched_rr.c
index 1155692448f1..52ba743fa7a7 100644
--- a/net/sctp/stream_sched_rr.c
+++ b/net/sctp/stream_sched_rr.c
@@ -100,7 +100,7 @@ static int sctp_sched_rr_init(struct sctp_stream *stream)
100static int sctp_sched_rr_init_sid(struct sctp_stream *stream, __u16 sid, 100static int sctp_sched_rr_init_sid(struct sctp_stream *stream, __u16 sid,
101 gfp_t gfp) 101 gfp_t gfp)
102{ 102{
103 INIT_LIST_HEAD(&stream->out[sid].ext->rr_list); 103 INIT_LIST_HEAD(&SCTP_SO(stream, sid)->ext->rr_list);
104 104
105 return 0; 105 return 0;
106} 106}
@@ -120,7 +120,7 @@ static void sctp_sched_rr_enqueue(struct sctp_outq *q,
120 ch = list_first_entry(&msg->chunks, struct sctp_chunk, frag_list); 120 ch = list_first_entry(&msg->chunks, struct sctp_chunk, frag_list);
121 sid = sctp_chunk_stream_no(ch); 121 sid = sctp_chunk_stream_no(ch);
122 stream = &q->asoc->stream; 122 stream = &q->asoc->stream;
123 sctp_sched_rr_sched(stream, stream->out[sid].ext); 123 sctp_sched_rr_sched(stream, SCTP_SO(stream, sid)->ext);
124} 124}
125 125
126static struct sctp_chunk *sctp_sched_rr_dequeue(struct sctp_outq *q) 126static struct sctp_chunk *sctp_sched_rr_dequeue(struct sctp_outq *q)
@@ -154,7 +154,7 @@ static void sctp_sched_rr_dequeue_done(struct sctp_outq *q,
154 154
155 /* Last chunk on that msg, move to the next stream */ 155 /* Last chunk on that msg, move to the next stream */
156 sid = sctp_chunk_stream_no(ch); 156 sid = sctp_chunk_stream_no(ch);
157 soute = q->asoc->stream.out[sid].ext; 157 soute = SCTP_SO(&q->asoc->stream, sid)->ext;
158 158
159 sctp_sched_rr_next_stream(&q->asoc->stream); 159 sctp_sched_rr_next_stream(&q->asoc->stream);
160 160
@@ -173,7 +173,7 @@ static void sctp_sched_rr_sched_all(struct sctp_stream *stream)
173 __u16 sid; 173 __u16 sid;
174 174
175 sid = sctp_chunk_stream_no(ch); 175 sid = sctp_chunk_stream_no(ch);
176 soute = stream->out[sid].ext; 176 soute = SCTP_SO(stream, sid)->ext;
177 if (soute) 177 if (soute)
178 sctp_sched_rr_sched(stream, soute); 178 sctp_sched_rr_sched(stream, soute);
179 } 179 }