diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2009-11-23 15:54:00 -0500 |
---|---|---|
committer | Vlad Yasevich <vladislav.yasevich@hp.com> | 2009-11-23 15:54:00 -0500 |
commit | 46d5a808558181e03a4760d2188cc9879445738a (patch) | |
tree | a51cc59d64042f61518d25ef4ecc71924f243084 /net/sctp/transport.c | |
parent | a5b03ad2143c5bc9ae76533e8321fe66258b4f35 (diff) |
sctp: Update max.burst implementation
Current implementation of max.burst ends up limiting new
data during cwnd decay period. The decay is happening becuase
the connection is idle and we are allowed to fill the congestion
window. The point of max.burst is to limit micro-bursts in response
to large acks. This still happens, as max.burst is still applied
to each transmit opportunity. It will also apply if a very large
send is made (greater then allowed by burst).
Tested-by: Florian Niederbacher <florian.niederbacher@student.uibk.ac.at>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net/sctp/transport.c')
-rw-r--r-- | net/sctp/transport.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 2df29cbdaf5a..9a6cb22d129f 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -576,6 +576,43 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
576 | transport->cwnd, transport->ssthresh); | 576 | transport->cwnd, transport->ssthresh); |
577 | } | 577 | } |
578 | 578 | ||
579 | /* Apply Max.Burst limit to the congestion window: | ||
580 | * sctpimpguide-05 2.14.2 | ||
581 | * D) When the time comes for the sender to | ||
582 | * transmit new DATA chunks, the protocol parameter Max.Burst MUST | ||
583 | * first be applied to limit how many new DATA chunks may be sent. | ||
584 | * The limit is applied by adjusting cwnd as follows: | ||
585 | * if ((flightsize+ Max.Burst * MTU) < cwnd) | ||
586 | * cwnd = flightsize + Max.Burst * MTU | ||
587 | */ | ||
588 | |||
589 | void sctp_transport_burst_limited(struct sctp_transport *t) | ||
590 | { | ||
591 | struct sctp_association *asoc = t->asoc; | ||
592 | u32 old_cwnd = t->cwnd; | ||
593 | u32 max_burst_bytes; | ||
594 | |||
595 | if (t->burst_limited) | ||
596 | return; | ||
597 | |||
598 | max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); | ||
599 | if (max_burst_bytes < old_cwnd) { | ||
600 | t->cwnd = max_burst_bytes; | ||
601 | t->burst_limited = old_cwnd; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | /* Restore the old cwnd congestion window, after the burst had it's | ||
606 | * desired effect. | ||
607 | */ | ||
608 | void sctp_transport_burst_reset(struct sctp_transport *t) | ||
609 | { | ||
610 | if (t->burst_limited) { | ||
611 | t->cwnd = t->burst_limited; | ||
612 | t->burst_limited = 0; | ||
613 | } | ||
614 | } | ||
615 | |||
579 | /* What is the next timeout value for this transport? */ | 616 | /* What is the next timeout value for this transport? */ |
580 | unsigned long sctp_transport_timeout(struct sctp_transport *t) | 617 | unsigned long sctp_transport_timeout(struct sctp_transport *t) |
581 | { | 618 | { |
@@ -598,6 +635,7 @@ void sctp_transport_reset(struct sctp_transport *t) | |||
598 | * (see Section 6.2.1) | 635 | * (see Section 6.2.1) |
599 | */ | 636 | */ |
600 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); | 637 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); |
638 | t->burst_limited = 0; | ||
601 | t->ssthresh = asoc->peer.i.a_rwnd; | 639 | t->ssthresh = asoc->peer.i.a_rwnd; |
602 | t->last_rto = t->rto = asoc->rto_initial; | 640 | t->last_rto = t->rto = asoc->rto_initial; |
603 | t->rtt = 0; | 641 | t->rtt = 0; |