|
@@ -2081,6 +2081,36 @@ static bool tcp_small_queue_check(struct sock *sk, const struct sk_buff *skb,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+static void tcp_chrono_set(struct tcp_sock *tp, const enum tcp_chrono new)
|
|
|
+{
|
|
|
+ const u32 now = tcp_time_stamp;
|
|
|
+
|
|
|
+ if (tp->chrono_type > TCP_CHRONO_UNSPEC)
|
|
|
+ tp->chrono_stat[tp->chrono_type - 1] += now - tp->chrono_start;
|
|
|
+ tp->chrono_start = now;
|
|
|
+ tp->chrono_type = new;
|
|
|
+}
|
|
|
+
|
|
|
+void tcp_chrono_start(struct sock *sk, const enum tcp_chrono type)
|
|
|
+{
|
|
|
+ struct tcp_sock *tp = tcp_sk(sk);
|
|
|
+
|
|
|
+ /* If there are multiple conditions worthy of tracking in a
|
|
|
+ * chronograph then the highest priority enum takes precedence over
|
|
|
+ * the other conditions. So that if something "more interesting"
|
|
|
+ * starts happening, stop the previous chrono and start a new one.
|
|
|
+ */
|
|
|
+ if (type > tp->chrono_type)
|
|
|
+ tcp_chrono_set(tp, type);
|
|
|
+}
|
|
|
+
|
|
|
+void tcp_chrono_stop(struct sock *sk, const enum tcp_chrono type)
|
|
|
+{
|
|
|
+ struct tcp_sock *tp = tcp_sk(sk);
|
|
|
+
|
|
|
+ tcp_chrono_set(tp, TCP_CHRONO_UNSPEC);
|
|
|
+}
|
|
|
+
|
|
|
/* This routine writes packets to the network. It advances the
|
|
|
* send_head. This happens as incoming acks open up the remote
|
|
|
* window for us.
|