summaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2009-08-07 19:23:28 +0200
committerVlad Yasevich <vladislav.yasevich@hp.com>2009-09-05 00:20:56 +0200
commit5d7ff261ef497c62f54c39effc259910a28b313d (patch)
tree78eca9144bafc85c65cfdf19e5c8c5dffbd271f4 /net/sctp
parentsctp: Generate SACKs when actually sending outbound DATA (diff)
downloadlinux-5d7ff261ef497c62f54c39effc259910a28b313d.tar.xz
linux-5d7ff261ef497c62f54c39effc259910a28b313d.zip
sctp: Try to encourage SACK bundling with DATA.
If the association has a SACK timer pending and now DATA queued to be send, we'll try to bundle the SACK with the next application send. As such, try encourage bundling by accounting for SACK in the size of the first chunk fragment. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/chunk.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 9292294dbc12..7acaf15679b6 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -207,14 +207,25 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
whole = 0;
first_len = max;
+ /* Check to see if we have a pending SACK and try to let it be bundled
+ * with this message. Do this if we don't have any data queued already.
+ * To check that, look at out_qlen and retransmit list.
+ * NOTE: we will not reduce to account for SACK, if the message would
+ * not have been fragmented.
+ */
+ if (timer_pending(&asoc->timers[SCTP_EVENT_TIMEOUT_SACK]) &&
+ asoc->outqueue.out_qlen == 0 &&
+ list_empty(&asoc->outqueue.retransmit) &&
+ msg_len > max)
+ max_data -= WORD_ROUND(sizeof(sctp_sack_chunk_t));
+
/* Encourage Cookie-ECHO bundling. */
- if (asoc->state < SCTP_STATE_COOKIE_ECHOED) {
+ if (asoc->state < SCTP_STATE_COOKIE_ECHOED)
max_data -= SCTP_ARBITRARY_COOKIE_ECHO_LEN;
- /* This is the biggesr first_len we can have */
- if (first_len > max_data)
- first_len = max_data;
- }
+ /* Now that we adjusted completely, reset first_len */
+ if (first_len > max_data)
+ first_len = max_data;
/* Account for a different sized first fragment */
if (msg_len >= first_len) {