tcp: Limit new segements burst to 4 during extended limited transmit
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 23 Jan 2013 12:37:49 +0000 (20:37 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 23 Jan 2013 12:38:56 +0000 (20:38 +0800)
sys/netinet/tcp_input.c

index c7dd1a7..fab9919 100644 (file)
@@ -134,6 +134,12 @@ struct tcphdr tcp_savetcp;
 #include <netproto/key/key.h>
 #endif
 
 #include <netproto/key/key.h>
 #endif
 
+/*
+ * Limit burst of new packets during SACK based fast recovery
+ * or extended limited transmit.
+ */
+#define TCP_SACK_MAXBURST      4
+
 MALLOC_DEFINE(M_TSEGQ, "tseg_qent", "TCP segment queue entry");
 
 static int log_in_vain = 0;
 MALLOC_DEFINE(M_TSEGQ, "tseg_qent", "TCP segment queue entry");
 
 static int log_in_vain = 0;
@@ -3231,7 +3237,6 @@ tcp_sack_rexmt(struct tcpcb *tp, boolean_t force)
        int nseg = 0;           /* consecutive new segments */
        int nseg_rexmt = 0;     /* retransmitted segments */
        int maxrexmt = 0;
        int nseg = 0;           /* consecutive new segments */
        int nseg_rexmt = 0;     /* retransmitted segments */
        int maxrexmt = 0;
-#define MAXBURST 4             /* limit burst of new packets on partial ack */
 
        if (force) {
                uint32_t unsacked = tcp_sack_first_unsacked_len(tp);
 
        if (force) {
                uint32_t unsacked = tcp_sack_first_unsacked_len(tp);
@@ -3249,7 +3254,7 @@ tcp_sack_rexmt(struct tcpcb *tp, boolean_t force)
        pipe = tcp_sack_compute_pipe(tp);
        while (((tcp_seq_diff_t)(ocwnd - pipe) >= (tcp_seq_diff_t)tp->t_maxseg
                || (force && nseg_rexmt < maxrexmt && nseg == 0)) &&
        pipe = tcp_sack_compute_pipe(tp);
        while (((tcp_seq_diff_t)(ocwnd - pipe) >= (tcp_seq_diff_t)tp->t_maxseg
                || (force && nseg_rexmt < maxrexmt && nseg == 0)) &&
-           (!tcp_do_smartsack || nseg < MAXBURST)) {
+           (!tcp_do_smartsack || nseg < TCP_SACK_MAXBURST)) {
                tcp_seq old_snd_max, old_rexmt_high, nextrexmt;
                uint32_t sent, seglen;
                boolean_t rescue;
                tcp_seq old_snd_max, old_rexmt_high, nextrexmt;
                uint32_t sent, seglen;
                boolean_t rescue;
@@ -3341,6 +3346,9 @@ tcp_sack_limitedxmit(struct tcpcb *tp)
        if (cwnd_left < (tcp_seq_diff_t)tp->t_maxseg)
                return FALSE;
 
        if (cwnd_left < (tcp_seq_diff_t)tp->t_maxseg)
                return FALSE;
 
+       if (tcp_do_smartsack)
+               cwnd_left = ulmin(cwnd_left, tp->t_maxseg * TCP_SACK_MAXBURST);
+
        next = tp->snd_nxt = tp->snd_max;
        tp->snd_cwnd = tp->snd_nxt - tp->snd_una +
            rounddown(cwnd_left, tp->t_maxseg);
        next = tp->snd_nxt = tp->snd_max;
        tp->snd_cwnd = tp->snd_nxt - tp->snd_una +
            rounddown(cwnd_left, tp->t_maxseg);