Print this page
11546 Track TCP round-trip time in nanoseconds
Portions contributed by: Cody Peter Mello <cody.mello@joyent.com>
Portions contributed by: Brandon Baker <bbaker@delphix.com>
Reviewed by: Jason King <jason.king@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>

@@ -21,11 +21,11 @@
 
 /*
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
  * Copyright 2011 Joyent, Inc.  All rights reserved.
- * Copyright (c) 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2014, 2016 by Delphix. All rights reserved.
  */
 
 #include <sys/types.h>
 #include <sys/strlog.h>
 #include <sys/strsun.h>

@@ -754,14 +754,13 @@
                         clock_t time_to_wait;
 
                         TCPS_BUMP_MIB(tcps, tcpTimRetrans);
                         if (!tcp->tcp_xmit_head)
                                 break;
-                        time_to_wait = ddi_get_lbolt() -
-                            (clock_t)tcp->tcp_xmit_head->b_prev;
-                        time_to_wait = tcp->tcp_rto -
-                            TICK_TO_MSEC(time_to_wait);
+                        time_to_wait = NSEC2MSEC(gethrtime() -
+                            (hrtime_t)(intptr_t)tcp->tcp_xmit_head->b_prev);
+                        time_to_wait = tcp->tcp_rto - time_to_wait;
                         /*
                          * If the timer fires too early, 1 clock tick earlier,
                          * restart the timer.
                          */
                         if (time_to_wait > msec_per_tick) {

@@ -1010,38 +1009,28 @@
                  * tcp_rtt_update so that we won't accidentally cache a
                  * bad value.  But only do this if this is not a zero
                  * window probe.
                  */
                 if (tcp->tcp_rtt_sa != 0 && tcp->tcp_zero_win_probe == 0) {
-                        tcp->tcp_rtt_sd += (tcp->tcp_rtt_sa >> 3) +
-                            (tcp->tcp_rtt_sa >> 5);
+                        tcp->tcp_rtt_sd += tcp->tcp_rtt_sa >> 3 +
+                            tcp->tcp_rtt_sa >> 5;
                         tcp->tcp_rtt_sa = 0;
                         tcp_ip_notify(tcp);
                         tcp->tcp_rtt_update = 0;
                 }
         }
 
 timer_rexmit:
         tcp->tcp_timer_backoff++;
-        if ((ms = (tcp->tcp_rtt_sa >> 3) + tcp->tcp_rtt_sd +
-            tcps->tcps_rexmit_interval_extra + (tcp->tcp_rtt_sa >> 5)) <
-            tcp->tcp_rto_min) {
                 /*
-                 * This means the original RTO is tcp_rexmit_interval_min.
-                 * So we will use tcp_rexmit_interval_min as the RTO value
-                 * and do the backoff.
+         * Calculate the backed off retransmission timeout. If the shift brings
+         * us back over the max, then we repin the value, and decrement the
+         * backoff to avoid overflow.
                  */
-                ms = tcp->tcp_rto_min << tcp->tcp_timer_backoff;
-        } else {
-                ms <<= tcp->tcp_timer_backoff;
-        }
+        ms = tcp_calculate_rto(tcp, tcps, 0) << tcp->tcp_timer_backoff;
         if (ms > tcp->tcp_rto_max) {
                 ms = tcp->tcp_rto_max;
-                /*
-                 * ms is at max, decrement tcp_timer_backoff to avoid
-                 * overflow.
-                 */
                 tcp->tcp_timer_backoff--;
         }
         tcp->tcp_ms_we_have_waited += ms;
         if (tcp->tcp_zero_win_probe == 0) {
                 tcp->tcp_rto = ms;

@@ -1057,12 +1046,13 @@
         if (mss > tcp->tcp_mss)
                 mss = tcp->tcp_mss;
         if (mss > tcp->tcp_swnd && tcp->tcp_swnd != 0)
                 mss = tcp->tcp_swnd;
 
-        if ((mp = tcp->tcp_xmit_head) != NULL)
-                mp->b_prev = (mblk_t *)ddi_get_lbolt();
+        if ((mp = tcp->tcp_xmit_head) != NULL) {
+                mp->b_prev = (mblk_t *)(intptr_t)gethrtime();
+        }
         mp = tcp_xmit_mp(tcp, mp, mss, NULL, NULL, tcp->tcp_suna, B_TRUE, &mss,
             B_TRUE);
 
         /*
          * When slow start after retransmission begins, start with