aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2012-07-02 05:59:24 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-09 02:56:16 -0400
commited1062772531b6e1029fa4ca62dc8d61f6d53d1c (patch)
tree2b1854d347f77cfd71a145b3976ebecc1dabf02c
parent12aba9e7974c5aabf0f4b8e90a5943bfa17fadf4 (diff)
sctp: refactor sctp_packet_append_chunk and clenup some memory leaks
While doing some recent work on sctp sack bundling I noted that sctp_packet_append_chunk was pretty inefficient. Specifially, it was called recursively while trying to bundle auth and sack chunks. Because of that we call sctp_packet_bundle_sack and sctp_packet_bundle_auth a total of 4 times for every call to sctp_packet_append_chunk, knowing that at least 3 of those calls will do nothing. So lets refactor sctp_packet_bundle_auth to have an outer part that does the attempted bundling, and an inner part that just does the chunk appends. This saves us several calls per iteration that we just don't need. Also, noticed that the auth and sack bundling fail to free the chunks they allocate if the append fails, so make sure we add that in Signed-off-by: Neil Horman <nhorman@tuxdriver.com> CC: Vlad Yasevich <vyasevich@gmail.com> CC: "David S. Miller" <davem@davemloft.net> CC: linux-sctp@vger.kernel.org Acked-by: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/sctp/output.c79
1 files changed, 52 insertions, 27 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 6ae47acaaec6..539f35d07f4e 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -64,6 +64,8 @@
64#include <net/sctp/checksum.h> 64#include <net/sctp/checksum.h>
65 65
66/* Forward declarations for private helpers. */ 66/* Forward declarations for private helpers. */
67static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet,
68 struct sctp_chunk *chunk);
67static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, 69static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
68 struct sctp_chunk *chunk); 70 struct sctp_chunk *chunk);
69static void sctp_packet_append_data(struct sctp_packet *packet, 71static void sctp_packet_append_data(struct sctp_packet *packet,
@@ -224,7 +226,10 @@ static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt,
224 if (!auth) 226 if (!auth)
225 return retval; 227 return retval;
226 228
227 retval = sctp_packet_append_chunk(pkt, auth); 229 retval = __sctp_packet_append_chunk(pkt, auth);
230
231 if (retval != SCTP_XMIT_OK)
232 sctp_chunk_free(auth);
228 233
229 return retval; 234 return retval;
230} 235}
@@ -256,48 +261,31 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt,
256 asoc->a_rwnd = asoc->rwnd; 261 asoc->a_rwnd = asoc->rwnd;
257 sack = sctp_make_sack(asoc); 262 sack = sctp_make_sack(asoc);
258 if (sack) { 263 if (sack) {
259 retval = sctp_packet_append_chunk(pkt, sack); 264 retval = __sctp_packet_append_chunk(pkt, sack);
265 if (retval != SCTP_XMIT_OK) {
266 sctp_chunk_free(sack);
267 goto out;
268 }
260 asoc->peer.sack_needed = 0; 269 asoc->peer.sack_needed = 0;
261 if (del_timer(timer)) 270 if (del_timer(timer))
262 sctp_association_put(asoc); 271 sctp_association_put(asoc);
263 } 272 }
264 } 273 }
265 } 274 }
275out:
266 return retval; 276 return retval;
267} 277}
268 278
279
269/* Append a chunk to the offered packet reporting back any inability to do 280/* Append a chunk to the offered packet reporting back any inability to do
270 * so. 281 * so.
271 */ 282 */
272sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, 283static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet,
273 struct sctp_chunk *chunk) 284 struct sctp_chunk *chunk)
274{ 285{
275 sctp_xmit_t retval = SCTP_XMIT_OK; 286 sctp_xmit_t retval = SCTP_XMIT_OK;
276 __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length)); 287 __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length));
277 288
278 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet,
279 chunk);
280
281 /* Data chunks are special. Before seeing what else we can
282 * bundle into this packet, check to see if we are allowed to
283 * send this DATA.
284 */
285 if (sctp_chunk_is_data(chunk)) {
286 retval = sctp_packet_can_append_data(packet, chunk);
287 if (retval != SCTP_XMIT_OK)
288 goto finish;
289 }
290
291 /* Try to bundle AUTH chunk */
292 retval = sctp_packet_bundle_auth(packet, chunk);
293 if (retval != SCTP_XMIT_OK)
294 goto finish;
295
296 /* Try to bundle SACK chunk */
297 retval = sctp_packet_bundle_sack(packet, chunk);
298 if (retval != SCTP_XMIT_OK)
299 goto finish;
300
301 /* Check to see if this chunk will fit into the packet */ 289 /* Check to see if this chunk will fit into the packet */
302 retval = sctp_packet_will_fit(packet, chunk, chunk_len); 290 retval = sctp_packet_will_fit(packet, chunk, chunk_len);
303 if (retval != SCTP_XMIT_OK) 291 if (retval != SCTP_XMIT_OK)
@@ -339,6 +327,43 @@ finish:
339 return retval; 327 return retval;
340} 328}
341 329
330/* Append a chunk to the offered packet reporting back any inability to do
331 * so.
332 */
333sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
334 struct sctp_chunk *chunk)
335{
336 sctp_xmit_t retval = SCTP_XMIT_OK;
337
338 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet,
339 chunk);
340
341 /* Data chunks are special. Before seeing what else we can
342 * bundle into this packet, check to see if we are allowed to
343 * send this DATA.
344 */
345 if (sctp_chunk_is_data(chunk)) {
346 retval = sctp_packet_can_append_data(packet, chunk);
347 if (retval != SCTP_XMIT_OK)
348 goto finish;
349 }
350
351 /* Try to bundle AUTH chunk */
352 retval = sctp_packet_bundle_auth(packet, chunk);
353 if (retval != SCTP_XMIT_OK)
354 goto finish;
355
356 /* Try to bundle SACK chunk */
357 retval = sctp_packet_bundle_sack(packet, chunk);
358 if (retval != SCTP_XMIT_OK)
359 goto finish;
360
361 retval = __sctp_packet_append_chunk(packet, chunk);
362
363finish:
364 return retval;
365}
366
342/* All packets are sent to the network through this function from 367/* All packets are sent to the network through this function from
343 * sctp_outq_tail(). 368 * sctp_outq_tail().
344 * 369 *