Print this page
11553 Want pluggable TCP congestion control algorithms
Portions contributed by: Cody Peter Mello <cody.mello@joyent.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Robert Mustacchi <robert.mustacchi@joyent.com>


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright 2011 Joyent, Inc.  All rights reserved.
  26  * Copyright (c) 2014, 2016 by Delphix. All rights reserved.
  27  */
  28 
  29 #include <sys/types.h>
  30 #include <sys/strlog.h>
  31 #include <sys/strsun.h>
  32 #include <sys/squeue_impl.h>
  33 #include <sys/squeue.h>
  34 #include <sys/callo.h>
  35 #include <sys/strsubr.h>
  36 
  37 #include <inet/common.h>
  38 #include <inet/ip.h>
  39 #include <inet/ip_ire.h>
  40 #include <inet/ip_rts.h>
  41 #include <inet/tcp.h>
  42 #include <inet/tcp_impl.h>
  43 
  44 /*
  45  * Implementation of TCP Timers.
  46  * =============================


 767                                 TCP_STAT(tcps, tcp_timer_fire_early);
 768                                 TCP_TIMER_RESTART(tcp, time_to_wait);
 769                                 return;
 770                         }
 771                         /*
 772                          * When we probe zero windows, we force the swnd open.
 773                          * If our peer acks with a closed window swnd will be
 774                          * set to zero by tcp_rput(). As long as we are
 775                          * receiving acks tcp_rput will
 776                          * reset 'tcp_ms_we_have_waited' so as not to trip the
 777                          * first and second interval actions.  NOTE: the timer
 778                          * interval is allowed to continue its exponential
 779                          * backoff.
 780                          */
 781                         if (tcp->tcp_swnd == 0 || tcp->tcp_zero_win_probe) {
 782                                 if (connp->conn_debug) {
 783                                         (void) strlog(TCP_MOD_ID, 0, 1,
 784                                             SL_TRACE, "tcp_timer: zero win");
 785                                 }
 786                         } else {
 787                                 /*
 788                                  * After retransmission, we need to do
 789                                  * slow start.  Set the ssthresh to one
 790                                  * half of current effective window and
 791                                  * cwnd to one MSS.  Also reset
 792                                  * tcp_cwnd_cnt.
 793                                  *
 794                                  * Note that if tcp_ssthresh is reduced because
 795                                  * of ECN, do not reduce it again unless it is
 796                                  * already one window of data away (tcp_cwr
 797                                  * should then be cleared) or this is a
 798                                  * timeout for a retransmitted segment.
 799                                  */
 800                                 uint32_t npkt;
 801 
 802                                 if (!tcp->tcp_cwr || tcp->tcp_rexmit) {
 803                                         npkt = ((tcp->tcp_timer_backoff ?
 804                                             tcp->tcp_cwnd_ssthresh :
 805                                             tcp->tcp_snxt -
 806                                             tcp->tcp_suna) >> 1) / tcp->tcp_mss;
 807                                         tcp->tcp_cwnd_ssthresh = MAX(npkt, 2) *
 808                                             tcp->tcp_mss;
 809                                 }
 810                                 tcp->tcp_cwnd = tcp->tcp_mss;
 811                                 tcp->tcp_cwnd_cnt = 0;
 812                                 if (tcp->tcp_ecn_ok) {
 813                                         tcp->tcp_cwr = B_TRUE;
 814                                         tcp->tcp_cwr_snd_max = tcp->tcp_snxt;
 815                                         tcp->tcp_ecn_cwr_sent = B_FALSE;
 816                                 }
 817                         }
 818                         break;
 819                 }
 820                 /*
 821                  * We have something to send yet we cannot send.  The
 822                  * reason can be:
 823                  *
 824                  * 1. Zero send window: we need to do zero window probe.
 825                  * 2. Zero cwnd: because of ECN, we need to "clock out
 826                  * segments.
 827                  * 3. SWS avoidance: receiver may have shrunk window,
 828                  * reset our knowledge.
 829                  *
 830                  * Note that condition 2 can happen with either 1 or
 831                  * 3.  But 1 and 3 are exclusive.
 832                  */
 833                 if (tcp->tcp_unsent != 0) {
 834                         /*
 835                          * Should not hold the zero-copy messages for too long.
 836                          */
 837                         if (tcp->tcp_snd_zcopy_aware && !tcp->tcp_xmit_zc_clean)




   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright 2011 Joyent, Inc.  All rights reserved.
  26  * Copyright (c) 2014, 2017 by Delphix. All rights reserved.
  27  */
  28 
  29 #include <sys/types.h>
  30 #include <sys/strlog.h>
  31 #include <sys/strsun.h>
  32 #include <sys/squeue_impl.h>
  33 #include <sys/squeue.h>
  34 #include <sys/callo.h>
  35 #include <sys/strsubr.h>
  36 
  37 #include <inet/common.h>
  38 #include <inet/ip.h>
  39 #include <inet/ip_ire.h>
  40 #include <inet/ip_rts.h>
  41 #include <inet/tcp.h>
  42 #include <inet/tcp_impl.h>
  43 
  44 /*
  45  * Implementation of TCP Timers.
  46  * =============================


 767                                 TCP_STAT(tcps, tcp_timer_fire_early);
 768                                 TCP_TIMER_RESTART(tcp, time_to_wait);
 769                                 return;
 770                         }
 771                         /*
 772                          * When we probe zero windows, we force the swnd open.
 773                          * If our peer acks with a closed window swnd will be
 774                          * set to zero by tcp_rput(). As long as we are
 775                          * receiving acks tcp_rput will
 776                          * reset 'tcp_ms_we_have_waited' so as not to trip the
 777                          * first and second interval actions.  NOTE: the timer
 778                          * interval is allowed to continue its exponential
 779                          * backoff.
 780                          */
 781                         if (tcp->tcp_swnd == 0 || tcp->tcp_zero_win_probe) {
 782                                 if (connp->conn_debug) {
 783                                         (void) strlog(TCP_MOD_ID, 0, 1,
 784                                             SL_TRACE, "tcp_timer: zero win");
 785                                 }
 786                         } else {
 787                                 cc_cong_signal(tcp, NULL, CC_RTO);





















 788                         }








 789                         break;
 790                 }
 791                 /*
 792                  * We have something to send yet we cannot send.  The
 793                  * reason can be:
 794                  *
 795                  * 1. Zero send window: we need to do zero window probe.
 796                  * 2. Zero cwnd: because of ECN, we need to "clock out
 797                  * segments.
 798                  * 3. SWS avoidance: receiver may have shrunk window,
 799                  * reset our knowledge.
 800                  *
 801                  * Note that condition 2 can happen with either 1 or
 802                  * 3.  But 1 and 3 are exclusive.
 803                  */
 804                 if (tcp->tcp_unsent != 0) {
 805                         /*
 806                          * Should not hold the zero-copy messages for too long.
 807                          */
 808                         if (tcp->tcp_snd_zcopy_aware && !tcp->tcp_xmit_zc_clean)