aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/stream.c
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2017-05-31 04:36:31 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-02 13:56:26 -0400
commitcee360ab4dd66fc1de33a5fa1cb418fa21c27ce3 (patch)
treedb9b8575e7392b314e94a946590b71bb5c856e64 /net/sctp/stream.c
parent6e7da286e3513ac1e107ef8dffa5f254029d68e7 (diff)
sctp: define the member stream as an object instead of pointer in asoc
As Marcelo's suggestion, stream is a fixed size member of asoc and would not grow with more streams. To avoid an allocation for it, this patch is to define it as an object instead of pointer and update the places using it, also create sctp_stream_update() called in sctp_assoc_update() to migrate the stream info from one stream to another. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/stream.c')
-rw-r--r--net/sctp/stream.c68
1 files changed, 33 insertions, 35 deletions
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index dda53a293986..af6b49850344 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -37,30 +37,23 @@
37 37
38int sctp_stream_new(struct sctp_association *asoc, gfp_t gfp) 38int sctp_stream_new(struct sctp_association *asoc, gfp_t gfp)
39{ 39{
40 struct sctp_stream *stream; 40 struct sctp_stream *stream = &asoc->stream;
41 int i; 41 int i;
42 42
43 stream = kzalloc(sizeof(*stream), gfp);
44 if (!stream)
45 return -ENOMEM;
46
47 stream->outcnt = asoc->c.sinit_num_ostreams; 43 stream->outcnt = asoc->c.sinit_num_ostreams;
48 stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp); 44 stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp);
49 if (!stream->out) { 45 if (!stream->out)
50 kfree(stream);
51 return -ENOMEM; 46 return -ENOMEM;
52 } 47
53 for (i = 0; i < stream->outcnt; i++) 48 for (i = 0; i < stream->outcnt; i++)
54 stream->out[i].state = SCTP_STREAM_OPEN; 49 stream->out[i].state = SCTP_STREAM_OPEN;
55 50
56 asoc->stream = stream;
57
58 return 0; 51 return 0;
59} 52}
60 53
61int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp) 54int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp)
62{ 55{
63 struct sctp_stream *stream = asoc->stream; 56 struct sctp_stream *stream = &asoc->stream;
64 int i; 57 int i;
65 58
66 /* Initial stream->out size may be very big, so free it and alloc 59 /* Initial stream->out size may be very big, so free it and alloc
@@ -70,7 +63,7 @@ int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp)
70 stream->outcnt = asoc->c.sinit_num_ostreams; 63 stream->outcnt = asoc->c.sinit_num_ostreams;
71 stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp); 64 stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp);
72 if (!stream->out) 65 if (!stream->out)
73 goto nomem; 66 return -ENOMEM;
74 67
75 for (i = 0; i < stream->outcnt; i++) 68 for (i = 0; i < stream->outcnt; i++)
76 stream->out[i].state = SCTP_STREAM_OPEN; 69 stream->out[i].state = SCTP_STREAM_OPEN;
@@ -79,26 +72,17 @@ int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp)
79 stream->in = kcalloc(stream->incnt, sizeof(*stream->in), gfp); 72 stream->in = kcalloc(stream->incnt, sizeof(*stream->in), gfp);
80 if (!stream->in) { 73 if (!stream->in) {
81 kfree(stream->out); 74 kfree(stream->out);
82 goto nomem; 75 stream->out = NULL;
76 return -ENOMEM;
83 } 77 }
84 78
85 return 0; 79 return 0;
86
87nomem:
88 asoc->stream = NULL;
89 kfree(stream);
90
91 return -ENOMEM;
92} 80}
93 81
94void sctp_stream_free(struct sctp_stream *stream) 82void sctp_stream_free(struct sctp_stream *stream)
95{ 83{
96 if (unlikely(!stream))
97 return;
98
99 kfree(stream->out); 84 kfree(stream->out);
100 kfree(stream->in); 85 kfree(stream->in);
101 kfree(stream);
102} 86}
103 87
104void sctp_stream_clear(struct sctp_stream *stream) 88void sctp_stream_clear(struct sctp_stream *stream)
@@ -112,6 +96,19 @@ void sctp_stream_clear(struct sctp_stream *stream)
112 stream->in[i].ssn = 0; 96 stream->in[i].ssn = 0;
113} 97}
114 98
99void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new)
100{
101 sctp_stream_free(stream);
102
103 stream->out = new->out;
104 stream->in = new->in;
105 stream->outcnt = new->outcnt;
106 stream->incnt = new->incnt;
107
108 new->out = NULL;
109 new->in = NULL;
110}
111
115static int sctp_send_reconf(struct sctp_association *asoc, 112static int sctp_send_reconf(struct sctp_association *asoc,
116 struct sctp_chunk *chunk) 113 struct sctp_chunk *chunk)
117{ 114{
@@ -128,7 +125,7 @@ static int sctp_send_reconf(struct sctp_association *asoc,
128int sctp_send_reset_streams(struct sctp_association *asoc, 125int sctp_send_reset_streams(struct sctp_association *asoc,
129 struct sctp_reset_streams *params) 126 struct sctp_reset_streams *params)
130{ 127{
131 struct sctp_stream *stream = asoc->stream; 128 struct sctp_stream *stream = &asoc->stream;
132 __u16 i, str_nums, *str_list; 129 __u16 i, str_nums, *str_list;
133 struct sctp_chunk *chunk; 130 struct sctp_chunk *chunk;
134 int retval = -EINVAL; 131 int retval = -EINVAL;
@@ -214,6 +211,7 @@ out:
214 211
215int sctp_send_reset_assoc(struct sctp_association *asoc) 212int sctp_send_reset_assoc(struct sctp_association *asoc)
216{ 213{
214 struct sctp_stream *stream = &asoc->stream;
217 struct sctp_chunk *chunk = NULL; 215 struct sctp_chunk *chunk = NULL;
218 int retval; 216 int retval;
219 __u16 i; 217 __u16 i;
@@ -230,8 +228,8 @@ int sctp_send_reset_assoc(struct sctp_association *asoc)
230 return -ENOMEM; 228 return -ENOMEM;
231 229
232 /* Block further xmit of data until this request is completed */ 230 /* Block further xmit of data until this request is completed */
233 for (i = 0; i < asoc->stream->outcnt; i++) 231 for (i = 0; i < stream->outcnt; i++)
234 asoc->stream->out[i].state = SCTP_STREAM_CLOSED; 232 stream->out[i].state = SCTP_STREAM_CLOSED;
235 233
236 asoc->strreset_chunk = chunk; 234 asoc->strreset_chunk = chunk;
237 sctp_chunk_hold(asoc->strreset_chunk); 235 sctp_chunk_hold(asoc->strreset_chunk);
@@ -241,8 +239,8 @@ int sctp_send_reset_assoc(struct sctp_association *asoc)
241 sctp_chunk_put(asoc->strreset_chunk); 239 sctp_chunk_put(asoc->strreset_chunk);
242 asoc->strreset_chunk = NULL; 240 asoc->strreset_chunk = NULL;
243 241
244 for (i = 0; i < asoc->stream->outcnt; i++) 242 for (i = 0; i < stream->outcnt; i++)
245 asoc->stream->out[i].state = SCTP_STREAM_OPEN; 243 stream->out[i].state = SCTP_STREAM_OPEN;
246 244
247 return retval; 245 return retval;
248 } 246 }
@@ -255,7 +253,7 @@ int sctp_send_reset_assoc(struct sctp_association *asoc)
255int sctp_send_add_streams(struct sctp_association *asoc, 253int sctp_send_add_streams(struct sctp_association *asoc,
256 struct sctp_add_streams *params) 254 struct sctp_add_streams *params)
257{ 255{
258 struct sctp_stream *stream = asoc->stream; 256 struct sctp_stream *stream = &asoc->stream;
259 struct sctp_chunk *chunk = NULL; 257 struct sctp_chunk *chunk = NULL;
260 int retval = -ENOMEM; 258 int retval = -ENOMEM;
261 __u32 outcnt, incnt; 259 __u32 outcnt, incnt;
@@ -357,7 +355,7 @@ struct sctp_chunk *sctp_process_strreset_outreq(
357 struct sctp_ulpevent **evp) 355 struct sctp_ulpevent **evp)
358{ 356{
359 struct sctp_strreset_outreq *outreq = param.v; 357 struct sctp_strreset_outreq *outreq = param.v;
360 struct sctp_stream *stream = asoc->stream; 358 struct sctp_stream *stream = &asoc->stream;
361 __u16 i, nums, flags = 0, *str_p = NULL; 359 __u16 i, nums, flags = 0, *str_p = NULL;
362 __u32 result = SCTP_STRRESET_DENIED; 360 __u32 result = SCTP_STRRESET_DENIED;
363 __u32 request_seq; 361 __u32 request_seq;
@@ -449,7 +447,7 @@ struct sctp_chunk *sctp_process_strreset_inreq(
449 struct sctp_ulpevent **evp) 447 struct sctp_ulpevent **evp)
450{ 448{
451 struct sctp_strreset_inreq *inreq = param.v; 449 struct sctp_strreset_inreq *inreq = param.v;
452 struct sctp_stream *stream = asoc->stream; 450 struct sctp_stream *stream = &asoc->stream;
453 __u32 result = SCTP_STRRESET_DENIED; 451 __u32 result = SCTP_STRRESET_DENIED;
454 struct sctp_chunk *chunk = NULL; 452 struct sctp_chunk *chunk = NULL;
455 __u16 i, nums, *str_p; 453 __u16 i, nums, *str_p;
@@ -523,7 +521,7 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
523{ 521{
524 __u32 init_tsn = 0, next_tsn = 0, max_tsn_seen; 522 __u32 init_tsn = 0, next_tsn = 0, max_tsn_seen;
525 struct sctp_strreset_tsnreq *tsnreq = param.v; 523 struct sctp_strreset_tsnreq *tsnreq = param.v;
526 struct sctp_stream *stream = asoc->stream; 524 struct sctp_stream *stream = &asoc->stream;
527 __u32 result = SCTP_STRRESET_DENIED; 525 __u32 result = SCTP_STRRESET_DENIED;
528 __u32 request_seq; 526 __u32 request_seq;
529 __u16 i; 527 __u16 i;
@@ -612,7 +610,7 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out(
612 struct sctp_ulpevent **evp) 610 struct sctp_ulpevent **evp)
613{ 611{
614 struct sctp_strreset_addstrm *addstrm = param.v; 612 struct sctp_strreset_addstrm *addstrm = param.v;
615 struct sctp_stream *stream = asoc->stream; 613 struct sctp_stream *stream = &asoc->stream;
616 __u32 result = SCTP_STRRESET_DENIED; 614 __u32 result = SCTP_STRRESET_DENIED;
617 struct sctp_stream_in *streamin; 615 struct sctp_stream_in *streamin;
618 __u32 request_seq, incnt; 616 __u32 request_seq, incnt;
@@ -687,7 +685,7 @@ struct sctp_chunk *sctp_process_strreset_addstrm_in(
687 struct sctp_ulpevent **evp) 685 struct sctp_ulpevent **evp)
688{ 686{
689 struct sctp_strreset_addstrm *addstrm = param.v; 687 struct sctp_strreset_addstrm *addstrm = param.v;
690 struct sctp_stream *stream = asoc->stream; 688 struct sctp_stream *stream = &asoc->stream;
691 __u32 result = SCTP_STRRESET_DENIED; 689 __u32 result = SCTP_STRRESET_DENIED;
692 struct sctp_stream_out *streamout; 690 struct sctp_stream_out *streamout;
693 struct sctp_chunk *chunk = NULL; 691 struct sctp_chunk *chunk = NULL;
@@ -758,8 +756,8 @@ struct sctp_chunk *sctp_process_strreset_resp(
758 union sctp_params param, 756 union sctp_params param,
759 struct sctp_ulpevent **evp) 757 struct sctp_ulpevent **evp)
760{ 758{
759 struct sctp_stream *stream = &asoc->stream;
761 struct sctp_strreset_resp *resp = param.v; 760 struct sctp_strreset_resp *resp = param.v;
762 struct sctp_stream *stream = asoc->stream;
763 struct sctp_transport *t; 761 struct sctp_transport *t;
764 __u16 i, nums, flags = 0; 762 __u16 i, nums, flags = 0;
765 sctp_paramhdr_t *req; 763 sctp_paramhdr_t *req;