mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			10578 lines
		
	
	
	
		
			348 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			10578 lines
		
	
	
	
		
			348 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 092758f89a20d9d2f00ce022152ed447ee1b0380 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Tue, 11 Jun 2019 12:26:55 -0400
 | 
						|
Subject: [PATCH 01/27] net-tcp_bbr: broaden app-limited rate sample detection
 | 
						|
 | 
						|
This commit is a bug fix for the Linux TCP app-limited
 | 
						|
(application-limited) logic that is used for collecting rate
 | 
						|
(bandwidth) samples.
 | 
						|
 | 
						|
Previously the app-limited logic only looked for "bubbles" of
 | 
						|
silence in between application writes, by checking at the start
 | 
						|
of each sendmsg. But "bubbles" of silence can also happen before
 | 
						|
retransmits: e.g. bubbles can happen between an application write
 | 
						|
and a retransmit, or between two retransmits.
 | 
						|
 | 
						|
Retransmits are triggered by ACKs or timers. So this commit checks
 | 
						|
for bubbles of app-limited silence upon ACKs or timers.
 | 
						|
 | 
						|
Why does this commit check for app-limited state at the start of
 | 
						|
ACKs and timer handling? Because at that point we know whether
 | 
						|
inflight was fully using the cwnd.  During processing the ACK or
 | 
						|
timer event we often change the cwnd; after changing the cwnd we
 | 
						|
can't know whether inflight was fully using the old cwnd.
 | 
						|
 | 
						|
Origin-9xx-SHA1: 3fe9b53291e018407780fb8c356adb5666722cbc
 | 
						|
Change-Id: I37221506f5166877c2b110753d39bb0757985e68
 | 
						|
---
 | 
						|
 net/ipv4/tcp_input.c | 1 +
 | 
						|
 net/ipv4/tcp_timer.c | 1 +
 | 
						|
 2 files changed, 2 insertions(+)
 | 
						|
 | 
						|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
 | 
						|
index 0640453fce54..1a308993c371 100644
 | 
						|
--- a/net/ipv4/tcp_input.c
 | 
						|
+++ b/net/ipv4/tcp_input.c
 | 
						|
@@ -3812,6 +3812,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
 | 
						|
 
 | 
						|
 	prior_fack = tcp_is_sack(tp) ? tcp_highest_sack_seq(tp) : tp->snd_una;
 | 
						|
 	rs.prior_in_flight = tcp_packets_in_flight(tp);
 | 
						|
+	tcp_rate_check_app_limited(sk);
 | 
						|
 
 | 
						|
 	/* ts_recent update must be made after we are sure that the packet
 | 
						|
 	 * is in window.
 | 
						|
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
 | 
						|
index cb79127f45c3..70e4de876a7f 100644
 | 
						|
--- a/net/ipv4/tcp_timer.c
 | 
						|
+++ b/net/ipv4/tcp_timer.c
 | 
						|
@@ -605,6 +605,7 @@ void tcp_write_timer_handler(struct sock *sk)
 | 
						|
 		return;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	tcp_rate_check_app_limited(sk);
 | 
						|
 	tcp_mstamp_refresh(tcp_sk(sk));
 | 
						|
 	event = icsk->icsk_pending;
 | 
						|
 
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 8ad58ff1db4ac78232203dcdc1e28c49263d8b6e Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Sun, 24 Jun 2018 21:55:59 -0400
 | 
						|
Subject: [PATCH 02/27] net-tcp_bbr: v2: shrink delivered_mstamp,
 | 
						|
 first_tx_mstamp to u32 to free up 8 bytes
 | 
						|
 | 
						|
Free up some space for tracking inflight and losses for each
 | 
						|
bw sample, in upcoming commits.
 | 
						|
 | 
						|
These timestamps are in microseconds, and are now stored in 32
 | 
						|
bits. So they can only hold time intervals up to roughly 2^12 = 4096
 | 
						|
seconds.  But Linux TCP RTT and RTO tracking has the same 32-bit
 | 
						|
microsecond implementation approach and resulting deployment
 | 
						|
limitations. So this is not introducing a new limit. And these should
 | 
						|
not be a limitation for the foreseeable future.
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: 238a7e6b5d51625fef1ce7769826a7b21b02ae55
 | 
						|
Change-Id: I3b779603797263b52a61ad57c565eb91fe42680c
 | 
						|
---
 | 
						|
 include/net/tcp.h   | 9 +++++++--
 | 
						|
 net/ipv4/tcp_rate.c | 7 ++++---
 | 
						|
 2 files changed, 11 insertions(+), 5 deletions(-)
 | 
						|
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index 5b70b241ce71..b4c0f5bed5dc 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -823,6 +823,11 @@ static inline u32 tcp_stamp_us_delta(u64 t1, u64 t0)
 | 
						|
 	return max_t(s64, t1 - t0, 0);
 | 
						|
 }
 | 
						|
 
 | 
						|
+static inline u32 tcp_stamp32_us_delta(u32 t1, u32 t0)
 | 
						|
+{
 | 
						|
+	return max_t(s32, t1 - t0, 0);
 | 
						|
+}
 | 
						|
+
 | 
						|
 static inline u32 tcp_skb_timestamp(const struct sk_buff *skb)
 | 
						|
 {
 | 
						|
 	return tcp_ns_to_ts(skb->skb_mstamp_ns);
 | 
						|
@@ -898,9 +903,9 @@ struct tcp_skb_cb {
 | 
						|
 			/* pkts S/ACKed so far upon tx of skb, incl retrans: */
 | 
						|
 			__u32 delivered;
 | 
						|
 			/* start of send pipeline phase */
 | 
						|
-			u64 first_tx_mstamp;
 | 
						|
+			u32 first_tx_mstamp;
 | 
						|
 			/* when we reached the "delivered" count */
 | 
						|
-			u64 delivered_mstamp;
 | 
						|
+			u32 delivered_mstamp;
 | 
						|
 		} tx;   /* only used for outgoing skbs */
 | 
						|
 		union {
 | 
						|
 			struct inet_skb_parm	h4;
 | 
						|
diff --git a/net/ipv4/tcp_rate.c b/net/ipv4/tcp_rate.c
 | 
						|
index a8f6d9d06f2e..763362159fe9 100644
 | 
						|
--- a/net/ipv4/tcp_rate.c
 | 
						|
+++ b/net/ipv4/tcp_rate.c
 | 
						|
@@ -101,8 +101,9 @@ void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb,
 | 
						|
 		/* Record send time of most recently ACKed packet: */
 | 
						|
 		tp->first_tx_mstamp  = tx_tstamp;
 | 
						|
 		/* Find the duration of the "send phase" of this window: */
 | 
						|
-		rs->interval_us = tcp_stamp_us_delta(tp->first_tx_mstamp,
 | 
						|
-						     scb->tx.first_tx_mstamp);
 | 
						|
+		rs->interval_us      = tcp_stamp32_us_delta(
 | 
						|
+						tp->first_tx_mstamp,
 | 
						|
+						scb->tx.first_tx_mstamp);
 | 
						|
 
 | 
						|
 	}
 | 
						|
 	/* Mark off the skb delivered once it's sacked to avoid being
 | 
						|
@@ -155,7 +156,7 @@ void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost,
 | 
						|
 	 * longer phase.
 | 
						|
 	 */
 | 
						|
 	snd_us = rs->interval_us;				/* send phase */
 | 
						|
-	ack_us = tcp_stamp_us_delta(tp->tcp_mstamp,
 | 
						|
+	ack_us = tcp_stamp32_us_delta(tp->tcp_mstamp,
 | 
						|
 				    rs->prior_mstamp); /* ack phase */
 | 
						|
 	rs->interval_us = max(snd_us, ack_us);
 | 
						|
 
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From a9db2da3c0026dddcdf6dab05c5c30d67fbeb32f Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Sat, 5 Aug 2017 11:49:50 -0400
 | 
						|
Subject: [PATCH 03/27] net-tcp_bbr: v2: snapshot packets in flight at transmit
 | 
						|
 time and pass in rate_sample
 | 
						|
 | 
						|
For understanding the relationship between inflight and losses or ECN
 | 
						|
signals, to try to find the highest inflight value that has acceptable
 | 
						|
levels of loss/ECN marking.
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: b3eb4f2d20efab4ca001f32c9294739036c493ea
 | 
						|
Change-Id: I7314047d0ff14dd261a04b1969a46dc658c8836a
 | 
						|
---
 | 
						|
 include/net/tcp.h   |  5 +++++
 | 
						|
 net/ipv4/tcp_rate.c | 14 ++++++++++++++
 | 
						|
 2 files changed, 19 insertions(+)
 | 
						|
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index b4c0f5bed5dc..21709e740fe2 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -906,6 +906,10 @@ struct tcp_skb_cb {
 | 
						|
 			u32 first_tx_mstamp;
 | 
						|
 			/* when we reached the "delivered" count */
 | 
						|
 			u32 delivered_mstamp;
 | 
						|
+#define TCPCB_IN_FLIGHT_BITS 20
 | 
						|
+#define TCPCB_IN_FLIGHT_MAX ((1U << TCPCB_IN_FLIGHT_BITS) - 1)
 | 
						|
+			u32 in_flight:20,   /* packets in flight at transmit */
 | 
						|
+			    unused2:12;
 | 
						|
 		} tx;   /* only used for outgoing skbs */
 | 
						|
 		union {
 | 
						|
 			struct inet_skb_parm	h4;
 | 
						|
@@ -1053,6 +1057,7 @@ struct rate_sample {
 | 
						|
 	u64  prior_mstamp; /* starting timestamp for interval */
 | 
						|
 	u32  prior_delivered;	/* tp->delivered at "prior_mstamp" */
 | 
						|
 	u32  prior_delivered_ce;/* tp->delivered_ce at "prior_mstamp" */
 | 
						|
+	u32 tx_in_flight;	/* packets in flight at starting timestamp */
 | 
						|
 	s32  delivered;		/* number of packets delivered over interval */
 | 
						|
 	s32  delivered_ce;	/* number of packets delivered w/ CE marks*/
 | 
						|
 	long interval_us;	/* time for tp->delivered to incr "delivered" */
 | 
						|
diff --git a/net/ipv4/tcp_rate.c b/net/ipv4/tcp_rate.c
 | 
						|
index 763362159fe9..782f44b4ee70 100644
 | 
						|
--- a/net/ipv4/tcp_rate.c
 | 
						|
+++ b/net/ipv4/tcp_rate.c
 | 
						|
@@ -40,6 +40,7 @@
 | 
						|
 void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb)
 | 
						|
 {
 | 
						|
 	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	u32 in_flight;
 | 
						|
 
 | 
						|
 	 /* In general we need to start delivery rate samples from the
 | 
						|
 	  * time we received the most recent ACK, to ensure we include
 | 
						|
@@ -67,6 +68,18 @@ void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb)
 | 
						|
 	TCP_SKB_CB(skb)->tx.delivered		= tp->delivered;
 | 
						|
 	TCP_SKB_CB(skb)->tx.delivered_ce	= tp->delivered_ce;
 | 
						|
 	TCP_SKB_CB(skb)->tx.is_app_limited	= tp->app_limited ? 1 : 0;
 | 
						|
+
 | 
						|
+	/* Check, sanitize, and record packets in flight after skb was sent. */
 | 
						|
+	in_flight = tcp_packets_in_flight(tp) + tcp_skb_pcount(skb);
 | 
						|
+	WARN_ONCE(in_flight > TCPCB_IN_FLIGHT_MAX,
 | 
						|
+		  "insane in_flight %u cc %s mss %u "
 | 
						|
+		  "cwnd %u pif %u %u %u %u\n",
 | 
						|
+		  in_flight, inet_csk(sk)->icsk_ca_ops->name,
 | 
						|
+		  tp->mss_cache, tp->snd_cwnd,
 | 
						|
+		  tp->packets_out, tp->retrans_out,
 | 
						|
+		  tp->sacked_out, tp->lost_out);
 | 
						|
+	in_flight = min(in_flight, TCPCB_IN_FLIGHT_MAX);
 | 
						|
+	TCP_SKB_CB(skb)->tx.in_flight		= in_flight;
 | 
						|
 }
 | 
						|
 
 | 
						|
 /* When an skb is sacked or acked, we fill in the rate sample with the (prior)
 | 
						|
@@ -97,6 +110,7 @@ void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb,
 | 
						|
 		rs->is_app_limited   = scb->tx.is_app_limited;
 | 
						|
 		rs->is_retrans	     = scb->sacked & TCPCB_RETRANS;
 | 
						|
 		rs->last_end_seq     = scb->end_seq;
 | 
						|
+		rs->tx_in_flight     = scb->tx.in_flight;
 | 
						|
 
 | 
						|
 		/* Record send time of most recently ACKed packet: */
 | 
						|
 		tp->first_tx_mstamp  = tx_tstamp;
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 5a337e11773eae0a4eeb855751d1af54f78ac370 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Thu, 12 Oct 2017 23:44:27 -0400
 | 
						|
Subject: [PATCH 04/27] net-tcp_bbr: v2: count packets lost over TCP rate
 | 
						|
 sampling interval
 | 
						|
 | 
						|
For understanding the relationship between inflight and packet loss
 | 
						|
signals, to try to find the highest inflight value that has acceptable
 | 
						|
levels of packet losses.
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: 4527e26b2bd7756a88b5b9ef1ada3da33dd609ab
 | 
						|
Change-Id: I594c2500868d9c530770e7ddd68ffc87c57f4fd5
 | 
						|
---
 | 
						|
 include/net/tcp.h   | 5 ++++-
 | 
						|
 net/ipv4/tcp_rate.c | 3 +++
 | 
						|
 2 files changed, 7 insertions(+), 1 deletion(-)
 | 
						|
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index 21709e740fe2..9c5d7575e659 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -910,6 +910,7 @@ struct tcp_skb_cb {
 | 
						|
 #define TCPCB_IN_FLIGHT_MAX ((1U << TCPCB_IN_FLIGHT_BITS) - 1)
 | 
						|
 			u32 in_flight:20,   /* packets in flight at transmit */
 | 
						|
 			    unused2:12;
 | 
						|
+			u32 lost;	/* packets lost so far upon tx of skb */
 | 
						|
 		} tx;   /* only used for outgoing skbs */
 | 
						|
 		union {
 | 
						|
 			struct inet_skb_parm	h4;
 | 
						|
@@ -1055,11 +1056,13 @@ struct ack_sample {
 | 
						|
  */
 | 
						|
 struct rate_sample {
 | 
						|
 	u64  prior_mstamp; /* starting timestamp for interval */
 | 
						|
+	u32  prior_lost;	/* tp->lost at "prior_mstamp" */
 | 
						|
 	u32  prior_delivered;	/* tp->delivered at "prior_mstamp" */
 | 
						|
 	u32  prior_delivered_ce;/* tp->delivered_ce at "prior_mstamp" */
 | 
						|
 	u32 tx_in_flight;	/* packets in flight at starting timestamp */
 | 
						|
+	s32  lost;		/* number of packets lost over interval */
 | 
						|
 	s32  delivered;		/* number of packets delivered over interval */
 | 
						|
-	s32  delivered_ce;	/* number of packets delivered w/ CE marks*/
 | 
						|
+	s32  delivered_ce;	/* packets delivered w/ CE mark over interval */
 | 
						|
 	long interval_us;	/* time for tp->delivered to incr "delivered" */
 | 
						|
 	u32 snd_interval_us;	/* snd interval for delivered packets */
 | 
						|
 	u32 rcv_interval_us;	/* rcv interval for delivered packets */
 | 
						|
diff --git a/net/ipv4/tcp_rate.c b/net/ipv4/tcp_rate.c
 | 
						|
index 782f44b4ee70..e985026fc037 100644
 | 
						|
--- a/net/ipv4/tcp_rate.c
 | 
						|
+++ b/net/ipv4/tcp_rate.c
 | 
						|
@@ -67,6 +67,7 @@ void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb)
 | 
						|
 	TCP_SKB_CB(skb)->tx.delivered_mstamp	= tp->delivered_mstamp;
 | 
						|
 	TCP_SKB_CB(skb)->tx.delivered		= tp->delivered;
 | 
						|
 	TCP_SKB_CB(skb)->tx.delivered_ce	= tp->delivered_ce;
 | 
						|
+	TCP_SKB_CB(skb)->tx.lost		= tp->lost;
 | 
						|
 	TCP_SKB_CB(skb)->tx.is_app_limited	= tp->app_limited ? 1 : 0;
 | 
						|
 
 | 
						|
 	/* Check, sanitize, and record packets in flight after skb was sent. */
 | 
						|
@@ -104,6 +105,7 @@ void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb,
 | 
						|
 	if (!rs->prior_delivered ||
 | 
						|
 	    tcp_skb_sent_after(tx_tstamp, tp->first_tx_mstamp,
 | 
						|
 			       scb->end_seq, rs->last_end_seq)) {
 | 
						|
+		rs->prior_lost	     = scb->tx.lost;
 | 
						|
 		rs->prior_delivered_ce  = scb->tx.delivered_ce;
 | 
						|
 		rs->prior_delivered  = scb->tx.delivered;
 | 
						|
 		rs->prior_mstamp     = scb->tx.delivered_mstamp;
 | 
						|
@@ -159,6 +161,7 @@ void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost,
 | 
						|
 		return;
 | 
						|
 	}
 | 
						|
 	rs->delivered   = tp->delivered - rs->prior_delivered;
 | 
						|
+	rs->lost        = tp->lost - rs->prior_lost;
 | 
						|
 
 | 
						|
 	rs->delivered_ce = tp->delivered_ce - rs->prior_delivered_ce;
 | 
						|
 	/* delivered_ce occupies less than 32 bits in the skb control block */
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 48c6bc09a6028e11a74c694dd993b080a09abf75 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Mon, 19 Nov 2018 13:48:36 -0500
 | 
						|
Subject: [PATCH 05/27] net-tcp_bbr: v2: export FLAG_ECE in rate_sample.is_ece
 | 
						|
 | 
						|
For understanding the relationship between inflight and ECN signals,
 | 
						|
to try to find the highest inflight value that has acceptable levels
 | 
						|
ECN marking.
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: 3eba998f2898541406c2666781182200934965a8
 | 
						|
Change-Id: I3a964e04cee83e11649a54507043d2dfe769a3b3
 | 
						|
---
 | 
						|
 include/net/tcp.h    | 1 +
 | 
						|
 net/ipv4/tcp_input.c | 1 +
 | 
						|
 2 files changed, 2 insertions(+)
 | 
						|
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index 9c5d7575e659..7072b785839f 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -1074,6 +1074,7 @@ struct rate_sample {
 | 
						|
 	bool is_app_limited;	/* is sample from packet with bubble in pipe? */
 | 
						|
 	bool is_retrans;	/* is sample from retransmission? */
 | 
						|
 	bool is_ack_delayed;	/* is this (likely) a delayed ACK? */
 | 
						|
+	bool is_ece;		/* did this ACK have ECN marked? */
 | 
						|
 };
 | 
						|
 
 | 
						|
 struct tcp_congestion_ops {
 | 
						|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
 | 
						|
index 1a308993c371..b089111bbe62 100644
 | 
						|
--- a/net/ipv4/tcp_input.c
 | 
						|
+++ b/net/ipv4/tcp_input.c
 | 
						|
@@ -3911,6 +3911,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
 | 
						|
 	delivered = tcp_newly_delivered(sk, delivered, flag);
 | 
						|
 	lost = tp->lost - lost;			/* freshly marked lost */
 | 
						|
 	rs.is_ack_delayed = !!(flag & FLAG_ACK_MAYBE_DELAYED);
 | 
						|
+	rs.is_ece = !!(flag & FLAG_ECE);
 | 
						|
 	tcp_rate_gen(sk, delivered, lost, is_sack_reneg, sack_state.rate);
 | 
						|
 	tcp_cong_control(sk, ack, delivered, flag, sack_state.rate);
 | 
						|
 	tcp_xmit_recovery(sk, rexmit);
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 721e70a3b75b30b517bb27d84f227322ac8a4e62 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Tue, 7 Aug 2018 21:52:06 -0400
 | 
						|
Subject: [PATCH 06/27] net-tcp_bbr: v2: introduce ca_ops->skb_marked_lost() CC
 | 
						|
 module callback API
 | 
						|
 | 
						|
For connections experiencing reordering, RACK can mark packets lost
 | 
						|
long after we receive the SACKs/ACKs hinting that the packets were
 | 
						|
actually lost.
 | 
						|
 | 
						|
This means that CC modules cannot easily learn the volume of inflight
 | 
						|
data at which packet loss happens by looking at the current inflight
 | 
						|
or even the packets in flight when the most recently SACKed packet was
 | 
						|
sent. To learn this, CC modules need to know how many packets were in
 | 
						|
flight at the time lost packets were sent. This new callback, combined
 | 
						|
with TCP_SKB_CB(skb)->tx.in_flight, allows them to learn this.
 | 
						|
 | 
						|
This also provides a consistent callback that is invoked whether
 | 
						|
packets are marked lost upon ACK processing, using the RACK reordering
 | 
						|
timer, or at RTO time.
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: afcbebe3374e4632ac6714d39e4dc8a8455956f4
 | 
						|
Change-Id: I54826ab53df636be537e5d3c618a46145d12d51a
 | 
						|
---
 | 
						|
 include/net/tcp.h    | 3 +++
 | 
						|
 net/ipv4/tcp_input.c | 5 +++++
 | 
						|
 2 files changed, 8 insertions(+)
 | 
						|
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index 7072b785839f..49c925270337 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -1101,6 +1101,9 @@ struct tcp_congestion_ops {
 | 
						|
 	/* override sysctl_tcp_min_tso_segs */
 | 
						|
 	u32 (*min_tso_segs)(struct sock *sk);
 | 
						|
 
 | 
						|
+	/* react to a specific lost skb (optional) */
 | 
						|
+	void (*skb_marked_lost)(struct sock *sk, const struct sk_buff *skb);
 | 
						|
+
 | 
						|
 	/* call when packets are delivered to update cwnd and pacing rate,
 | 
						|
 	 * after all the ca_state processing. (optional)
 | 
						|
 	 */
 | 
						|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
 | 
						|
index b089111bbe62..8f76bdea1bd9 100644
 | 
						|
--- a/net/ipv4/tcp_input.c
 | 
						|
+++ b/net/ipv4/tcp_input.c
 | 
						|
@@ -1079,7 +1079,12 @@ static void tcp_verify_retransmit_hint(struct tcp_sock *tp, struct sk_buff *skb)
 | 
						|
  */
 | 
						|
 static void tcp_notify_skb_loss_event(struct tcp_sock *tp, const struct sk_buff *skb)
 | 
						|
 {
 | 
						|
+	struct sock *sk = (struct sock *)tp;
 | 
						|
+	const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;
 | 
						|
+
 | 
						|
 	tp->lost += tcp_skb_pcount(skb);
 | 
						|
+	if (ca_ops->skb_marked_lost)
 | 
						|
+		ca_ops->skb_marked_lost(sk, skb);
 | 
						|
 }
 | 
						|
 
 | 
						|
 void tcp_mark_skb_lost(struct sock *sk, struct sk_buff *skb)
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From ddc77e8fe5229a7cbd52d4af7edde7fa2734a0e1 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Tue, 7 May 2019 22:36:36 -0400
 | 
						|
Subject: [PATCH 07/27] net-tcp_bbr: v2: factor out tx.in_flight setting into
 | 
						|
 tcp_set_tx_in_flight()
 | 
						|
 | 
						|
Factor out the code to set an skb's tx.in_flight field into its own
 | 
						|
function, so that this code can be used for the TCP_REPAIR "fake send"
 | 
						|
code path that inserts skbs into the rtx queue without sending
 | 
						|
them. This is in preparation for the following patch, which fixes an
 | 
						|
issue with TCP_REPAIR and tx.in_flight.
 | 
						|
 | 
						|
Tested: See last patch in series for sponge link.
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: e880fc907d06ea7354333f60f712748ebce9497b
 | 
						|
Change-Id: I4fbd4a6e18a51ab06d50ab1c9ad820ce5bea89af
 | 
						|
---
 | 
						|
 include/net/tcp.h   |  1 +
 | 
						|
 net/ipv4/tcp_rate.c | 32 +++++++++++++++++++-------------
 | 
						|
 2 files changed, 20 insertions(+), 13 deletions(-)
 | 
						|
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index 49c925270337..1ab6b2753236 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -1184,6 +1184,7 @@ static inline void tcp_ca_event(struct sock *sk, const enum tcp_ca_event event)
 | 
						|
 void tcp_set_ca_state(struct sock *sk, const u8 ca_state);
 | 
						|
 
 | 
						|
 /* From tcp_rate.c */
 | 
						|
+void tcp_set_tx_in_flight(struct sock *sk, struct sk_buff *skb);
 | 
						|
 void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb);
 | 
						|
 void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb,
 | 
						|
 			    struct rate_sample *rs);
 | 
						|
diff --git a/net/ipv4/tcp_rate.c b/net/ipv4/tcp_rate.c
 | 
						|
index e985026fc037..a8b4c9504570 100644
 | 
						|
--- a/net/ipv4/tcp_rate.c
 | 
						|
+++ b/net/ipv4/tcp_rate.c
 | 
						|
@@ -34,13 +34,30 @@
 | 
						|
  * ready to send in the write queue.
 | 
						|
  */
 | 
						|
 
 | 
						|
+void tcp_set_tx_in_flight(struct sock *sk, struct sk_buff *skb)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	u32 in_flight;
 | 
						|
+
 | 
						|
+	/* Check, sanitize, and record packets in flight after skb was sent. */
 | 
						|
+	in_flight = tcp_packets_in_flight(tp) + tcp_skb_pcount(skb);
 | 
						|
+	if (WARN_ONCE(in_flight > TCPCB_IN_FLIGHT_MAX,
 | 
						|
+		      "insane in_flight %u cc %s mss %u "
 | 
						|
+		      "cwnd %u pif %u %u %u %u\n",
 | 
						|
+		      in_flight, inet_csk(sk)->icsk_ca_ops->name,
 | 
						|
+		      tp->mss_cache, tp->snd_cwnd,
 | 
						|
+		      tp->packets_out, tp->retrans_out,
 | 
						|
+		      tp->sacked_out, tp->lost_out))
 | 
						|
+		in_flight = TCPCB_IN_FLIGHT_MAX;
 | 
						|
+	TCP_SKB_CB(skb)->tx.in_flight = in_flight;
 | 
						|
+}
 | 
						|
+
 | 
						|
 /* Snapshot the current delivery information in the skb, to generate
 | 
						|
  * a rate sample later when the skb is (s)acked in tcp_rate_skb_delivered().
 | 
						|
  */
 | 
						|
 void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb)
 | 
						|
 {
 | 
						|
 	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
-	u32 in_flight;
 | 
						|
 
 | 
						|
 	 /* In general we need to start delivery rate samples from the
 | 
						|
 	  * time we received the most recent ACK, to ensure we include
 | 
						|
@@ -69,18 +86,7 @@ void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb)
 | 
						|
 	TCP_SKB_CB(skb)->tx.delivered_ce	= tp->delivered_ce;
 | 
						|
 	TCP_SKB_CB(skb)->tx.lost		= tp->lost;
 | 
						|
 	TCP_SKB_CB(skb)->tx.is_app_limited	= tp->app_limited ? 1 : 0;
 | 
						|
-
 | 
						|
-	/* Check, sanitize, and record packets in flight after skb was sent. */
 | 
						|
-	in_flight = tcp_packets_in_flight(tp) + tcp_skb_pcount(skb);
 | 
						|
-	WARN_ONCE(in_flight > TCPCB_IN_FLIGHT_MAX,
 | 
						|
-		  "insane in_flight %u cc %s mss %u "
 | 
						|
-		  "cwnd %u pif %u %u %u %u\n",
 | 
						|
-		  in_flight, inet_csk(sk)->icsk_ca_ops->name,
 | 
						|
-		  tp->mss_cache, tp->snd_cwnd,
 | 
						|
-		  tp->packets_out, tp->retrans_out,
 | 
						|
-		  tp->sacked_out, tp->lost_out);
 | 
						|
-	in_flight = min(in_flight, TCPCB_IN_FLIGHT_MAX);
 | 
						|
-	TCP_SKB_CB(skb)->tx.in_flight		= in_flight;
 | 
						|
+	tcp_set_tx_in_flight(sk, skb);
 | 
						|
 }
 | 
						|
 
 | 
						|
 /* When an skb is sacked or acked, we fill in the rate sample with the (prior)
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 52dd9fd01e87674a3c57dbd8d2e10febc58130e6 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Wed, 1 May 2019 20:16:33 -0400
 | 
						|
Subject: [PATCH 08/27] net-tcp_bbr: v2: adjust skb tx.in_flight upon merge in
 | 
						|
 tcp_shifted_skb()
 | 
						|
 | 
						|
When tcp_shifted_skb() updates state as adjacent SACKed skbs are
 | 
						|
coalesced, previously the tx.in_flight was not adjusted, so we could
 | 
						|
get contradictory state where the skb's recorded pcount was bigger
 | 
						|
than the tx.in_flight (the number of segments that were in_flight
 | 
						|
after sending the skb).
 | 
						|
 | 
						|
Normally have a SACKed skb with contradictory pcount/tx.in_flight
 | 
						|
would not matter. However, with SACK reneging, the SACKed bit is
 | 
						|
removed, and an skb once again becomes eligible for retransmitting,
 | 
						|
fragmenting, SACKing, etc. Packetdrill testing verified the following
 | 
						|
sequence is possible in a kernel that does not have this commit:
 | 
						|
 | 
						|
 - skb N is SACKed
 | 
						|
 - skb N+1 is SACKed and combined with skb N using tcp_shifted_skb()
 | 
						|
   - tcp_shifted_skb() will increase the pcount of prev,
 | 
						|
     but leave tx.in_flight as-is
 | 
						|
   - so prev skb can have pcount > tx.in_flight
 | 
						|
 - RTO, tcp_timeout_mark_lost(), detect reneg,
 | 
						|
   remove "SACKed" bit, mark skb N as lost
 | 
						|
   - find pcount of skb N is greater than its tx.in_flight
 | 
						|
 | 
						|
I suspect this issue iw what caused the bbr2_inflight_hi_from_lost_skb():
 | 
						|
  WARN_ON_ONCE(inflight_prev < 0)
 | 
						|
to fire in production machines using bbr2.
 | 
						|
 | 
						|
Tested: See last commit in series for sponge link.
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: 1a3e997e613d2dcf32b947992882854ebe873715
 | 
						|
Change-Id: I1b0b75c27519953430c7db51c6f358f104c7af55
 | 
						|
---
 | 
						|
 net/ipv4/tcp_input.c | 11 +++++++++++
 | 
						|
 1 file changed, 11 insertions(+)
 | 
						|
 | 
						|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
 | 
						|
index 8f76bdea1bd9..394633fc9fa6 100644
 | 
						|
--- a/net/ipv4/tcp_input.c
 | 
						|
+++ b/net/ipv4/tcp_input.c
 | 
						|
@@ -1465,6 +1465,17 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *prev,
 | 
						|
 	WARN_ON_ONCE(tcp_skb_pcount(skb) < pcount);
 | 
						|
 	tcp_skb_pcount_add(skb, -pcount);
 | 
						|
 
 | 
						|
+	/* Adjust tx.in_flight as pcount is shifted from skb to prev. */
 | 
						|
+	if (WARN_ONCE(TCP_SKB_CB(skb)->tx.in_flight < pcount,
 | 
						|
+		      "prev in_flight: %u skb in_flight: %u pcount: %u",
 | 
						|
+		      TCP_SKB_CB(prev)->tx.in_flight,
 | 
						|
+		      TCP_SKB_CB(skb)->tx.in_flight,
 | 
						|
+		      pcount))
 | 
						|
+		TCP_SKB_CB(skb)->tx.in_flight = 0;
 | 
						|
+	else
 | 
						|
+		TCP_SKB_CB(skb)->tx.in_flight -= pcount;
 | 
						|
+	TCP_SKB_CB(prev)->tx.in_flight += pcount;
 | 
						|
+
 | 
						|
 	/* When we're adding to gso_segs == 1, gso_size will be zero,
 | 
						|
 	 * in theory this shouldn't be necessary but as long as DSACK
 | 
						|
 	 * code can come after this skb later on it's better to keep
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 8d8c4a58577e23dfb57406d36f71da10d9c5f1bb Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Wed, 1 May 2019 20:16:25 -0400
 | 
						|
Subject: [PATCH 09/27] net-tcp_bbr: v2: adjust skb tx.in_flight upon split in
 | 
						|
 tcp_fragment()
 | 
						|
 | 
						|
When we fragment an skb that has already been sent, we need to update
 | 
						|
the tx.in_flight for the first skb in the resulting pair ("buff").
 | 
						|
 | 
						|
Because we were not updating the tx.in_flight, the tx.in_flight value
 | 
						|
was inconsistent with the pcount of the "buff" skb (tx.in_flight would
 | 
						|
be too high). That meant that if the "buff" skb was lost, then
 | 
						|
bbr2_inflight_hi_from_lost_skb() would calculate an inflight_hi value
 | 
						|
that is too high. This could result in longer queues and higher packet
 | 
						|
loss.
 | 
						|
 | 
						|
Packetdrill testing verified that without this commit, when the second
 | 
						|
half of an skb is SACKed and then later the first half of that skb is
 | 
						|
marked lost, the calculated inflight_hi was incorrect.
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: 385f1ddc610798fab2837f9f372857438b25f874
 | 
						|
Change-Id: I617f8cab4e9be7a0b8e8d30b047bf8645393354d
 | 
						|
---
 | 
						|
 net/ipv4/tcp_output.c | 11 ++++++++++-
 | 
						|
 1 file changed, 10 insertions(+), 1 deletion(-)
 | 
						|
 | 
						|
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
 | 
						|
index c69f4d966024..82465a0cf921 100644
 | 
						|
--- a/net/ipv4/tcp_output.c
 | 
						|
+++ b/net/ipv4/tcp_output.c
 | 
						|
@@ -1533,7 +1533,7 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,
 | 
						|
 {
 | 
						|
 	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
 	struct sk_buff *buff;
 | 
						|
-	int nsize, old_factor;
 | 
						|
+	int nsize, old_factor, inflight_prev;
 | 
						|
 	long limit;
 | 
						|
 	int nlen;
 | 
						|
 	u8 flags;
 | 
						|
@@ -1610,6 +1610,15 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,
 | 
						|
 
 | 
						|
 		if (diff)
 | 
						|
 			tcp_adjust_pcount(sk, skb, diff);
 | 
						|
+
 | 
						|
+		/* Set buff tx.in_flight as if buff were sent by itself. */
 | 
						|
+		inflight_prev = TCP_SKB_CB(skb)->tx.in_flight - old_factor;
 | 
						|
+		if (WARN_ONCE(inflight_prev < 0,
 | 
						|
+			      "inconsistent: tx.in_flight: %u old_factor: %d",
 | 
						|
+			      TCP_SKB_CB(skb)->tx.in_flight, old_factor))
 | 
						|
+			inflight_prev = 0;
 | 
						|
+		TCP_SKB_CB(buff)->tx.in_flight = inflight_prev +
 | 
						|
+						 tcp_skb_pcount(buff);
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	/* Link BUFF into the send queue. */
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 8418f129970ad19ed9eb1dd5e4cd2ef50634a5a3 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Tue, 7 May 2019 22:37:19 -0400
 | 
						|
Subject: [PATCH 10/27] net-tcp_bbr: v2: set tx.in_flight for skbs in repair
 | 
						|
 write queue
 | 
						|
 | 
						|
Syzkaller was able to use TCP_REPAIR to reproduce the new warning
 | 
						|
added in tcp_fragment():
 | 
						|
 | 
						|
  WARNING: CPU: 0 PID: 118174 at net/ipv4/tcp_output.c:1487
 | 
						|
    tcp_fragment+0xdcc/0x10a0 net/ipv4/tcp_output.c:1487()
 | 
						|
  inconsistent: tx.in_flight: 0 old_factor: 53
 | 
						|
 | 
						|
The warning happens because skbs inserted into the tcp_rtx_queue
 | 
						|
during the repair process go through a sort of "fake send" process,
 | 
						|
and that process was seting pcount but not tx.in_flight, and thus the
 | 
						|
warnings (where old_factor is the old pcount).
 | 
						|
 | 
						|
The fix of setting tx.in_flight in the TCP_REPAIR code path seems
 | 
						|
simple enough, and indeed makes the repro code from syzkaller stop
 | 
						|
producing warnings. Running through kokonut tests, and will send out
 | 
						|
for review when all tests pass.
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: 330f825a08a6fe92cef74d799cc468864c479f63
 | 
						|
Change-Id: I0bc4a790f040fd4239620e1eedd5dc64666c6f05
 | 
						|
---
 | 
						|
 net/ipv4/tcp_output.c | 1 +
 | 
						|
 1 file changed, 1 insertion(+)
 | 
						|
 | 
						|
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
 | 
						|
index 82465a0cf921..95816a1a5858 100644
 | 
						|
--- a/net/ipv4/tcp_output.c
 | 
						|
+++ b/net/ipv4/tcp_output.c
 | 
						|
@@ -2644,6 +2644,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
 | 
						|
 			skb_set_delivery_time(skb, tp->tcp_wstamp_ns, true);
 | 
						|
 			list_move_tail(&skb->tcp_tsorted_anchor, &tp->tsorted_sent_queue);
 | 
						|
 			tcp_init_tso_segs(skb, mss_now);
 | 
						|
+			tcp_set_tx_in_flight(sk, skb);
 | 
						|
 			goto repair; /* Skip network transmission */
 | 
						|
 		}
 | 
						|
 
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From cffd0b97c891dd51ce52c95d2738e4628d6d217c Mon Sep 17 00:00:00 2001
 | 
						|
From: Yousuk Seung <ysseung@google.com>
 | 
						|
Date: Wed, 23 May 2018 17:55:54 -0700
 | 
						|
Subject: [PATCH 11/27] net-tcp: add new ca opts flag TCP_CONG_WANTS_CE_EVENTS
 | 
						|
 | 
						|
Add a a new ca opts flag TCP_CONG_WANTS_CE_EVENTS that allows a
 | 
						|
congestion control module to receive CE events.
 | 
						|
 | 
						|
Currently congestion control modules have to set the TCP_CONG_NEEDS_ECN
 | 
						|
bit in opts flag to receive CE events but this may incur changes in ECN
 | 
						|
behavior elsewhere. This patch adds a new bit TCP_CONG_WANTS_CE_EVENTS
 | 
						|
that allows congestion control modules to receive CE events
 | 
						|
independently of TCP_CONG_NEEDS_ECN.
 | 
						|
 | 
						|
Effort: net-tcp
 | 
						|
Origin-9xx-SHA1: 9f7e14716cde760bc6c67ef8ef7e1ee48501d95b
 | 
						|
Change-Id: I2255506985242f376d910c6fd37daabaf4744f24
 | 
						|
---
 | 
						|
 include/net/tcp.h    | 14 +++++++++++++-
 | 
						|
 net/ipv4/tcp_input.c |  4 ++--
 | 
						|
 2 files changed, 15 insertions(+), 3 deletions(-)
 | 
						|
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index 1ab6b2753236..989aaedc2e4a 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -1036,7 +1036,11 @@ enum tcp_ca_ack_event_flags {
 | 
						|
 #define TCP_CONG_NON_RESTRICTED 0x1
 | 
						|
 /* Requires ECN/ECT set on all packets */
 | 
						|
 #define TCP_CONG_NEEDS_ECN	0x2
 | 
						|
-#define TCP_CONG_MASK	(TCP_CONG_NON_RESTRICTED | TCP_CONG_NEEDS_ECN)
 | 
						|
+/* Wants notification of CE events (CA_EVENT_ECN_IS_CE, CA_EVENT_ECN_NO_CE). */
 | 
						|
+#define TCP_CONG_WANTS_CE_EVENTS	0x4
 | 
						|
+#define TCP_CONG_MASK	(TCP_CONG_NON_RESTRICTED | \
 | 
						|
+			 TCP_CONG_NEEDS_ECN | \
 | 
						|
+			 TCP_CONG_WANTS_CE_EVENTS)
 | 
						|
 
 | 
						|
 union tcp_cc_info;
 | 
						|
 
 | 
						|
@@ -1165,6 +1169,14 @@ static inline char *tcp_ca_get_name_by_key(u32 key, char *buffer)
 | 
						|
 }
 | 
						|
 #endif
 | 
						|
 
 | 
						|
+static inline bool tcp_ca_wants_ce_events(const struct sock *sk)
 | 
						|
+{
 | 
						|
+	const struct inet_connection_sock *icsk = inet_csk(sk);
 | 
						|
+
 | 
						|
+	return icsk->icsk_ca_ops->flags & (TCP_CONG_NEEDS_ECN |
 | 
						|
+					   TCP_CONG_WANTS_CE_EVENTS);
 | 
						|
+}
 | 
						|
+
 | 
						|
 static inline bool tcp_ca_needs_ecn(const struct sock *sk)
 | 
						|
 {
 | 
						|
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 | 
						|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
 | 
						|
index 394633fc9fa6..82a68b768be4 100644
 | 
						|
--- a/net/ipv4/tcp_input.c
 | 
						|
+++ b/net/ipv4/tcp_input.c
 | 
						|
@@ -349,7 +349,7 @@ static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb)
 | 
						|
 			tcp_enter_quickack_mode(sk, 2);
 | 
						|
 		break;
 | 
						|
 	case INET_ECN_CE:
 | 
						|
-		if (tcp_ca_needs_ecn(sk))
 | 
						|
+		if (tcp_ca_wants_ce_events(sk))
 | 
						|
 			tcp_ca_event(sk, CA_EVENT_ECN_IS_CE);
 | 
						|
 
 | 
						|
 		if (!(tp->ecn_flags & TCP_ECN_DEMAND_CWR)) {
 | 
						|
@@ -360,7 +360,7 @@ static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb)
 | 
						|
 		tp->ecn_flags |= TCP_ECN_SEEN;
 | 
						|
 		break;
 | 
						|
 	default:
 | 
						|
-		if (tcp_ca_needs_ecn(sk))
 | 
						|
+		if (tcp_ca_wants_ce_events(sk))
 | 
						|
 			tcp_ca_event(sk, CA_EVENT_ECN_NO_CE);
 | 
						|
 		tp->ecn_flags |= TCP_ECN_SEEN;
 | 
						|
 		break;
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From a827b3564662d4b300dbc03e062740ec5df12c86 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Fri, 27 Sep 2019 17:10:26 -0400
 | 
						|
Subject: [PATCH 12/27] net-tcp: re-generalize TSO sizing in TCP CC module API
 | 
						|
 | 
						|
Reorganize the API for CC modules so that the CC module once again
 | 
						|
gets complete control of the TSO sizing decision. This is how the API
 | 
						|
was set up around 2016 and the initial BBRv1 upstreaming. Later Eric
 | 
						|
Dumazet simplified it. But with wider testing it now seems that to
 | 
						|
avoid CPU regressions BBR needs to have a different TSO sizing
 | 
						|
function.
 | 
						|
 | 
						|
This is necessary to handle cases where there are many flows
 | 
						|
bottlenecked on the sender host's NIC, in which case BBR's pacing rate
 | 
						|
is much lower than CUBIC/Reno/DCTCP's. Why does this happen? Because
 | 
						|
BBR's pacing rate adapts to the low bandwidth share each flow sees. By
 | 
						|
contrast, CUBIC/Reno/DCTCP see no loss or ECN, so they grow a very
 | 
						|
large cwnd, and thus large pacing rate and large TSO burst size.
 | 
						|
 | 
						|
Change-Id: Ic8ccfdbe4010ee8d4bf6a6334c48a2fceb2171ea
 | 
						|
---
 | 
						|
 include/net/tcp.h     |  4 ++--
 | 
						|
 net/ipv4/tcp_bbr.c    | 38 ++++++++++++++++++++++++++------------
 | 
						|
 net/ipv4/tcp_output.c | 11 +++++------
 | 
						|
 3 files changed, 33 insertions(+), 20 deletions(-)
 | 
						|
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index 989aaedc2e4a..b65268d3a3c2 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -1102,8 +1102,8 @@ struct tcp_congestion_ops {
 | 
						|
 	/* hook for packet ack accounting (optional) */
 | 
						|
 	void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample);
 | 
						|
 
 | 
						|
-	/* override sysctl_tcp_min_tso_segs */
 | 
						|
-	u32 (*min_tso_segs)(struct sock *sk);
 | 
						|
+	/* pick target number of segments per TSO/GSO skb (optional): */
 | 
						|
+	u32 (*tso_segs)(struct sock *sk, unsigned int mss_now);
 | 
						|
 
 | 
						|
 	/* react to a specific lost skb (optional) */
 | 
						|
 	void (*skb_marked_lost)(struct sock *sk, const struct sk_buff *skb);
 | 
						|
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c
 | 
						|
index 54eec33c6e1c..fbd8fa11acca 100644
 | 
						|
--- a/net/ipv4/tcp_bbr.c
 | 
						|
+++ b/net/ipv4/tcp_bbr.c
 | 
						|
@@ -294,26 +294,40 @@ static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain)
 | 
						|
 		sk->sk_pacing_rate = rate;
 | 
						|
 }
 | 
						|
 
 | 
						|
-/* override sysctl_tcp_min_tso_segs */
 | 
						|
 static u32 bbr_min_tso_segs(struct sock *sk)
 | 
						|
 {
 | 
						|
 	return sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2;
 | 
						|
 }
 | 
						|
 
 | 
						|
+/* Return the number of segments BBR would like in a TSO/GSO skb, given
 | 
						|
+ * a particular max gso size as a constraint.
 | 
						|
+ */
 | 
						|
+static u32 bbr_tso_segs_generic(struct sock *sk, unsigned int mss_now,
 | 
						|
+				u32 gso_max_size)
 | 
						|
+{
 | 
						|
+	u32 segs;
 | 
						|
+	u32 bytes;
 | 
						|
+
 | 
						|
+	/* Budget a TSO/GSO burst size allowance based on bw (pacing_rate). */
 | 
						|
+	bytes = sk->sk_pacing_rate >> sk->sk_pacing_shift;
 | 
						|
+
 | 
						|
+	bytes = min_t(u32, bytes, gso_max_size - 1 - MAX_TCP_HEADER);
 | 
						|
+	segs = max_t(u32, bytes / mss_now, bbr_min_tso_segs(sk));
 | 
						|
+	return segs;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Custom tcp_tso_autosize() for BBR, used at transmit time to cap skb size. */
 | 
						|
+static u32  bbr_tso_segs(struct sock *sk, unsigned int mss_now)
 | 
						|
+{
 | 
						|
+	return bbr_tso_segs_generic(sk, mss_now, sk->sk_gso_max_size);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Like bbr_tso_segs(), using mss_cache, ignoring driver's sk_gso_max_size. */
 | 
						|
 static u32 bbr_tso_segs_goal(struct sock *sk)
 | 
						|
 {
 | 
						|
 	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
-	u32 segs, bytes;
 | 
						|
-
 | 
						|
-	/* Sort of tcp_tso_autosize() but ignoring
 | 
						|
-	 * driver provided sk_gso_max_size.
 | 
						|
-	 */
 | 
						|
-	bytes = min_t(unsigned long,
 | 
						|
-		      sk->sk_pacing_rate >> READ_ONCE(sk->sk_pacing_shift),
 | 
						|
-		      GSO_LEGACY_MAX_SIZE - 1 - MAX_TCP_HEADER);
 | 
						|
-	segs = max_t(u32, bytes / tp->mss_cache, bbr_min_tso_segs(sk));
 | 
						|
 
 | 
						|
-	return min(segs, 0x7FU);
 | 
						|
+	return  bbr_tso_segs_generic(sk, tp->mss_cache, GSO_MAX_SIZE);
 | 
						|
 }
 | 
						|
 
 | 
						|
 /* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */
 | 
						|
@@ -1149,7 +1163,7 @@ static struct tcp_congestion_ops tcp_bbr_cong_ops __read_mostly = {
 | 
						|
 	.undo_cwnd	= bbr_undo_cwnd,
 | 
						|
 	.cwnd_event	= bbr_cwnd_event,
 | 
						|
 	.ssthresh	= bbr_ssthresh,
 | 
						|
-	.min_tso_segs	= bbr_min_tso_segs,
 | 
						|
+	.tso_segs	= bbr_tso_segs,
 | 
						|
 	.get_info	= bbr_get_info,
 | 
						|
 	.set_state	= bbr_set_state,
 | 
						|
 };
 | 
						|
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
 | 
						|
index 95816a1a5858..5284249f4689 100644
 | 
						|
--- a/net/ipv4/tcp_output.c
 | 
						|
+++ b/net/ipv4/tcp_output.c
 | 
						|
@@ -2002,13 +2002,12 @@ static u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
 | 
						|
 static u32 tcp_tso_segs(struct sock *sk, unsigned int mss_now)
 | 
						|
 {
 | 
						|
 	const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;
 | 
						|
-	u32 min_tso, tso_segs;
 | 
						|
+	u32 tso_segs;
 | 
						|
 
 | 
						|
-	min_tso = ca_ops->min_tso_segs ?
 | 
						|
-			ca_ops->min_tso_segs(sk) :
 | 
						|
-			READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs);
 | 
						|
-
 | 
						|
-	tso_segs = tcp_tso_autosize(sk, mss_now, min_tso);
 | 
						|
+	tso_segs = ca_ops->tso_segs ?
 | 
						|
+		ca_ops->tso_segs(sk, mss_now) :
 | 
						|
+		tcp_tso_autosize(sk, mss_now,
 | 
						|
+				 READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs));
 | 
						|
 	return min_t(u32, tso_segs, sk->sk_gso_max_segs);
 | 
						|
 }
 | 
						|
 
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 443e2f20e82a9f975fcb02d79f6f882006bc448c Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Sat, 16 Nov 2019 13:16:25 -0500
 | 
						|
Subject: [PATCH 13/27] net-tcp: add fast_ack_mode=1: skip rwin check in
 | 
						|
 tcp_fast_ack_mode__tcp_ack_snd_check()
 | 
						|
 | 
						|
Add logic for an experimental TCP connection behavior, enabled with
 | 
						|
tp->fast_ack_mode = 1, which disables checking the receive window
 | 
						|
before sending an ack in __tcp_ack_snd_check(). If this behavior is
 | 
						|
enabled, the data receiver sends an ACK if the amount of data is >
 | 
						|
RCV.MSS.
 | 
						|
 | 
						|
Change-Id: Iaa0a0fd7108221f883137a79d5bfa724f1b096d4
 | 
						|
---
 | 
						|
 include/linux/tcp.h  | 3 ++-
 | 
						|
 net/ipv4/tcp.c       | 1 +
 | 
						|
 net/ipv4/tcp_cong.c  | 1 +
 | 
						|
 net/ipv4/tcp_input.c | 5 +++--
 | 
						|
 4 files changed, 7 insertions(+), 3 deletions(-)
 | 
						|
 | 
						|
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
 | 
						|
index 41b1da621a45..d8f94ef1a297 100644
 | 
						|
--- a/include/linux/tcp.h
 | 
						|
+++ b/include/linux/tcp.h
 | 
						|
@@ -255,7 +255,8 @@ struct tcp_sock {
 | 
						|
 	u8	compressed_ack;
 | 
						|
 	u8	dup_ack_counter:2,
 | 
						|
 		tlp_retrans:1,	/* TLP is a retransmission */
 | 
						|
-		unused:5;
 | 
						|
+		fast_ack_mode:2, /* which fast ack mode ? */
 | 
						|
+		unused:3;
 | 
						|
 	u32	chrono_start;	/* Start time in jiffies of a TCP chrono */
 | 
						|
 	u32	chrono_stat[3];	/* Time in jiffies for chrono_stat stats */
 | 
						|
 	u8	chrono_type:2,	/* current chronograph type */
 | 
						|
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
 | 
						|
index 6667c3538f2a..34207ec358d8 100644
 | 
						|
--- a/net/ipv4/tcp.c
 | 
						|
+++ b/net/ipv4/tcp.c
 | 
						|
@@ -3190,6 +3190,7 @@ int tcp_disconnect(struct sock *sk, int flags)
 | 
						|
 	tp->rx_opt.dsack = 0;
 | 
						|
 	tp->rx_opt.num_sacks = 0;
 | 
						|
 	tp->rcv_ooopack = 0;
 | 
						|
+	tp->fast_ack_mode = 0;
 | 
						|
 
 | 
						|
 
 | 
						|
 	/* Clean up fastopen related fields */
 | 
						|
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
 | 
						|
index d3cae40749e8..0f268f2ff2e9 100644
 | 
						|
--- a/net/ipv4/tcp_cong.c
 | 
						|
+++ b/net/ipv4/tcp_cong.c
 | 
						|
@@ -189,6 +189,7 @@ void tcp_init_congestion_control(struct sock *sk)
 | 
						|
 	struct inet_connection_sock *icsk = inet_csk(sk);
 | 
						|
 
 | 
						|
 	tcp_sk(sk)->prior_ssthresh = 0;
 | 
						|
+	tcp_sk(sk)->fast_ack_mode = 0;
 | 
						|
 	if (icsk->icsk_ca_ops->init)
 | 
						|
 		icsk->icsk_ca_ops->init(sk);
 | 
						|
 	if (tcp_ca_needs_ecn(sk))
 | 
						|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
 | 
						|
index 82a68b768be4..8a455eb0c552 100644
 | 
						|
--- a/net/ipv4/tcp_input.c
 | 
						|
+++ b/net/ipv4/tcp_input.c
 | 
						|
@@ -5527,13 +5527,14 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
 | 
						|
 
 | 
						|
 	    /* More than one full frame received... */
 | 
						|
 	if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss &&
 | 
						|
+	     (tp->fast_ack_mode == 1 ||
 | 
						|
 	     /* ... and right edge of window advances far enough.
 | 
						|
 	      * (tcp_recvmsg() will send ACK otherwise).
 | 
						|
 	      * If application uses SO_RCVLOWAT, we want send ack now if
 | 
						|
 	      * we have not received enough bytes to satisfy the condition.
 | 
						|
 	      */
 | 
						|
-	    (tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat ||
 | 
						|
-	     __tcp_select_window(sk) >= tp->rcv_wnd)) ||
 | 
						|
+	      (tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat ||
 | 
						|
+	       __tcp_select_window(sk) >= tp->rcv_wnd))) ||
 | 
						|
 	    /* We ACK each frame or... */
 | 
						|
 	    tcp_in_quickack_mode(sk) ||
 | 
						|
 	    /* Protocol state mandates a one-time immediate ACK */
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 09264a22823a54e020bfdf0ae86fc3644958db16 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Tue, 11 Jun 2019 12:54:22 -0400
 | 
						|
Subject: [PATCH 14/27] net-tcp_bbr: v2: BBRv2 ("bbr2") congestion control for
 | 
						|
 Linux TCP
 | 
						|
 | 
						|
BBR v2 is an enhacement to the BBR v1 algorithm. It's designed to aim for lower
 | 
						|
queues, lower loss, and better Reno/CUBIC coexistence than BBR v1.
 | 
						|
 | 
						|
BBR v2 maintains the core of BBR v1: an explicit model of the network
 | 
						|
path that is two-dimensional, adapting to estimate the (a) maximum
 | 
						|
available bandwidth and (b) maximum safe volume of data a flow can
 | 
						|
keep in-flight in the network. It maintains the estimated BDP as a
 | 
						|
core guide for estimating an appropriate level of in-flight data.
 | 
						|
 | 
						|
BBR v2 makes several key enhancements:
 | 
						|
 | 
						|
o Its bandwidth-probing time scale is adapted, within bounds, to allow improved
 | 
						|
coexistence with Reno and CUBIC. The bandwidth-probing time scale is (a)
 | 
						|
extended dynamically based on estimated BDP to improve coexistence with
 | 
						|
Reno/CUBIC; (b) bounded by an interactive wall-clock time-scale to be more
 | 
						|
scalable and responsive than Reno and CUBIC.
 | 
						|
 | 
						|
o Rather than being largely agnostic to loss and ECN marks, it explicitly uses
 | 
						|
loss and (DCTCP-style) ECN signals to maintain its model.
 | 
						|
 | 
						|
o It aims for lower losses than v1 by adjusting its model to attempt to stay
 | 
						|
within loss rate and ECN mark rate bounds (loss_thresh and ecn_thresh,
 | 
						|
respectively).
 | 
						|
 | 
						|
o It adapts to loss/ECN signals even when the application is running out of
 | 
						|
data ("application-limited"), in case the "application-limited" flow is also
 | 
						|
"network-limited" (the bw and/or inflight available to this flow is lower than
 | 
						|
previously estimated when the flow ran out of data).
 | 
						|
 | 
						|
o It has a three-part model: the model explicit three tracks operating points,
 | 
						|
where an operating point is a tuple: (bandwidth, inflight). The three operating
 | 
						|
points are:
 | 
						|
 | 
						|
  o latest:        the latest measurement from the current round trip
 | 
						|
  o upper bound:   robust, optimistic, long-term upper bound
 | 
						|
  o lower bound:   robust, conservative, short-term lower bound
 | 
						|
 | 
						|
These are stored in the following state variables:
 | 
						|
 | 
						|
  o latest:  bw_latest, inflight_latest
 | 
						|
  o lo:      bw_lo,     inflight_lo
 | 
						|
  o hi:      bw_hi[2],  inflight_hi
 | 
						|
 | 
						|
To gain intuition about the meaning of the three operating points, it
 | 
						|
may help to consider the analogs in CUBIC, which has a somewhat
 | 
						|
analogous three-part model used by its probing state machine:
 | 
						|
 | 
						|
  BBR param     CUBIC param
 | 
						|
  -----------   -------------
 | 
						|
  latest     ~  cwnd
 | 
						|
  lo         ~  ssthresh
 | 
						|
  hi         ~  last_max_cwnd
 | 
						|
 | 
						|
The analogy is only a loose one, though, since the BBR operating
 | 
						|
points are calculated differently, and are 2-dimensional (bw,inflight)
 | 
						|
rather than CUBIC's one-dimensional notion of operating point
 | 
						|
(inflight).
 | 
						|
 | 
						|
o It uses the three-part model to adapt the magnitude of its bandwidth
 | 
						|
to match the estimated space available in the buffer, rather than (as
 | 
						|
in BBR v1) assuming that it was always acceptable to place 0.25*BDP in
 | 
						|
the bottleneck buffer when probing (commodity datacenter switches
 | 
						|
commonly do not have that much buffer for WAN flows). When BBR v2
 | 
						|
estimates it hit a buffer limit during probing, its bandwidth probing
 | 
						|
then starts gently in case little space is still available in the
 | 
						|
buffer, and the accelerates, slowly at first and then rapidly if it
 | 
						|
can grow inflight without seeing congestion signals. In such cases,
 | 
						|
probing is bounded by inflight_hi + inflight_probe, where
 | 
						|
inflight_probe grows as: [0, 1, 2, 4, 8, 16,...]. This allows BBR to
 | 
						|
keep losses low and bounded if a bottleneck remains congested, while
 | 
						|
rapidly/scalably utilizing free bandwidth when it becomes available.
 | 
						|
 | 
						|
o It has a slightly revised state machine, to achieve the goals above.
 | 
						|
    BBR_BW_PROBE_UP:    pushes up inflight to probe for bw/vol
 | 
						|
    BBR_BW_PROBE_DOWN:  drain excess inflight from the queue
 | 
						|
    BBR_BW_PROBE_CRUISE: use pipe, w/ headroom in queue/pipe
 | 
						|
    BBR_BW_PROBE_REFILL: try refill the pipe again to 100%, leaving queue empty
 | 
						|
 | 
						|
o The estimated BDP: BBR v2 continues to maintain an estimate of the
 | 
						|
path's two-way propagation delay, by tracking a windowed min_rtt, and
 | 
						|
coordinating (on an as-ndeeded basis) to try to expose the two-way
 | 
						|
propagation delay by draining the bottleneck queue.
 | 
						|
 | 
						|
BBR v2 continues to use its min_rtt and (currently-applicable) bandwidth
 | 
						|
estimate to estimate the current bandwidth-delay product. The estimated BDP
 | 
						|
still provides one important guideline for bounding inflight data. However,
 | 
						|
because any min-filtered RTT and max-filtered bw inherently tend to both
 | 
						|
overestimate, the estimated BDP is often too high; in this case loss or ECN
 | 
						|
marks can ensue, in which case BBR v2 adjusts inflight_hi and inflight_lo to
 | 
						|
adapt its sending rate and inflight down to match the available capacity of the
 | 
						|
path.
 | 
						|
 | 
						|
o Space: Note that ICSK_CA_PRIV_SIZE increased. This is because BBR v2
 | 
						|
requires more space. Note that much of the space is due to support for
 | 
						|
per-socket parameterization and debugging in this release for research
 | 
						|
and debugging. With that state removed, the full "struct bbr" is 140
 | 
						|
bytes, or 144 with padding. This is an increase of 40 bytes over the
 | 
						|
existing ca_priv space.
 | 
						|
 | 
						|
o Code: BBR v2 reuses many pieces from BBR v1. But it omits the following
 | 
						|
  significant pieces:
 | 
						|
 | 
						|
  o "packet conservation" (bbr_set_cwnd_to_recover_or_restore(),
 | 
						|
    bbr_can_grow_inflight())
 | 
						|
  o long-term bandwidth estimator ("policer mode")
 | 
						|
 | 
						|
  The code layout tries to keep BBR v2 code near the bottom of the
 | 
						|
  file, so that v1-applicable code in the top does not accidentally
 | 
						|
  refer to v2 code.
 | 
						|
 | 
						|
o Docs:
 | 
						|
  See the following docs for more details and diagrams decsribing the BBR v2
 | 
						|
  algorithm:
 | 
						|
    https://datatracker.ietf.org/meeting/104/materials/slides-104-iccrg-an-update-on-bbr-00
 | 
						|
    https://datatracker.ietf.org/meeting/102/materials/slides-102-iccrg-an-update-on-bbr-work-at-google-00
 | 
						|
 | 
						|
o Internal notes:
 | 
						|
  For this upstream rebase, Neal started from:
 | 
						|
    git show fed518041ac6:net/ipv4/tcp_bbr.c > net/ipv4/tcp_bbr.c
 | 
						|
  then removed dev instrumentation (dynamic get/set for parameters)
 | 
						|
  and code that was only used by BBRv1
 | 
						|
 | 
						|
Effort: net-tcp_bbr
 | 
						|
Origin-9xx-SHA1: 2c84098e60bed6d67dde23cd7538c51dee273102
 | 
						|
Change-Id: I125cf26ba2a7a686f2fa5e87f4c2afceb65f7a05
 | 
						|
---
 | 
						|
 include/net/inet_connection_sock.h |    5 +-
 | 
						|
 include/uapi/linux/inet_diag.h     |   33 +
 | 
						|
 net/ipv4/Kconfig                   |   22 +
 | 
						|
 net/ipv4/Makefile                  |    1 +
 | 
						|
 net/ipv4/tcp_bbr2.c                | 2683 ++++++++++++++++++++++++++++
 | 
						|
 5 files changed, 2742 insertions(+), 2 deletions(-)
 | 
						|
 create mode 100644 net/ipv4/tcp_bbr2.c
 | 
						|
 | 
						|
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
 | 
						|
index c2b15f7e5516..1387e67a017f 100644
 | 
						|
--- a/include/net/inet_connection_sock.h
 | 
						|
+++ b/include/net/inet_connection_sock.h
 | 
						|
@@ -135,8 +135,9 @@ struct inet_connection_sock {
 | 
						|
 	u32			  icsk_probes_tstamp;
 | 
						|
 	u32			  icsk_user_timeout;
 | 
						|
 
 | 
						|
-	u64			  icsk_ca_priv[104 / sizeof(u64)];
 | 
						|
-#define ICSK_CA_PRIV_SIZE	  sizeof_field(struct inet_connection_sock, icsk_ca_priv)
 | 
						|
+/* XXX inflated by temporary internal debugging info */
 | 
						|
+#define ICSK_CA_PRIV_SIZE      (216)
 | 
						|
+	u64			  icsk_ca_priv[ICSK_CA_PRIV_SIZE / sizeof(u64)];
 | 
						|
 };
 | 
						|
 
 | 
						|
 #define ICSK_TIME_RETRANS	1	/* Retransmit timer */
 | 
						|
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
 | 
						|
index 50655de04c9b..0e24f11627d5 100644
 | 
						|
--- a/include/uapi/linux/inet_diag.h
 | 
						|
+++ b/include/uapi/linux/inet_diag.h
 | 
						|
@@ -231,9 +231,42 @@ struct tcp_bbr_info {
 | 
						|
 	__u32	bbr_cwnd_gain;		/* cwnd gain shifted left 8 bits */
 | 
						|
 };
 | 
						|
 
 | 
						|
+/* Phase as reported in netlink/ss stats. */
 | 
						|
+enum tcp_bbr2_phase {
 | 
						|
+	BBR2_PHASE_INVALID		= 0,
 | 
						|
+	BBR2_PHASE_STARTUP		= 1,
 | 
						|
+	BBR2_PHASE_DRAIN		= 2,
 | 
						|
+	BBR2_PHASE_PROBE_RTT		= 3,
 | 
						|
+	BBR2_PHASE_PROBE_BW_UP		= 4,
 | 
						|
+	BBR2_PHASE_PROBE_BW_DOWN	= 5,
 | 
						|
+	BBR2_PHASE_PROBE_BW_CRUISE	= 6,
 | 
						|
+	BBR2_PHASE_PROBE_BW_REFILL	= 7
 | 
						|
+};
 | 
						|
+
 | 
						|
+struct tcp_bbr2_info {
 | 
						|
+	/* u64 bw: bandwidth (app throughput) estimate in Byte per sec: */
 | 
						|
+	__u32	bbr_bw_lsb;		/* lower 32 bits of bw */
 | 
						|
+	__u32	bbr_bw_msb;		/* upper 32 bits of bw */
 | 
						|
+	__u32	bbr_min_rtt;		/* min-filtered RTT in uSec */
 | 
						|
+	__u32	bbr_pacing_gain;	/* pacing gain shifted left 8 bits */
 | 
						|
+	__u32	bbr_cwnd_gain;		/* cwnd gain shifted left 8 bits */
 | 
						|
+	__u32	bbr_bw_hi_lsb;		/* lower 32 bits of bw_hi */
 | 
						|
+	__u32	bbr_bw_hi_msb;		/* upper 32 bits of bw_hi */
 | 
						|
+	__u32	bbr_bw_lo_lsb;		/* lower 32 bits of bw_lo */
 | 
						|
+	__u32	bbr_bw_lo_msb;		/* upper 32 bits of bw_lo */
 | 
						|
+	__u8	bbr_mode;		/* current bbr_mode in state machine */
 | 
						|
+	__u8	bbr_phase;		/* current state machine phase */
 | 
						|
+	__u8	unused1;		/* alignment padding; not used yet */
 | 
						|
+	__u8	bbr_version;		/* MUST be at this offset in struct */
 | 
						|
+	__u32	bbr_inflight_lo;	/* lower/short-term data volume bound */
 | 
						|
+	__u32	bbr_inflight_hi;	/* higher/long-term data volume bound */
 | 
						|
+	__u32	bbr_extra_acked;	/* max excess packets ACKed in epoch */
 | 
						|
+};
 | 
						|
+
 | 
						|
 union tcp_cc_info {
 | 
						|
 	struct tcpvegas_info	vegas;
 | 
						|
 	struct tcp_dctcp_info	dctcp;
 | 
						|
 	struct tcp_bbr_info	bbr;
 | 
						|
+	struct tcp_bbr2_info	bbr2;
 | 
						|
 };
 | 
						|
 #endif /* _UAPI_INET_DIAG_H_ */
 | 
						|
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
 | 
						|
index 2dfb12230f08..b6bec331a82e 100644
 | 
						|
--- a/net/ipv4/Kconfig
 | 
						|
+++ b/net/ipv4/Kconfig
 | 
						|
@@ -678,6 +678,24 @@ config TCP_CONG_BBR
 | 
						|
 	  AQM schemes that do not provide a delay signal. It requires the fq
 | 
						|
 	  ("Fair Queue") pacing packet scheduler.
 | 
						|
 
 | 
						|
+config TCP_CONG_BBR2
 | 
						|
+	tristate "BBR2 TCP"
 | 
						|
+	default n
 | 
						|
+	help
 | 
						|
+
 | 
						|
+	BBR2 TCP congestion control is a model-based congestion control
 | 
						|
+	algorithm that aims to maximize network utilization, keep queues and
 | 
						|
+	retransmit rates low, and to be able to coexist with Reno/CUBIC in
 | 
						|
+	common scenarios. It builds an explicit model of the network path.  It
 | 
						|
+	tolerates a targeted degree of random packet loss and delay that are
 | 
						|
+	unrelated to congestion. It can operate over LAN, WAN, cellular, wifi,
 | 
						|
+	or cable modem links, and can use DCTCP-L4S-style ECN signals.  It can
 | 
						|
+	coexist with flows that use loss-based congestion control, and can
 | 
						|
+	operate with shallow buffers, deep buffers, bufferbloat, policers, or
 | 
						|
+	AQM schemes that do not provide a delay signal. It requires pacing,
 | 
						|
+	using either TCP internal pacing or the fq ("Fair Queue") pacing packet
 | 
						|
+	scheduler.
 | 
						|
+
 | 
						|
 choice
 | 
						|
 	prompt "Default TCP congestion control"
 | 
						|
 	default DEFAULT_CUBIC
 | 
						|
@@ -715,6 +733,9 @@ choice
 | 
						|
 	config DEFAULT_BBR
 | 
						|
 		bool "BBR" if TCP_CONG_BBR=y
 | 
						|
 
 | 
						|
+	config DEFAULT_BBR2
 | 
						|
+		bool "BBR2" if TCP_CONG_BBR2=y
 | 
						|
+
 | 
						|
 	config DEFAULT_RENO
 | 
						|
 		bool "Reno"
 | 
						|
 endchoice
 | 
						|
@@ -739,6 +760,7 @@ config DEFAULT_TCP_CONG
 | 
						|
 	default "dctcp" if DEFAULT_DCTCP
 | 
						|
 	default "cdg" if DEFAULT_CDG
 | 
						|
 	default "bbr" if DEFAULT_BBR
 | 
						|
+	default "bbr2" if DEFAULT_BBR2
 | 
						|
 	default "cubic"
 | 
						|
 
 | 
						|
 config TCP_MD5SIG
 | 
						|
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
 | 
						|
index bbdd9c44f14e..8dee1547d820 100644
 | 
						|
--- a/net/ipv4/Makefile
 | 
						|
+++ b/net/ipv4/Makefile
 | 
						|
@@ -46,6 +46,7 @@ obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
 | 
						|
 obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o
 | 
						|
 obj-$(CONFIG_INET_RAW_DIAG) += raw_diag.o
 | 
						|
 obj-$(CONFIG_TCP_CONG_BBR) += tcp_bbr.o
 | 
						|
+obj-$(CONFIG_TCP_CONG_BBR2) += tcp_bbr2.o
 | 
						|
 obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
 | 
						|
 obj-$(CONFIG_TCP_CONG_CDG) += tcp_cdg.o
 | 
						|
 obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o
 | 
						|
diff --git a/net/ipv4/tcp_bbr2.c b/net/ipv4/tcp_bbr2.c
 | 
						|
new file mode 100644
 | 
						|
index 000000000000..a6959b70e51d
 | 
						|
--- /dev/null
 | 
						|
+++ b/net/ipv4/tcp_bbr2.c
 | 
						|
@@ -0,0 +1,2686 @@
 | 
						|
+/* BBR (Bottleneck Bandwidth and RTT) congestion control, v2
 | 
						|
+ *
 | 
						|
+ * BBRv2 is a model-based congestion control algorithm that aims for low
 | 
						|
+ * queues, low loss, and (bounded) Reno/CUBIC coexistence. To maintain a model
 | 
						|
+ * of the network path, it uses measurements of bandwidth and RTT, as well as
 | 
						|
+ * (if they occur) packet loss and/or DCTCP/L4S-style ECN signals.  Note that
 | 
						|
+ * although it can use ECN or loss signals explicitly, it does not require
 | 
						|
+ * either; it can bound its in-flight data based on its estimate of the BDP.
 | 
						|
+ *
 | 
						|
+ * The model has both higher and lower bounds for the operating range:
 | 
						|
+ *   lo: bw_lo, inflight_lo: conservative short-term lower bound
 | 
						|
+ *   hi: bw_hi, inflight_hi: robust long-term upper bound
 | 
						|
+ * The bandwidth-probing time scale is (a) extended dynamically based on
 | 
						|
+ * estimated BDP to improve coexistence with Reno/CUBIC; (b) bounded by
 | 
						|
+ * an interactive wall-clock time-scale to be more scalable and responsive
 | 
						|
+ * than Reno and CUBIC.
 | 
						|
+ *
 | 
						|
+ * Here is a state transition diagram for BBR:
 | 
						|
+ *
 | 
						|
+ *             |
 | 
						|
+ *             V
 | 
						|
+ *    +---> STARTUP  ----+
 | 
						|
+ *    |        |         |
 | 
						|
+ *    |        V         |
 | 
						|
+ *    |      DRAIN   ----+
 | 
						|
+ *    |        |         |
 | 
						|
+ *    |        V         |
 | 
						|
+ *    +---> PROBE_BW ----+
 | 
						|
+ *    |      ^    |      |
 | 
						|
+ *    |      |    |      |
 | 
						|
+ *    |      +----+      |
 | 
						|
+ *    |                  |
 | 
						|
+ *    +---- PROBE_RTT <--+
 | 
						|
+ *
 | 
						|
+ * A BBR flow starts in STARTUP, and ramps up its sending rate quickly.
 | 
						|
+ * When it estimates the pipe is full, it enters DRAIN to drain the queue.
 | 
						|
+ * In steady state a BBR flow only uses PROBE_BW and PROBE_RTT.
 | 
						|
+ * A long-lived BBR flow spends the vast majority of its time remaining
 | 
						|
+ * (repeatedly) in PROBE_BW, fully probing and utilizing the pipe's bandwidth
 | 
						|
+ * in a fair manner, with a small, bounded queue. *If* a flow has been
 | 
						|
+ * continuously sending for the entire min_rtt window, and hasn't seen an RTT
 | 
						|
+ * sample that matches or decreases its min_rtt estimate for 10 seconds, then
 | 
						|
+ * it briefly enters PROBE_RTT to cut inflight to a minimum value to re-probe
 | 
						|
+ * the path's two-way propagation delay (min_rtt). When exiting PROBE_RTT, if
 | 
						|
+ * we estimated that we reached the full bw of the pipe then we enter PROBE_BW;
 | 
						|
+ * otherwise we enter STARTUP to try to fill the pipe.
 | 
						|
+ *
 | 
						|
+ * BBR is described in detail in:
 | 
						|
+ *   "BBR: Congestion-Based Congestion Control",
 | 
						|
+ *   Neal Cardwell, Yuchung Cheng, C. Stephen Gunn, Soheil Hassas Yeganeh,
 | 
						|
+ *   Van Jacobson. ACM Queue, Vol. 14 No. 5, September-October 2016.
 | 
						|
+ *
 | 
						|
+ * There is a public e-mail list for discussing BBR development and testing:
 | 
						|
+ *   https://groups.google.com/forum/#!forum/bbr-dev
 | 
						|
+ *
 | 
						|
+ * NOTE: BBR might be used with the fq qdisc ("man tc-fq") with pacing enabled,
 | 
						|
+ * otherwise TCP stack falls back to an internal pacing using one high
 | 
						|
+ * resolution timer per TCP socket and may use more resources.
 | 
						|
+ */
 | 
						|
+#include <linux/module.h>
 | 
						|
+#include <net/tcp.h>
 | 
						|
+#include <linux/inet_diag.h>
 | 
						|
+#include <linux/inet.h>
 | 
						|
+#include <linux/random.h>
 | 
						|
+
 | 
						|
+#include "tcp_dctcp.h"
 | 
						|
+
 | 
						|
+/* Scale factor for rate in pkt/uSec unit to avoid truncation in bandwidth
 | 
						|
+ * estimation. The rate unit ~= (1500 bytes / 1 usec / 2^24) ~= 715 bps.
 | 
						|
+ * This handles bandwidths from 0.06pps (715bps) to 256Mpps (3Tbps) in a u32.
 | 
						|
+ * Since the minimum window is >=4 packets, the lower bound isn't
 | 
						|
+ * an issue. The upper bound isn't an issue with existing technologies.
 | 
						|
+ */
 | 
						|
+#define BW_SCALE 24
 | 
						|
+#define BW_UNIT (1 << BW_SCALE)
 | 
						|
+
 | 
						|
+#define BBR_SCALE 8	/* scaling factor for fractions in BBR (e.g. gains) */
 | 
						|
+#define BBR_UNIT (1 << BBR_SCALE)
 | 
						|
+
 | 
						|
+#define FLAG_DEBUG_VERBOSE	0x1	/* Verbose debugging messages */
 | 
						|
+#define FLAG_DEBUG_LOOPBACK	0x2	/* Do NOT skip loopback addr */
 | 
						|
+
 | 
						|
+#define CYCLE_LEN		8	/* number of phases in a pacing gain cycle */
 | 
						|
+
 | 
						|
+/* BBR has the following modes for deciding how fast to send: */
 | 
						|
+enum bbr_mode {
 | 
						|
+	BBR_STARTUP,	/* ramp up sending rate rapidly to fill pipe */
 | 
						|
+	BBR_DRAIN,	/* drain any queue created during startup */
 | 
						|
+	BBR_PROBE_BW,	/* discover, share bw: pace around estimated bw */
 | 
						|
+	BBR_PROBE_RTT,	/* cut inflight to min to probe min_rtt */
 | 
						|
+};
 | 
						|
+
 | 
						|
+/* How does the incoming ACK stream relate to our bandwidth probing? */
 | 
						|
+enum bbr_ack_phase {
 | 
						|
+	BBR_ACKS_INIT,		  /* not probing; not getting probe feedback */
 | 
						|
+	BBR_ACKS_REFILLING,	  /* sending at est. bw to fill pipe */
 | 
						|
+	BBR_ACKS_PROBE_STARTING,  /* inflight rising to probe bw */
 | 
						|
+	BBR_ACKS_PROBE_FEEDBACK,  /* getting feedback from bw probing */
 | 
						|
+	BBR_ACKS_PROBE_STOPPING,  /* stopped probing; still getting feedback */
 | 
						|
+};
 | 
						|
+
 | 
						|
+/* BBR congestion control block */
 | 
						|
+struct bbr {
 | 
						|
+	u32	min_rtt_us;	        /* min RTT in min_rtt_win_sec window */
 | 
						|
+	u32	min_rtt_stamp;	        /* timestamp of min_rtt_us */
 | 
						|
+	u32	probe_rtt_done_stamp;   /* end time for BBR_PROBE_RTT mode */
 | 
						|
+	u32	probe_rtt_min_us;	/* min RTT in bbr_probe_rtt_win_ms window */
 | 
						|
+	u32	probe_rtt_min_stamp;	/* timestamp of probe_rtt_min_us*/
 | 
						|
+	u32     next_rtt_delivered; /* scb->tx.delivered at end of round */
 | 
						|
+	u32	prior_rcv_nxt;	/* tp->rcv_nxt when CE state last changed */
 | 
						|
+	u64	cycle_mstamp;	     /* time of this cycle phase start */
 | 
						|
+	u32     mode:3,		     /* current bbr_mode in state machine */
 | 
						|
+		prev_ca_state:3,     /* CA state on previous ACK */
 | 
						|
+		packet_conservation:1,  /* use packet conservation? */
 | 
						|
+		round_start:1,	     /* start of packet-timed tx->ack round? */
 | 
						|
+		ce_state:1,          /* If most recent data has CE bit set */
 | 
						|
+		bw_probe_up_rounds:5,   /* cwnd-limited rounds in PROBE_UP */
 | 
						|
+		try_fast_path:1, 	/* can we take fast path? */
 | 
						|
+		unused2:11,
 | 
						|
+		idle_restart:1,	     /* restarting after idle? */
 | 
						|
+		probe_rtt_round_done:1,  /* a BBR_PROBE_RTT round at 4 pkts? */
 | 
						|
+		cycle_idx:3,	/* current index in pacing_gain cycle array */
 | 
						|
+		has_seen_rtt:1;	     /* have we seen an RTT sample yet? */
 | 
						|
+	u32	pacing_gain:11,	/* current gain for setting pacing rate */
 | 
						|
+		cwnd_gain:11,	/* current gain for setting cwnd */
 | 
						|
+		full_bw_reached:1,   /* reached full bw in Startup? */
 | 
						|
+		full_bw_cnt:2,	/* number of rounds without large bw gains */
 | 
						|
+		init_cwnd:7;	/* initial cwnd */
 | 
						|
+	u32	prior_cwnd;	/* prior cwnd upon entering loss recovery */
 | 
						|
+	u32	full_bw;	/* recent bw, to estimate if pipe is full */
 | 
						|
+
 | 
						|
+	/* For tracking ACK aggregation: */
 | 
						|
+	u64	ack_epoch_mstamp;	/* start of ACK sampling epoch */
 | 
						|
+	u16	extra_acked[2];		/* max excess data ACKed in epoch */
 | 
						|
+	u32	ack_epoch_acked:20,	/* packets (S)ACKed in sampling epoch */
 | 
						|
+		extra_acked_win_rtts:5,	/* age of extra_acked, in round trips */
 | 
						|
+		extra_acked_win_idx:1,	/* current index in extra_acked array */
 | 
						|
+	/* BBR v2 state: */
 | 
						|
+		unused1:2,
 | 
						|
+		startup_ecn_rounds:2,	/* consecutive hi ECN STARTUP rounds */
 | 
						|
+		loss_in_cycle:1,	/* packet loss in this cycle? */
 | 
						|
+		ecn_in_cycle:1;		/* ECN in this cycle? */
 | 
						|
+	u32	loss_round_delivered; /* scb->tx.delivered ending loss round */
 | 
						|
+	u32	undo_bw_lo;	     /* bw_lo before latest losses */
 | 
						|
+	u32	undo_inflight_lo;    /* inflight_lo before latest losses */
 | 
						|
+	u32	undo_inflight_hi;    /* inflight_hi before latest losses */
 | 
						|
+	u32	bw_latest;	 /* max delivered bw in last round trip */
 | 
						|
+	u32	bw_lo;		 /* lower bound on sending bandwidth */
 | 
						|
+	u32	bw_hi[2];	 /* upper bound of sending bandwidth range*/
 | 
						|
+	u32	inflight_latest; /* max delivered data in last round trip */
 | 
						|
+	u32	inflight_lo;	 /* lower bound of inflight data range */
 | 
						|
+	u32	inflight_hi;	 /* upper bound of inflight data range */
 | 
						|
+	u32	bw_probe_up_cnt; /* packets delivered per inflight_hi incr */
 | 
						|
+	u32	bw_probe_up_acks;  /* packets (S)ACKed since inflight_hi incr */
 | 
						|
+	u32	probe_wait_us;	 /* PROBE_DOWN until next clock-driven probe */
 | 
						|
+	u32	ecn_eligible:1,	/* sender can use ECN (RTT, handshake)? */
 | 
						|
+		ecn_alpha:9,	/* EWMA delivered_ce/delivered; 0..256 */
 | 
						|
+		bw_probe_samples:1,    /* rate samples reflect bw probing? */
 | 
						|
+		prev_probe_too_high:1, /* did last PROBE_UP go too high? */
 | 
						|
+		stopped_risky_probe:1, /* last PROBE_UP stopped due to risk? */
 | 
						|
+		rounds_since_probe:8,  /* packet-timed rounds since probed bw */
 | 
						|
+		loss_round_start:1,    /* loss_round_delivered round trip? */
 | 
						|
+		loss_in_round:1,       /* loss marked in this round trip? */
 | 
						|
+		ecn_in_round:1,	       /* ECN marked in this round trip? */
 | 
						|
+		ack_phase:3,	       /* bbr_ack_phase: meaning of ACKs */
 | 
						|
+		loss_events_in_round:4,/* losses in STARTUP round */
 | 
						|
+		initialized:1;	       /* has bbr_init() been called? */
 | 
						|
+	u32	alpha_last_delivered;	 /* tp->delivered    at alpha update */
 | 
						|
+	u32	alpha_last_delivered_ce; /* tp->delivered_ce at alpha update */
 | 
						|
+
 | 
						|
+	/* Params configurable using setsockopt. Refer to correspoding
 | 
						|
+	 * module param for detailed description of params.
 | 
						|
+	 */
 | 
						|
+	struct bbr_params {
 | 
						|
+		u32	high_gain:11,		/* max allowed value: 2047 */
 | 
						|
+			drain_gain:10,		/* max allowed value: 1023 */
 | 
						|
+			cwnd_gain:11;		/* max allowed value: 2047 */
 | 
						|
+		u32	cwnd_min_target:4,	/* max allowed value: 15 */
 | 
						|
+			min_rtt_win_sec:5,	/* max allowed value: 31 */
 | 
						|
+			probe_rtt_mode_ms:9,	/* max allowed value: 511 */
 | 
						|
+			full_bw_cnt:3,		/* max allowed value: 7 */
 | 
						|
+			bw_rtts:5,		/* max allowed value: 31 */
 | 
						|
+			cwnd_tso_budget:1,	/* allowed values: {0, 1} */
 | 
						|
+			unused3:1,
 | 
						|
+			drain_to_target:1,	/* boolean */
 | 
						|
+			precise_ece_ack:1,	/* boolean */
 | 
						|
+			extra_acked_in_startup:1, /* allowed values: {0, 1} */
 | 
						|
+			fast_path:1;		/* boolean */
 | 
						|
+		u32	full_bw_thresh:10,	/* max allowed value: 1023 */
 | 
						|
+			startup_cwnd_gain:11,	/* max allowed value: 2047 */
 | 
						|
+			bw_probe_pif_gain:9,	/* max allowed value: 511 */
 | 
						|
+			usage_based_cwnd:1, 	/* boolean */
 | 
						|
+			unused2:1;
 | 
						|
+		u16	probe_rtt_win_ms:14,	/* max allowed value: 16383 */
 | 
						|
+			refill_add_inc:2;	/* max allowed value: 3 */
 | 
						|
+		u16	extra_acked_gain:11,	/* max allowed value: 2047 */
 | 
						|
+			extra_acked_win_rtts:5; /* max allowed value: 31*/
 | 
						|
+		u16	pacing_gain[CYCLE_LEN]; /* max allowed value: 1023 */
 | 
						|
+		/* Mostly BBR v2 parameters below here: */
 | 
						|
+		u32	ecn_alpha_gain:8,	/* max allowed value: 255 */
 | 
						|
+			ecn_factor:8,		/* max allowed value: 255 */
 | 
						|
+			ecn_thresh:8,		/* max allowed value: 255 */
 | 
						|
+			beta:8;			/* max allowed value: 255 */
 | 
						|
+		u32	ecn_max_rtt_us:19,	/* max allowed value: 524287 */
 | 
						|
+			bw_probe_reno_gain:9,	/* max allowed value: 511 */
 | 
						|
+			full_loss_cnt:4;	/* max allowed value: 15 */
 | 
						|
+		u32	probe_rtt_cwnd_gain:8,	/* max allowed value: 255 */
 | 
						|
+			inflight_headroom:8,	/* max allowed value: 255 */
 | 
						|
+			loss_thresh:8,		/* max allowed value: 255 */
 | 
						|
+			bw_probe_max_rounds:8;	/* max allowed value: 255 */
 | 
						|
+		u32	bw_probe_rand_rounds:4, /* max allowed value: 15 */
 | 
						|
+			bw_probe_base_us:26,	/* usecs: 0..2^26-1 (67 secs) */
 | 
						|
+			full_ecn_cnt:2;		/* max allowed value: 3 */
 | 
						|
+		u32	bw_probe_rand_us:26,	/* usecs: 0..2^26-1 (67 secs) */
 | 
						|
+			undo:1,			/* boolean */
 | 
						|
+			tso_rtt_shift:4,	/* max allowed value: 15 */
 | 
						|
+			unused5:1;
 | 
						|
+		u32	ecn_reprobe_gain:9,	/* max allowed value: 511 */
 | 
						|
+			unused1:14,
 | 
						|
+			ecn_alpha_init:9;	/* max allowed value: 256 */
 | 
						|
+	} params;
 | 
						|
+
 | 
						|
+	struct {
 | 
						|
+		u32	snd_isn; /* Initial sequence number */
 | 
						|
+		u32	rs_bw; 	 /* last valid rate sample bw */
 | 
						|
+		u32	target_cwnd; /* target cwnd, based on BDP */
 | 
						|
+		u8	undo:1,  /* Undo even happened but not yet logged */
 | 
						|
+			unused:7;
 | 
						|
+		char	event;	 /* single-letter event debug codes */
 | 
						|
+		u16	unused2;
 | 
						|
+	} debug;
 | 
						|
+};
 | 
						|
+
 | 
						|
+struct bbr_context {
 | 
						|
+	u32 sample_bw;
 | 
						|
+	u32 target_cwnd;
 | 
						|
+	u32 log:1;
 | 
						|
+};
 | 
						|
+
 | 
						|
+/* Window length of bw filter (in rounds). Max allowed value is 31 (0x1F) */
 | 
						|
+static int bbr_bw_rtts = CYCLE_LEN + 2;
 | 
						|
+/* Window length of min_rtt filter (in sec). Max allowed value is 31 (0x1F) */
 | 
						|
+static u32 bbr_min_rtt_win_sec = 10;
 | 
						|
+/* Minimum time (in ms) spent at bbr_cwnd_min_target in BBR_PROBE_RTT mode.
 | 
						|
+ * Max allowed value is 511 (0x1FF).
 | 
						|
+ */
 | 
						|
+static u32 bbr_probe_rtt_mode_ms = 200;
 | 
						|
+/* Window length of probe_rtt_min_us filter (in ms), and consequently the
 | 
						|
+ * typical interval between PROBE_RTT mode entries.
 | 
						|
+ * Note that bbr_probe_rtt_win_ms must be <= bbr_min_rtt_win_sec * MSEC_PER_SEC
 | 
						|
+ */
 | 
						|
+static u32 bbr_probe_rtt_win_ms = 5000;
 | 
						|
+/* Skip TSO below the following bandwidth (bits/sec): */
 | 
						|
+static int bbr_min_tso_rate = 1200000;
 | 
						|
+
 | 
						|
+/* Use min_rtt to help adapt TSO burst size, with smaller min_rtt resulting
 | 
						|
+ * in bigger TSO bursts. By default we cut the RTT-based allowance in half
 | 
						|
+ * for every 2^9 usec (aka 512 us) of RTT, so that the RTT-based allowance
 | 
						|
+ * is below 1500 bytes after 6 * ~500 usec = 3ms.
 | 
						|
+ */
 | 
						|
+static u32 bbr_tso_rtt_shift = 9;  /* halve allowance per 2^9 usecs, 512us */
 | 
						|
+
 | 
						|
+/* Select cwnd TSO budget approach:
 | 
						|
+ *  0: padding
 | 
						|
+ *  1: flooring
 | 
						|
+ */
 | 
						|
+static uint bbr_cwnd_tso_budget = 1;
 | 
						|
+
 | 
						|
+/* Pace at ~1% below estimated bw, on average, to reduce queue at bottleneck.
 | 
						|
+ * In order to help drive the network toward lower queues and low latency while
 | 
						|
+ * maintaining high utilization, the average pacing rate aims to be slightly
 | 
						|
+ * lower than the estimated bandwidth. This is an important aspect of the
 | 
						|
+ * design.
 | 
						|
+ */
 | 
						|
+static const int bbr_pacing_margin_percent = 1;
 | 
						|
+
 | 
						|
+/* We use a high_gain value of 2/ln(2) because it's the smallest pacing gain
 | 
						|
+ * that will allow a smoothly increasing pacing rate that will double each RTT
 | 
						|
+ * and send the same number of packets per RTT that an un-paced, slow-starting
 | 
						|
+ * Reno or CUBIC flow would. Max allowed value is 2047 (0x7FF).
 | 
						|
+ */
 | 
						|
+static int bbr_high_gain  = BBR_UNIT * 2885 / 1000 + 1;
 | 
						|
+/* The gain for deriving startup cwnd. Max allowed value is 2047 (0x7FF). */
 | 
						|
+static int bbr_startup_cwnd_gain  = BBR_UNIT * 2885 / 1000 + 1;
 | 
						|
+/* The pacing gain of 1/high_gain in BBR_DRAIN is calculated to typically drain
 | 
						|
+ * the queue created in BBR_STARTUP in a single round. Max allowed value
 | 
						|
+ * is 1023 (0x3FF).
 | 
						|
+ */
 | 
						|
+static int bbr_drain_gain = BBR_UNIT * 1000 / 2885;
 | 
						|
+/* The gain for deriving steady-state cwnd tolerates delayed/stretched ACKs.
 | 
						|
+ * Max allowed value is 2047 (0x7FF).
 | 
						|
+ */
 | 
						|
+static int bbr_cwnd_gain  = BBR_UNIT * 2;
 | 
						|
+/* The pacing_gain values for the PROBE_BW gain cycle, to discover/share bw.
 | 
						|
+ * Max allowed value for each element is 1023 (0x3FF).
 | 
						|
+ */
 | 
						|
+enum bbr_pacing_gain_phase {
 | 
						|
+	BBR_BW_PROBE_UP		= 0,  /* push up inflight to probe for bw/vol */
 | 
						|
+	BBR_BW_PROBE_DOWN	= 1,  /* drain excess inflight from the queue */
 | 
						|
+	BBR_BW_PROBE_CRUISE	= 2,  /* use pipe, w/ headroom in queue/pipe */
 | 
						|
+	BBR_BW_PROBE_REFILL	= 3,  /* v2: refill the pipe again to 100% */
 | 
						|
+};
 | 
						|
+static int bbr_pacing_gain[] = {
 | 
						|
+	BBR_UNIT * 5 / 4,	/* probe for more available bw */
 | 
						|
+	BBR_UNIT * 3 / 4,	/* drain queue and/or yield bw to other flows */
 | 
						|
+	BBR_UNIT, BBR_UNIT, BBR_UNIT,	/* cruise at 1.0*bw to utilize pipe, */
 | 
						|
+	BBR_UNIT, BBR_UNIT, BBR_UNIT	/* without creating excess queue... */
 | 
						|
+};
 | 
						|
+/* Randomize the starting gain cycling phase over N phases: */
 | 
						|
+static u32 bbr_cycle_rand = 7;
 | 
						|
+
 | 
						|
+/* Try to keep at least this many packets in flight, if things go smoothly. For
 | 
						|
+ * smooth functioning, a sliding window protocol ACKing every other packet
 | 
						|
+ * needs at least 4 packets in flight. Max allowed value is 15 (0xF).
 | 
						|
+ */
 | 
						|
+static u32 bbr_cwnd_min_target = 4;
 | 
						|
+
 | 
						|
+/* Cwnd to BDP proportion in PROBE_RTT mode scaled by BBR_UNIT. Default: 50%.
 | 
						|
+ * Use 0 to disable. Max allowed value is 255.
 | 
						|
+ */
 | 
						|
+static u32 bbr_probe_rtt_cwnd_gain = BBR_UNIT * 1 / 2;
 | 
						|
+
 | 
						|
+/* To estimate if BBR_STARTUP mode (i.e. high_gain) has filled pipe... */
 | 
						|
+/* If bw has increased significantly (1.25x), there may be more bw available.
 | 
						|
+ * Max allowed value is 1023 (0x3FF).
 | 
						|
+ */
 | 
						|
+static u32 bbr_full_bw_thresh = BBR_UNIT * 5 / 4;
 | 
						|
+/* But after 3 rounds w/o significant bw growth, estimate pipe is full.
 | 
						|
+ * Max allowed value is 7 (0x7).
 | 
						|
+ */
 | 
						|
+static u32 bbr_full_bw_cnt = 3;
 | 
						|
+
 | 
						|
+static u32 bbr_flags;		/* Debugging related stuff */
 | 
						|
+
 | 
						|
+/* Whether to debug using printk.
 | 
						|
+ */
 | 
						|
+static bool bbr_debug_with_printk;
 | 
						|
+
 | 
						|
+/* Whether to debug using ftrace event tcp:tcp_bbr_event.
 | 
						|
+ * Ignored when bbr_debug_with_printk is set.
 | 
						|
+ */
 | 
						|
+static bool bbr_debug_ftrace;
 | 
						|
+
 | 
						|
+/* Experiment: each cycle, try to hold sub-unity gain until inflight <= BDP. */
 | 
						|
+static bool bbr_drain_to_target = true;		/* default: enabled */
 | 
						|
+
 | 
						|
+/* Experiment: Flags to control BBR with ECN behavior.
 | 
						|
+ */
 | 
						|
+static bool bbr_precise_ece_ack = true;		/* default: enabled */
 | 
						|
+
 | 
						|
+/* The max rwin scaling shift factor is 14 (RFC 1323), so the max sane rwin is
 | 
						|
+ * (2^(16+14) B)/(1024 B/packet) = 1M packets.
 | 
						|
+ */
 | 
						|
+static u32 bbr_cwnd_warn_val	= 1U << 20;
 | 
						|
+
 | 
						|
+static u16 bbr_debug_port_mask;
 | 
						|
+
 | 
						|
+/* BBR module parameters. These are module parameters only in Google prod.
 | 
						|
+ * Upstream these are intentionally not module parameters.
 | 
						|
+ */
 | 
						|
+static int bbr_pacing_gain_size = CYCLE_LEN;
 | 
						|
+
 | 
						|
+/* Gain factor for adding extra_acked to target cwnd: */
 | 
						|
+static int bbr_extra_acked_gain = 256;
 | 
						|
+
 | 
						|
+/* Window length of extra_acked window. Max allowed val is 31. */
 | 
						|
+static u32 bbr_extra_acked_win_rtts = 5;
 | 
						|
+
 | 
						|
+/* Max allowed val for ack_epoch_acked, after which sampling epoch is reset */
 | 
						|
+static u32 bbr_ack_epoch_acked_reset_thresh = 1U << 20;
 | 
						|
+
 | 
						|
+/* Time period for clamping cwnd increment due to ack aggregation */
 | 
						|
+static u32 bbr_extra_acked_max_us = 100 * 1000;
 | 
						|
+
 | 
						|
+/* Use extra acked in startup ?
 | 
						|
+ * 0: disabled
 | 
						|
+ * 1: use latest extra_acked value from 1-2 rtt in startup
 | 
						|
+ */
 | 
						|
+static int bbr_extra_acked_in_startup = 1;		/* default: enabled */
 | 
						|
+
 | 
						|
+/* Experiment: don't grow cwnd beyond twice of what we just probed. */
 | 
						|
+static bool bbr_usage_based_cwnd;		/* default: disabled */
 | 
						|
+
 | 
						|
+/* For lab testing, researchers can enable BBRv2 ECN support with this flag,
 | 
						|
+ * when they know that any ECN marks that the connections experience will be
 | 
						|
+ * DCTCP/L4S-style ECN marks, rather than RFC3168 ECN marks.
 | 
						|
+ * TODO(ncardwell): Production use of the BBRv2 ECN functionality depends on
 | 
						|
+ * negotiation or configuration that is outside the scope of the BBRv2
 | 
						|
+ * alpha release.
 | 
						|
+ */
 | 
						|
+static bool bbr_ecn_enable = false;
 | 
						|
+
 | 
						|
+module_param_named(bw_rtts,           bbr_bw_rtts,           int,    0644);
 | 
						|
+module_param_named(min_tso_rate,      bbr_min_tso_rate,      int,    0644);
 | 
						|
+module_param_named(tso_rtt_shift,     bbr_tso_rtt_shift,     int,    0644);
 | 
						|
+module_param_named(high_gain,         bbr_high_gain,         int,    0644);
 | 
						|
+module_param_named(drain_gain,        bbr_drain_gain,        int,    0644);
 | 
						|
+module_param_named(startup_cwnd_gain, bbr_startup_cwnd_gain, int,    0644);
 | 
						|
+module_param_named(cwnd_gain,         bbr_cwnd_gain,         int,    0644);
 | 
						|
+module_param_array_named(pacing_gain, bbr_pacing_gain,       int,
 | 
						|
+			 &bbr_pacing_gain_size, 0644);
 | 
						|
+module_param_named(cycle_rand,        bbr_cycle_rand,        uint,   0644);
 | 
						|
+module_param_named(cwnd_min_target,   bbr_cwnd_min_target,   uint,   0644);
 | 
						|
+module_param_named(probe_rtt_cwnd_gain,
 | 
						|
+		   bbr_probe_rtt_cwnd_gain,		     uint,   0664);
 | 
						|
+module_param_named(cwnd_warn_val,     bbr_cwnd_warn_val,     uint,   0664);
 | 
						|
+module_param_named(debug_port_mask,   bbr_debug_port_mask,   ushort, 0644);
 | 
						|
+module_param_named(flags,             bbr_flags,             uint,   0644);
 | 
						|
+module_param_named(debug_ftrace,      bbr_debug_ftrace, bool,   0644);
 | 
						|
+module_param_named(debug_with_printk, bbr_debug_with_printk, bool,   0644);
 | 
						|
+module_param_named(min_rtt_win_sec,   bbr_min_rtt_win_sec,   uint,   0644);
 | 
						|
+module_param_named(probe_rtt_mode_ms, bbr_probe_rtt_mode_ms, uint,   0644);
 | 
						|
+module_param_named(probe_rtt_win_ms,  bbr_probe_rtt_win_ms,  uint,   0644);
 | 
						|
+module_param_named(full_bw_thresh,    bbr_full_bw_thresh,    uint,   0644);
 | 
						|
+module_param_named(full_bw_cnt,       bbr_full_bw_cnt,       uint,   0644);
 | 
						|
+module_param_named(cwnd_tso_bduget,   bbr_cwnd_tso_budget,   uint,   0664);
 | 
						|
+module_param_named(extra_acked_gain,  bbr_extra_acked_gain,  int,    0664);
 | 
						|
+module_param_named(extra_acked_win_rtts,
 | 
						|
+		   bbr_extra_acked_win_rtts, uint,   0664);
 | 
						|
+module_param_named(extra_acked_max_us,
 | 
						|
+		   bbr_extra_acked_max_us, uint,   0664);
 | 
						|
+module_param_named(ack_epoch_acked_reset_thresh,
 | 
						|
+		   bbr_ack_epoch_acked_reset_thresh, uint,   0664);
 | 
						|
+module_param_named(drain_to_target,   bbr_drain_to_target,   bool,   0664);
 | 
						|
+module_param_named(precise_ece_ack,   bbr_precise_ece_ack,   bool,   0664);
 | 
						|
+module_param_named(extra_acked_in_startup,
 | 
						|
+		   bbr_extra_acked_in_startup, int, 0664);
 | 
						|
+module_param_named(usage_based_cwnd, bbr_usage_based_cwnd, bool,   0664);
 | 
						|
+module_param_named(ecn_enable,       bbr_ecn_enable,         bool,   0664);
 | 
						|
+
 | 
						|
+static void bbr2_exit_probe_rtt(struct sock *sk);
 | 
						|
+static void bbr2_reset_congestion_signals(struct sock *sk);
 | 
						|
+
 | 
						|
+static void bbr_check_probe_rtt_done(struct sock *sk);
 | 
						|
+
 | 
						|
+/* Do we estimate that STARTUP filled the pipe? */
 | 
						|
+static bool bbr_full_bw_reached(const struct sock *sk)
 | 
						|
+{
 | 
						|
+	const struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	return bbr->full_bw_reached;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Return the windowed max recent bandwidth sample, in pkts/uS << BW_SCALE. */
 | 
						|
+static u32 bbr_max_bw(const struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	return max(bbr->bw_hi[0], bbr->bw_hi[1]);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Return the estimated bandwidth of the path, in pkts/uS << BW_SCALE. */
 | 
						|
+static u32 bbr_bw(const struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	return min(bbr_max_bw(sk), bbr->bw_lo);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Return maximum extra acked in past k-2k round trips,
 | 
						|
+ * where k = bbr_extra_acked_win_rtts.
 | 
						|
+ */
 | 
						|
+static u16 bbr_extra_acked(const struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	return max(bbr->extra_acked[0], bbr->extra_acked[1]);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Return rate in bytes per second, optionally with a gain.
 | 
						|
+ * The order here is chosen carefully to avoid overflow of u64. This should
 | 
						|
+ * work for input rates of up to 2.9Tbit/sec and gain of 2.89x.
 | 
						|
+ */
 | 
						|
+static u64 bbr_rate_bytes_per_sec(struct sock *sk, u64 rate, int gain,
 | 
						|
+				  int margin)
 | 
						|
+{
 | 
						|
+	unsigned int mss = tcp_sk(sk)->mss_cache;
 | 
						|
+
 | 
						|
+	rate *= mss;
 | 
						|
+	rate *= gain;
 | 
						|
+	rate >>= BBR_SCALE;
 | 
						|
+	rate *= USEC_PER_SEC / 100 * (100 - margin);
 | 
						|
+	rate >>= BW_SCALE;
 | 
						|
+	rate = max(rate, 1ULL);
 | 
						|
+	return rate;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static u64 bbr_bw_bytes_per_sec(struct sock *sk, u64 rate)
 | 
						|
+{
 | 
						|
+	return bbr_rate_bytes_per_sec(sk, rate, BBR_UNIT, 0);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/*static u64 bbr_rate_kbps(struct sock *sk, u64 rate)
 | 
						|
+{
 | 
						|
+	rate = bbr_bw_bytes_per_sec(sk, rate);
 | 
						|
+	rate *= 8;
 | 
						|
+	do_div(rate, 1000);
 | 
						|
+	return rate;
 | 
						|
+}*/
 | 
						|
+
 | 
						|
+static u32 bbr_tso_segs_goal(struct sock *sk);
 | 
						|
+static void bbr_debug(struct sock *sk, u32 acked,
 | 
						|
+		      const struct rate_sample *rs, struct bbr_context *ctx)
 | 
						|
+{
 | 
						|
+#if 0
 | 
						|
+	static const char ca_states[] = {
 | 
						|
+		[TCP_CA_Open]		= 'O',
 | 
						|
+		[TCP_CA_Disorder]	= 'D',
 | 
						|
+		[TCP_CA_CWR]		= 'C',
 | 
						|
+		[TCP_CA_Recovery]	= 'R',
 | 
						|
+		[TCP_CA_Loss]		= 'L',
 | 
						|
+	};
 | 
						|
+	static const char mode[] = {
 | 
						|
+		'G',  /* Growing   - BBR_STARTUP */
 | 
						|
+		'D',  /* Drain     - BBR_DRAIN */
 | 
						|
+		'W',  /* Window    - BBR_PROBE_BW */
 | 
						|
+		'M',  /* Min RTT   - BBR_PROBE_RTT */
 | 
						|
+	};
 | 
						|
+	static const char ack_phase[] = { /* bbr_ack_phase strings */
 | 
						|
+		'I',	/* BBR_ACKS_INIT	   - 'Init' */
 | 
						|
+		'R',	/* BBR_ACKS_REFILLING	   - 'Refilling' */
 | 
						|
+		'B',	/* BBR_ACKS_PROBE_STARTING - 'Before' */
 | 
						|
+		'F',	/* BBR_ACKS_PROBE_FEEDBACK - 'Feedback' */
 | 
						|
+		'A',	/* BBR_ACKS_PROBE_STOPPING - 'After' */
 | 
						|
+	};
 | 
						|
+#endif
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	const u32 una = tp->snd_una - bbr->debug.snd_isn;
 | 
						|
+	//const u32 fack = tcp_highest_sack_seq(tp);
 | 
						|
+	const u16 dport = ntohs(inet_sk(sk)->inet_dport);
 | 
						|
+	bool is_port_match = (bbr_debug_port_mask &&
 | 
						|
+			      ((dport & bbr_debug_port_mask) == 0));
 | 
						|
+	char debugmsg[320];
 | 
						|
+
 | 
						|
+	if (sk->sk_state == TCP_SYN_SENT)
 | 
						|
+		return;  /* no bbr_init() yet if SYN retransmit -> CA_Loss */
 | 
						|
+
 | 
						|
+	if (!tp->snd_cwnd || tp->snd_cwnd > bbr_cwnd_warn_val) {
 | 
						|
+		char addr[INET6_ADDRSTRLEN + 10] = { 0 };
 | 
						|
+
 | 
						|
+		if (sk->sk_family == AF_INET)
 | 
						|
+			snprintf(addr, sizeof(addr), "%pI4:%u",
 | 
						|
+				 &inet_sk(sk)->inet_daddr, dport);
 | 
						|
+		else if (sk->sk_family == AF_INET6)
 | 
						|
+			snprintf(addr, sizeof(addr), "%pI6:%u",
 | 
						|
+				 &sk->sk_v6_daddr, dport);
 | 
						|
+
 | 
						|
+		WARN_ONCE(1,
 | 
						|
+			"BBR %s cwnd alert: %u "
 | 
						|
+			"snd_una: %u ca: %d pacing_gain: %u cwnd_gain: %u "
 | 
						|
+			"bw: %u rtt: %u min_rtt: %u "
 | 
						|
+			"acked: %u tso_segs: %u "
 | 
						|
+			"bw: %d %ld %d pif: %u\n",
 | 
						|
+			addr, tp->snd_cwnd,
 | 
						|
+			una, inet_csk(sk)->icsk_ca_state,
 | 
						|
+			bbr->pacing_gain, bbr->cwnd_gain,
 | 
						|
+			bbr_max_bw(sk), (tp->srtt_us >> 3), bbr->min_rtt_us,
 | 
						|
+			acked, bbr_tso_segs_goal(sk),
 | 
						|
+			rs->delivered, rs->interval_us, rs->is_retrans,
 | 
						|
+			tcp_packets_in_flight(tp));
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (likely(!bbr_debug_with_printk && !bbr_debug_ftrace))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	if (!sock_flag(sk, SOCK_DBG) && !is_port_match)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	if (!ctx->log && !tp->app_limited && !(bbr_flags & FLAG_DEBUG_VERBOSE))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	if (ipv4_is_loopback(inet_sk(sk)->inet_daddr) &&
 | 
						|
+	    !(bbr_flags & FLAG_DEBUG_LOOPBACK))
 | 
						|
+		return;
 | 
						|
+#if 0
 | 
						|
+	snprintf(debugmsg, sizeof(debugmsg) - 1,
 | 
						|
+		 "BBR %pI4:%-5u %5u,%03u:%-7u %c "
 | 
						|
+		 "%c %2u br %2u cr %2d rtt %5ld d %2d i %5ld mrtt %d %cbw %llu "
 | 
						|
+		 "bw %llu lb %llu ib %llu qb %llu "
 | 
						|
+		 "a %u if %2u %c %c dl %u l %u al %u # %u t %u %c %c "
 | 
						|
+		 "lr %d er %d ea %d bwl %lld il %d ih %d c %d "
 | 
						|
+		 "v %d %c %u %c %s\n",
 | 
						|
+		 &inet_sk(sk)->inet_daddr, dport,
 | 
						|
+		 una / 1000, una % 1000, fack - tp->snd_una,
 | 
						|
+		 ca_states[inet_csk(sk)->icsk_ca_state],
 | 
						|
+		 bbr->debug.undo ? '@' : mode[bbr->mode],
 | 
						|
+		 tp->snd_cwnd,
 | 
						|
+		 bbr_extra_acked(sk),	/* br (legacy): extra_acked */
 | 
						|
+		 rs->tx_in_flight,	/* cr (legacy): tx_inflight */
 | 
						|
+		 rs->rtt_us,
 | 
						|
+		 rs->delivered,
 | 
						|
+		 rs->interval_us,
 | 
						|
+		 bbr->min_rtt_us,
 | 
						|
+		 rs->is_app_limited ? '_' : 'l',
 | 
						|
+		 bbr_rate_kbps(sk, ctx->sample_bw), /* lbw: latest sample bw */
 | 
						|
+		 bbr_rate_kbps(sk, bbr_max_bw(sk)), /* bw: max bw */
 | 
						|
+		 0ULL,				    /* lb: [obsolete] */
 | 
						|
+		 0ULL,				    /* ib: [obsolete] */
 | 
						|
+		 (u64)sk->sk_pacing_rate * 8 / 1000,
 | 
						|
+		 acked,
 | 
						|
+		 tcp_packets_in_flight(tp),
 | 
						|
+		 rs->is_ack_delayed ? 'd' : '.',
 | 
						|
+		 bbr->round_start ? '*' : '.',
 | 
						|
+		 tp->delivered, tp->lost,
 | 
						|
+		 tp->app_limited,
 | 
						|
+		 0,			    	    /* #: [obsolete] */
 | 
						|
+		 ctx->target_cwnd,
 | 
						|
+		 tp->reord_seen ? 'r' : '.',  /* r: reordering seen? */
 | 
						|
+		 ca_states[bbr->prev_ca_state],
 | 
						|
+		 (rs->lost + rs->delivered) > 0 ?
 | 
						|
+		 (1000 * rs->lost /
 | 
						|
+		  (rs->lost + rs->delivered)) : 0,    /* lr: loss rate x1000 */
 | 
						|
+		 (rs->delivered) > 0 ?
 | 
						|
+		 (1000 * rs->delivered_ce /
 | 
						|
+		  (rs->delivered)) : 0,		      /* er: ECN rate x1000 */
 | 
						|
+		 1000 * bbr->ecn_alpha >> BBR_SCALE,  /* ea: ECN alpha x1000 */
 | 
						|
+		 bbr->bw_lo == ~0U ?
 | 
						|
+		   -1 : (s64)bbr_rate_kbps(sk, bbr->bw_lo), /* bwl */
 | 
						|
+		 bbr->inflight_lo,	/* il */
 | 
						|
+		 bbr->inflight_hi,	/* ih */
 | 
						|
+		 bbr->bw_probe_up_cnt,	/* c */
 | 
						|
+		 2,			/* v: version */
 | 
						|
+		 bbr->debug.event,
 | 
						|
+		 bbr->cycle_idx,
 | 
						|
+		 ack_phase[bbr->ack_phase],
 | 
						|
+		 bbr->bw_probe_samples ? "Y" : "N");
 | 
						|
+#endif
 | 
						|
+	debugmsg[sizeof(debugmsg) - 1] = 0;
 | 
						|
+
 | 
						|
+	/* printk takes a higher precedence. */
 | 
						|
+	if (bbr_debug_with_printk)
 | 
						|
+		printk(KERN_DEBUG "%s", debugmsg);
 | 
						|
+
 | 
						|
+	if (unlikely(bbr->debug.undo))
 | 
						|
+		bbr->debug.undo = 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Convert a BBR bw and gain factor to a pacing rate in bytes per second. */
 | 
						|
+static unsigned long bbr_bw_to_pacing_rate(struct sock *sk, u32 bw, int gain)
 | 
						|
+{
 | 
						|
+	u64 rate = bw;
 | 
						|
+
 | 
						|
+	rate = bbr_rate_bytes_per_sec(sk, rate, gain,
 | 
						|
+				      bbr_pacing_margin_percent);
 | 
						|
+	rate = min_t(u64, rate, sk->sk_max_pacing_rate);
 | 
						|
+	return rate;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Initialize pacing rate to: high_gain * init_cwnd / RTT. */
 | 
						|
+static void bbr_init_pacing_rate_from_rtt(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u64 bw;
 | 
						|
+	u32 rtt_us;
 | 
						|
+
 | 
						|
+	if (tp->srtt_us) {		/* any RTT sample yet? */
 | 
						|
+		rtt_us = max(tp->srtt_us >> 3, 1U);
 | 
						|
+		bbr->has_seen_rtt = 1;
 | 
						|
+	} else {			 /* no RTT sample yet */
 | 
						|
+		rtt_us = USEC_PER_MSEC;	 /* use nominal default RTT */
 | 
						|
+	}
 | 
						|
+	bw = (u64)tp->snd_cwnd * BW_UNIT;
 | 
						|
+	do_div(bw, rtt_us);
 | 
						|
+	sk->sk_pacing_rate = bbr_bw_to_pacing_rate(sk, bw, bbr->params.high_gain);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Pace using current bw estimate and a gain factor. */
 | 
						|
+static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	unsigned long rate = bbr_bw_to_pacing_rate(sk, bw, gain);
 | 
						|
+
 | 
						|
+	if (unlikely(!bbr->has_seen_rtt && tp->srtt_us))
 | 
						|
+		bbr_init_pacing_rate_from_rtt(sk);
 | 
						|
+	if (bbr_full_bw_reached(sk) || rate > sk->sk_pacing_rate)
 | 
						|
+		sk->sk_pacing_rate = rate;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static u32 bbr_min_tso_segs(struct sock *sk)
 | 
						|
+{
 | 
						|
+	return sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Return the number of segments BBR would like in a TSO/GSO skb, given
 | 
						|
+ * a particular max gso size as a constraint.
 | 
						|
+ */
 | 
						|
+static u32 bbr_tso_segs_generic(struct sock *sk, unsigned int mss_now,
 | 
						|
+				u32 gso_max_size)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 segs, r;
 | 
						|
+	u32 bytes;
 | 
						|
+
 | 
						|
+	/* Budget a TSO/GSO burst size allowance based on bw (pacing_rate). */
 | 
						|
+	bytes = sk->sk_pacing_rate >> sk->sk_pacing_shift;
 | 
						|
+
 | 
						|
+	/* Budget a TSO/GSO burst size allowance based on min_rtt. For every
 | 
						|
+	 * K = 2^tso_rtt_shift microseconds of min_rtt, halve the burst.
 | 
						|
+	 * The min_rtt-based burst allowance is: 64 KBytes / 2^(min_rtt/K)
 | 
						|
+	 */
 | 
						|
+	if (bbr->params.tso_rtt_shift) {
 | 
						|
+		r = bbr->min_rtt_us >> bbr->params.tso_rtt_shift;
 | 
						|
+		if (r < BITS_PER_TYPE(u32))   /* prevent undefined behavior */
 | 
						|
+			bytes += GSO_MAX_SIZE >> r;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	bytes = min_t(u32, bytes, gso_max_size - 1 - MAX_TCP_HEADER);
 | 
						|
+	segs = max_t(u32, bytes / mss_now, bbr_min_tso_segs(sk));
 | 
						|
+	return segs;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Custom tcp_tso_autosize() for BBR, used at transmit time to cap skb size. */
 | 
						|
+static u32  bbr_tso_segs(struct sock *sk, unsigned int mss_now)
 | 
						|
+{
 | 
						|
+	return bbr_tso_segs_generic(sk, mss_now, sk->sk_gso_max_size);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Like bbr_tso_segs(), using mss_cache, ignoring driver's sk_gso_max_size. */
 | 
						|
+static u32 bbr_tso_segs_goal(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+
 | 
						|
+	return  bbr_tso_segs_generic(sk, tp->mss_cache, GSO_MAX_SIZE);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */
 | 
						|
+static void bbr_save_cwnd(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (bbr->prev_ca_state < TCP_CA_Recovery && bbr->mode != BBR_PROBE_RTT)
 | 
						|
+		bbr->prior_cwnd = tp->snd_cwnd;  /* this cwnd is good enough */
 | 
						|
+	else  /* loss recovery or BBR_PROBE_RTT have temporarily cut cwnd */
 | 
						|
+		bbr->prior_cwnd = max(bbr->prior_cwnd, tp->snd_cwnd);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (event == CA_EVENT_TX_START && tp->app_limited) {
 | 
						|
+		bbr->idle_restart = 1;
 | 
						|
+		bbr->ack_epoch_mstamp = tp->tcp_mstamp;
 | 
						|
+		bbr->ack_epoch_acked = 0;
 | 
						|
+		/* Avoid pointless buffer overflows: pace at est. bw if we don't
 | 
						|
+		 * need more speed (we're restarting from idle and app-limited).
 | 
						|
+		 */
 | 
						|
+		if (bbr->mode == BBR_PROBE_BW)
 | 
						|
+			bbr_set_pacing_rate(sk, bbr_bw(sk), BBR_UNIT);
 | 
						|
+		else if (bbr->mode == BBR_PROBE_RTT)
 | 
						|
+			bbr_check_probe_rtt_done(sk);
 | 
						|
+	} else if ((event == CA_EVENT_ECN_IS_CE ||
 | 
						|
+		    event == CA_EVENT_ECN_NO_CE) &&
 | 
						|
+		    bbr_ecn_enable &&
 | 
						|
+		    bbr->params.precise_ece_ack) {
 | 
						|
+		u32 state = bbr->ce_state;
 | 
						|
+		dctcp_ece_ack_update(sk, event, &bbr->prior_rcv_nxt, &state);
 | 
						|
+		bbr->ce_state = state;
 | 
						|
+		if (tp->fast_ack_mode == 2 && event == CA_EVENT_ECN_IS_CE)
 | 
						|
+			tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS);
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Calculate bdp based on min RTT and the estimated bottleneck bandwidth:
 | 
						|
+ *
 | 
						|
+ * bdp = ceil(bw * min_rtt * gain)
 | 
						|
+ *
 | 
						|
+ * The key factor, gain, controls the amount of queue. While a small gain
 | 
						|
+ * builds a smaller queue, it becomes more vulnerable to noise in RTT
 | 
						|
+ * measurements (e.g., delayed ACKs or other ACK compression effects). This
 | 
						|
+ * noise may cause BBR to under-estimate the rate.
 | 
						|
+ */
 | 
						|
+static u32 bbr_bdp(struct sock *sk, u32 bw, int gain)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 bdp;
 | 
						|
+	u64 w;
 | 
						|
+
 | 
						|
+	/* If we've never had a valid RTT sample, cap cwnd at the initial
 | 
						|
+	 * default. This should only happen when the connection is not using TCP
 | 
						|
+	 * timestamps and has retransmitted all of the SYN/SYNACK/data packets
 | 
						|
+	 * ACKed so far. In this case, an RTO can cut cwnd to 1, in which
 | 
						|
+	 * case we need to slow-start up toward something safe: initial cwnd.
 | 
						|
+	 */
 | 
						|
+	if (unlikely(bbr->min_rtt_us == ~0U))	 /* no valid RTT samples yet? */
 | 
						|
+		return bbr->init_cwnd;  /* be safe: cap at initial cwnd */
 | 
						|
+
 | 
						|
+	w = (u64)bw * bbr->min_rtt_us;
 | 
						|
+
 | 
						|
+	/* Apply a gain to the given value, remove the BW_SCALE shift, and
 | 
						|
+	 * round the value up to avoid a negative feedback loop.
 | 
						|
+	 */
 | 
						|
+	bdp = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT;
 | 
						|
+
 | 
						|
+	return bdp;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* To achieve full performance in high-speed paths, we budget enough cwnd to
 | 
						|
+ * fit full-sized skbs in-flight on both end hosts to fully utilize the path:
 | 
						|
+ *   - one skb in sending host Qdisc,
 | 
						|
+ *   - one skb in sending host TSO/GSO engine
 | 
						|
+ *   - one skb being received by receiver host LRO/GRO/delayed-ACK engine
 | 
						|
+ * Don't worry, at low rates (bbr_min_tso_rate) this won't bloat cwnd because
 | 
						|
+ * in such cases tso_segs_goal is 1. The minimum cwnd is 4 packets,
 | 
						|
+ * which allows 2 outstanding 2-packet sequences, to try to keep pipe
 | 
						|
+ * full even with ACK-every-other-packet delayed ACKs.
 | 
						|
+ */
 | 
						|
+static u32 bbr_quantization_budget(struct sock *sk, u32 cwnd)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 tso_segs_goal;
 | 
						|
+
 | 
						|
+	tso_segs_goal = 3 * bbr_tso_segs_goal(sk);
 | 
						|
+
 | 
						|
+	/* Allow enough full-sized skbs in flight to utilize end systems. */
 | 
						|
+	if (bbr->params.cwnd_tso_budget == 1) {
 | 
						|
+		cwnd = max_t(u32, cwnd, tso_segs_goal);
 | 
						|
+		cwnd = max_t(u32, cwnd, bbr->params.cwnd_min_target);
 | 
						|
+	} else {
 | 
						|
+		cwnd += tso_segs_goal;
 | 
						|
+		cwnd = (cwnd + 1) & ~1U;
 | 
						|
+	}
 | 
						|
+	/* Ensure gain cycling gets inflight above BDP even for small BDPs. */
 | 
						|
+	if (bbr->mode == BBR_PROBE_BW && bbr->cycle_idx == BBR_BW_PROBE_UP)
 | 
						|
+		cwnd += 2;
 | 
						|
+
 | 
						|
+	return cwnd;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Find inflight based on min RTT and the estimated bottleneck bandwidth. */
 | 
						|
+static u32 bbr_inflight(struct sock *sk, u32 bw, int gain)
 | 
						|
+{
 | 
						|
+	u32 inflight;
 | 
						|
+
 | 
						|
+	inflight = bbr_bdp(sk, bw, gain);
 | 
						|
+	inflight = bbr_quantization_budget(sk, inflight);
 | 
						|
+
 | 
						|
+	return inflight;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* With pacing at lower layers, there's often less data "in the network" than
 | 
						|
+ * "in flight". With TSQ and departure time pacing at lower layers (e.g. fq),
 | 
						|
+ * we often have several skbs queued in the pacing layer with a pre-scheduled
 | 
						|
+ * earliest departure time (EDT). BBR adapts its pacing rate based on the
 | 
						|
+ * inflight level that it estimates has already been "baked in" by previous
 | 
						|
+ * departure time decisions. We calculate a rough estimate of the number of our
 | 
						|
+ * packets that might be in the network at the earliest departure time for the
 | 
						|
+ * next skb scheduled:
 | 
						|
+ *   in_network_at_edt = inflight_at_edt - (EDT - now) * bw
 | 
						|
+ * If we're increasing inflight, then we want to know if the transmit of the
 | 
						|
+ * EDT skb will push inflight above the target, so inflight_at_edt includes
 | 
						|
+ * bbr_tso_segs_goal() from the skb departing at EDT. If decreasing inflight,
 | 
						|
+ * then estimate if inflight will sink too low just before the EDT transmit.
 | 
						|
+ */
 | 
						|
+static u32 bbr_packets_in_net_at_edt(struct sock *sk, u32 inflight_now)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u64 now_ns, edt_ns, interval_us;
 | 
						|
+	u32 interval_delivered, inflight_at_edt;
 | 
						|
+
 | 
						|
+	now_ns = tp->tcp_clock_cache;
 | 
						|
+	edt_ns = max(tp->tcp_wstamp_ns, now_ns);
 | 
						|
+	interval_us = div_u64(edt_ns - now_ns, NSEC_PER_USEC);
 | 
						|
+	interval_delivered = (u64)bbr_bw(sk) * interval_us >> BW_SCALE;
 | 
						|
+	inflight_at_edt = inflight_now;
 | 
						|
+	if (bbr->pacing_gain > BBR_UNIT)              /* increasing inflight */
 | 
						|
+		inflight_at_edt += bbr_tso_segs_goal(sk);  /* include EDT skb */
 | 
						|
+	if (interval_delivered >= inflight_at_edt)
 | 
						|
+		return 0;
 | 
						|
+	return inflight_at_edt - interval_delivered;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Find the cwnd increment based on estimate of ack aggregation */
 | 
						|
+static u32 bbr_ack_aggregation_cwnd(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 max_aggr_cwnd, aggr_cwnd = 0;
 | 
						|
+
 | 
						|
+	if (bbr->params.extra_acked_gain &&
 | 
						|
+	    (bbr_full_bw_reached(sk) || bbr->params.extra_acked_in_startup)) {
 | 
						|
+		max_aggr_cwnd = ((u64)bbr_bw(sk) * bbr_extra_acked_max_us)
 | 
						|
+				/ BW_UNIT;
 | 
						|
+		aggr_cwnd = (bbr->params.extra_acked_gain * bbr_extra_acked(sk))
 | 
						|
+			     >> BBR_SCALE;
 | 
						|
+		aggr_cwnd = min(aggr_cwnd, max_aggr_cwnd);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return aggr_cwnd;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Returns the cwnd for PROBE_RTT mode. */
 | 
						|
+static u32 bbr_probe_rtt_cwnd(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (bbr->params.probe_rtt_cwnd_gain == 0)
 | 
						|
+		return bbr->params.cwnd_min_target;
 | 
						|
+	return max_t(u32, bbr->params.cwnd_min_target,
 | 
						|
+		     bbr_bdp(sk, bbr_bw(sk), bbr->params.probe_rtt_cwnd_gain));
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Slow-start up toward target cwnd (if bw estimate is growing, or packet loss
 | 
						|
+ * has drawn us down below target), or snap down to target if we're above it.
 | 
						|
+ */
 | 
						|
+static void bbr_set_cwnd(struct sock *sk, const struct rate_sample *rs,
 | 
						|
+			 u32 acked, u32 bw, int gain, u32 cwnd,
 | 
						|
+			 struct bbr_context *ctx)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 target_cwnd = 0, prev_cwnd = tp->snd_cwnd, max_probe;
 | 
						|
+
 | 
						|
+	if (!acked)
 | 
						|
+		goto done;  /* no packet fully ACKed; just apply caps */
 | 
						|
+
 | 
						|
+	target_cwnd = bbr_bdp(sk, bw, gain);
 | 
						|
+
 | 
						|
+	/* Increment the cwnd to account for excess ACKed data that seems
 | 
						|
+	 * due to aggregation (of data and/or ACKs) visible in the ACK stream.
 | 
						|
+	 */
 | 
						|
+	target_cwnd += bbr_ack_aggregation_cwnd(sk);
 | 
						|
+	target_cwnd = bbr_quantization_budget(sk, target_cwnd);
 | 
						|
+
 | 
						|
+	/* If we're below target cwnd, slow start cwnd toward target cwnd. */
 | 
						|
+	bbr->debug.target_cwnd = target_cwnd;
 | 
						|
+
 | 
						|
+	/* Update cwnd and enable fast path if cwnd reaches target_cwnd. */
 | 
						|
+	bbr->try_fast_path = 0;
 | 
						|
+	if (bbr_full_bw_reached(sk)) { /* only cut cwnd if we filled the pipe */
 | 
						|
+		cwnd += acked;
 | 
						|
+		if (cwnd >= target_cwnd) {
 | 
						|
+			cwnd = target_cwnd;
 | 
						|
+			bbr->try_fast_path = 1;
 | 
						|
+		}
 | 
						|
+	} else if (cwnd < target_cwnd || cwnd  < 2 * bbr->init_cwnd) {
 | 
						|
+		cwnd += acked;
 | 
						|
+	} else {
 | 
						|
+		bbr->try_fast_path = 1;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/* When growing cwnd, don't grow beyond twice what we just probed. */
 | 
						|
+	if (bbr->params.usage_based_cwnd) {
 | 
						|
+		max_probe = max(2 * tp->max_packets_out, tp->snd_cwnd);
 | 
						|
+		cwnd = min(cwnd, max_probe);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	cwnd = max_t(u32, cwnd, bbr->params.cwnd_min_target);
 | 
						|
+done:
 | 
						|
+	tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp);	/* apply global cap */
 | 
						|
+	if (bbr->mode == BBR_PROBE_RTT)  /* drain queue, refresh min_rtt */
 | 
						|
+		tp->snd_cwnd = min_t(u32, tp->snd_cwnd, bbr_probe_rtt_cwnd(sk));
 | 
						|
+
 | 
						|
+	ctx->target_cwnd = target_cwnd;
 | 
						|
+	ctx->log = (tp->snd_cwnd != prev_cwnd);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* See if we have reached next round trip */
 | 
						|
+static void bbr_update_round_start(struct sock *sk,
 | 
						|
+		const struct rate_sample *rs, struct bbr_context *ctx)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr->round_start = 0;
 | 
						|
+
 | 
						|
+	/* See if we've reached the next RTT */
 | 
						|
+	if (rs->interval_us > 0 &&
 | 
						|
+	    !before(rs->prior_delivered, bbr->next_rtt_delivered)) {
 | 
						|
+		bbr->next_rtt_delivered = tp->delivered;
 | 
						|
+		bbr->round_start = 1;
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Calculate the bandwidth based on how fast packets are delivered */
 | 
						|
+static void bbr_calculate_bw_sample(struct sock *sk,
 | 
						|
+			const struct rate_sample *rs, struct bbr_context *ctx)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u64 bw = 0;
 | 
						|
+
 | 
						|
+	/* Divide delivered by the interval to find a (lower bound) bottleneck
 | 
						|
+	 * bandwidth sample. Delivered is in packets and interval_us in uS and
 | 
						|
+	 * ratio will be <<1 for most connections. So delivered is first scaled.
 | 
						|
+	 * Round up to allow growth at low rates, even with integer division.
 | 
						|
+	 */
 | 
						|
+	if (rs->interval_us > 0) {
 | 
						|
+		if (WARN_ONCE(rs->delivered < 0,
 | 
						|
+			      "negative delivered: %d interval_us: %ld\n",
 | 
						|
+			      rs->delivered, rs->interval_us))
 | 
						|
+			return;
 | 
						|
+
 | 
						|
+		bw = DIV_ROUND_UP_ULL((u64)rs->delivered * BW_UNIT, rs->interval_us);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	ctx->sample_bw = bw;
 | 
						|
+	bbr->debug.rs_bw = bw;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Estimates the windowed max degree of ack aggregation.
 | 
						|
+ * This is used to provision extra in-flight data to keep sending during
 | 
						|
+ * inter-ACK silences.
 | 
						|
+ *
 | 
						|
+ * Degree of ack aggregation is estimated as extra data acked beyond expected.
 | 
						|
+ *
 | 
						|
+ * max_extra_acked = "maximum recent excess data ACKed beyond max_bw * interval"
 | 
						|
+ * cwnd += max_extra_acked
 | 
						|
+ *
 | 
						|
+ * Max extra_acked is clamped by cwnd and bw * bbr_extra_acked_max_us (100 ms).
 | 
						|
+ * Max filter is an approximate sliding window of 5-10 (packet timed) round
 | 
						|
+ * trips for non-startup phase, and 1-2 round trips for startup.
 | 
						|
+ */
 | 
						|
+static void bbr_update_ack_aggregation(struct sock *sk,
 | 
						|
+				       const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	u32 epoch_us, expected_acked, extra_acked;
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	u32 extra_acked_win_rtts_thresh = bbr->params.extra_acked_win_rtts;
 | 
						|
+
 | 
						|
+	if (!bbr->params.extra_acked_gain || rs->acked_sacked <= 0 ||
 | 
						|
+	    rs->delivered < 0 || rs->interval_us <= 0)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	if (bbr->round_start) {
 | 
						|
+		bbr->extra_acked_win_rtts = min(0x1F,
 | 
						|
+						bbr->extra_acked_win_rtts + 1);
 | 
						|
+		if (bbr->params.extra_acked_in_startup &&
 | 
						|
+		    !bbr_full_bw_reached(sk))
 | 
						|
+			extra_acked_win_rtts_thresh = 1;
 | 
						|
+		if (bbr->extra_acked_win_rtts >=
 | 
						|
+		    extra_acked_win_rtts_thresh) {
 | 
						|
+			bbr->extra_acked_win_rtts = 0;
 | 
						|
+			bbr->extra_acked_win_idx = bbr->extra_acked_win_idx ?
 | 
						|
+						   0 : 1;
 | 
						|
+			bbr->extra_acked[bbr->extra_acked_win_idx] = 0;
 | 
						|
+		}
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/* Compute how many packets we expected to be delivered over epoch. */
 | 
						|
+	epoch_us = tcp_stamp_us_delta(tp->delivered_mstamp,
 | 
						|
+				      bbr->ack_epoch_mstamp);
 | 
						|
+	expected_acked = ((u64)bbr_bw(sk) * epoch_us) / BW_UNIT;
 | 
						|
+
 | 
						|
+	/* Reset the aggregation epoch if ACK rate is below expected rate or
 | 
						|
+	 * significantly large no. of ack received since epoch (potentially
 | 
						|
+	 * quite old epoch).
 | 
						|
+	 */
 | 
						|
+	if (bbr->ack_epoch_acked <= expected_acked ||
 | 
						|
+	    (bbr->ack_epoch_acked + rs->acked_sacked >=
 | 
						|
+	     bbr_ack_epoch_acked_reset_thresh)) {
 | 
						|
+		bbr->ack_epoch_acked = 0;
 | 
						|
+		bbr->ack_epoch_mstamp = tp->delivered_mstamp;
 | 
						|
+		expected_acked = 0;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/* Compute excess data delivered, beyond what was expected. */
 | 
						|
+	bbr->ack_epoch_acked = min_t(u32, 0xFFFFF,
 | 
						|
+				   bbr->ack_epoch_acked + rs->acked_sacked);
 | 
						|
+	extra_acked = bbr->ack_epoch_acked - expected_acked;
 | 
						|
+	extra_acked = min(extra_acked, tp->snd_cwnd);
 | 
						|
+	if (extra_acked > bbr->extra_acked[bbr->extra_acked_win_idx])
 | 
						|
+		bbr->extra_acked[bbr->extra_acked_win_idx] = extra_acked;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Estimate when the pipe is full, using the change in delivery rate: BBR
 | 
						|
+ * estimates that STARTUP filled the pipe if the estimated bw hasn't changed by
 | 
						|
+ * at least bbr_full_bw_thresh (25%) after bbr_full_bw_cnt (3) non-app-limited
 | 
						|
+ * rounds. Why 3 rounds: 1: rwin autotuning grows the rwin, 2: we fill the
 | 
						|
+ * higher rwin, 3: we get higher delivery rate samples. Or transient
 | 
						|
+ * cross-traffic or radio noise can go away. CUBIC Hystart shares a similar
 | 
						|
+ * design goal, but uses delay and inter-ACK spacing instead of bandwidth.
 | 
						|
+ */
 | 
						|
+static void bbr_check_full_bw_reached(struct sock *sk,
 | 
						|
+				      const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 bw_thresh;
 | 
						|
+
 | 
						|
+	if (bbr_full_bw_reached(sk) || !bbr->round_start || rs->is_app_limited)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	bw_thresh = (u64)bbr->full_bw * bbr->params.full_bw_thresh >> BBR_SCALE;
 | 
						|
+	if (bbr_max_bw(sk) >= bw_thresh) {
 | 
						|
+		bbr->full_bw = bbr_max_bw(sk);
 | 
						|
+		bbr->full_bw_cnt = 0;
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+	++bbr->full_bw_cnt;
 | 
						|
+	bbr->full_bw_reached = bbr->full_bw_cnt >= bbr->params.full_bw_cnt;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* If pipe is probably full, drain the queue and then enter steady-state. */
 | 
						|
+static bool bbr_check_drain(struct sock *sk, const struct rate_sample *rs,
 | 
						|
+			    struct bbr_context *ctx)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (bbr->mode == BBR_STARTUP && bbr_full_bw_reached(sk)) {
 | 
						|
+		bbr->mode = BBR_DRAIN;	/* drain queue we created */
 | 
						|
+		tcp_sk(sk)->snd_ssthresh =
 | 
						|
+				bbr_inflight(sk, bbr_max_bw(sk), BBR_UNIT);
 | 
						|
+		bbr2_reset_congestion_signals(sk);
 | 
						|
+	}	/* fall through to check if in-flight is already small: */
 | 
						|
+	if (bbr->mode == BBR_DRAIN &&
 | 
						|
+	    bbr_packets_in_net_at_edt(sk, tcp_packets_in_flight(tcp_sk(sk))) <=
 | 
						|
+	    bbr_inflight(sk, bbr_max_bw(sk), BBR_UNIT))
 | 
						|
+		return true;  /* exiting DRAIN now */
 | 
						|
+	return false;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr_check_probe_rtt_done(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (!(bbr->probe_rtt_done_stamp &&
 | 
						|
+	      after(tcp_jiffies32, bbr->probe_rtt_done_stamp)))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	bbr->probe_rtt_min_stamp = tcp_jiffies32; /* schedule next PROBE_RTT */
 | 
						|
+	tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd);
 | 
						|
+	bbr2_exit_probe_rtt(sk);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* The goal of PROBE_RTT mode is to have BBR flows cooperatively and
 | 
						|
+ * periodically drain the bottleneck queue, to converge to measure the true
 | 
						|
+ * min_rtt (unloaded propagation delay). This allows the flows to keep queues
 | 
						|
+ * small (reducing queuing delay and packet loss) and achieve fairness among
 | 
						|
+ * BBR flows.
 | 
						|
+ *
 | 
						|
+ * The min_rtt filter window is 10 seconds. When the min_rtt estimate expires,
 | 
						|
+ * we enter PROBE_RTT mode and cap the cwnd at bbr_cwnd_min_target=4 packets.
 | 
						|
+ * After at least bbr_probe_rtt_mode_ms=200ms and at least one packet-timed
 | 
						|
+ * round trip elapsed with that flight size <= 4, we leave PROBE_RTT mode and
 | 
						|
+ * re-enter the previous mode. BBR uses 200ms to approximately bound the
 | 
						|
+ * performance penalty of PROBE_RTT's cwnd capping to roughly 2% (200ms/10s).
 | 
						|
+ *
 | 
						|
+ * Note that flows need only pay 2% if they are busy sending over the last 10
 | 
						|
+ * seconds. Interactive applications (e.g., Web, RPCs, video chunks) often have
 | 
						|
+ * natural silences or low-rate periods within 10 seconds where the rate is low
 | 
						|
+ * enough for long enough to drain its queue in the bottleneck. We pick up
 | 
						|
+ * these min RTT measurements opportunistically with our min_rtt filter. :-)
 | 
						|
+ */
 | 
						|
+static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	bool probe_rtt_expired, min_rtt_expired;
 | 
						|
+	u32 expire;
 | 
						|
+
 | 
						|
+	/* Track min RTT in probe_rtt_win_ms to time next PROBE_RTT state. */
 | 
						|
+	expire = bbr->probe_rtt_min_stamp +
 | 
						|
+		 msecs_to_jiffies(bbr->params.probe_rtt_win_ms);
 | 
						|
+	probe_rtt_expired = after(tcp_jiffies32, expire);
 | 
						|
+	if (rs->rtt_us >= 0 &&
 | 
						|
+	    (rs->rtt_us <= bbr->probe_rtt_min_us ||
 | 
						|
+	     (probe_rtt_expired && !rs->is_ack_delayed))) {
 | 
						|
+		bbr->probe_rtt_min_us = rs->rtt_us;
 | 
						|
+		bbr->probe_rtt_min_stamp = tcp_jiffies32;
 | 
						|
+	}
 | 
						|
+	/* Track min RTT seen in the min_rtt_win_sec filter window: */
 | 
						|
+	expire = bbr->min_rtt_stamp + bbr->params.min_rtt_win_sec * HZ;
 | 
						|
+	min_rtt_expired = after(tcp_jiffies32, expire);
 | 
						|
+	if (bbr->probe_rtt_min_us <= bbr->min_rtt_us ||
 | 
						|
+	    min_rtt_expired) {
 | 
						|
+		bbr->min_rtt_us = bbr->probe_rtt_min_us;
 | 
						|
+		bbr->min_rtt_stamp = bbr->probe_rtt_min_stamp;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (bbr->params.probe_rtt_mode_ms > 0 && probe_rtt_expired &&
 | 
						|
+	    !bbr->idle_restart && bbr->mode != BBR_PROBE_RTT) {
 | 
						|
+		bbr->mode = BBR_PROBE_RTT;  /* dip, drain queue */
 | 
						|
+		bbr_save_cwnd(sk);  /* note cwnd so we can restore it */
 | 
						|
+		bbr->probe_rtt_done_stamp = 0;
 | 
						|
+		bbr->ack_phase = BBR_ACKS_PROBE_STOPPING;
 | 
						|
+		bbr->next_rtt_delivered = tp->delivered;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (bbr->mode == BBR_PROBE_RTT) {
 | 
						|
+		/* Ignore low rate samples during this mode. */
 | 
						|
+		tp->app_limited =
 | 
						|
+			(tp->delivered + tcp_packets_in_flight(tp)) ? : 1;
 | 
						|
+		/* Maintain min packets in flight for max(200 ms, 1 round). */
 | 
						|
+		if (!bbr->probe_rtt_done_stamp &&
 | 
						|
+		    tcp_packets_in_flight(tp) <= bbr_probe_rtt_cwnd(sk)) {
 | 
						|
+			bbr->probe_rtt_done_stamp = tcp_jiffies32 +
 | 
						|
+				msecs_to_jiffies(bbr->params.probe_rtt_mode_ms);
 | 
						|
+			bbr->probe_rtt_round_done = 0;
 | 
						|
+			bbr->next_rtt_delivered = tp->delivered;
 | 
						|
+		} else if (bbr->probe_rtt_done_stamp) {
 | 
						|
+			if (bbr->round_start)
 | 
						|
+				bbr->probe_rtt_round_done = 1;
 | 
						|
+			if (bbr->probe_rtt_round_done)
 | 
						|
+				bbr_check_probe_rtt_done(sk);
 | 
						|
+		}
 | 
						|
+	}
 | 
						|
+	/* Restart after idle ends only once we process a new S/ACK for data */
 | 
						|
+	if (rs->delivered > 0)
 | 
						|
+		bbr->idle_restart = 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr_update_gains(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	switch (bbr->mode) {
 | 
						|
+	case BBR_STARTUP:
 | 
						|
+		bbr->pacing_gain = bbr->params.high_gain;
 | 
						|
+		bbr->cwnd_gain	 = bbr->params.startup_cwnd_gain;
 | 
						|
+		break;
 | 
						|
+	case BBR_DRAIN:
 | 
						|
+		bbr->pacing_gain = bbr->params.drain_gain;  /* slow, to drain */
 | 
						|
+		bbr->cwnd_gain = bbr->params.startup_cwnd_gain;  /* keep cwnd */
 | 
						|
+		break;
 | 
						|
+	case BBR_PROBE_BW:
 | 
						|
+		bbr->pacing_gain = bbr->params.pacing_gain[bbr->cycle_idx];
 | 
						|
+		bbr->cwnd_gain = bbr->params.cwnd_gain;
 | 
						|
+		break;
 | 
						|
+	case BBR_PROBE_RTT:
 | 
						|
+		bbr->pacing_gain = BBR_UNIT;
 | 
						|
+		bbr->cwnd_gain = BBR_UNIT;
 | 
						|
+		break;
 | 
						|
+	default:
 | 
						|
+		WARN_ONCE(1, "BBR bad mode: %u\n", bbr->mode);
 | 
						|
+		break;
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr_init(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	int i;
 | 
						|
+
 | 
						|
+	WARN_ON_ONCE(tp->snd_cwnd >= bbr_cwnd_warn_val);
 | 
						|
+
 | 
						|
+	bbr->initialized = 1;
 | 
						|
+	bbr->params.high_gain = min(0x7FF, bbr_high_gain);
 | 
						|
+	bbr->params.drain_gain = min(0x3FF, bbr_drain_gain);
 | 
						|
+	bbr->params.startup_cwnd_gain = min(0x7FF, bbr_startup_cwnd_gain);
 | 
						|
+	bbr->params.cwnd_gain = min(0x7FF, bbr_cwnd_gain);
 | 
						|
+	bbr->params.cwnd_tso_budget = min(0x1U, bbr_cwnd_tso_budget);
 | 
						|
+	bbr->params.cwnd_min_target = min(0xFU, bbr_cwnd_min_target);
 | 
						|
+	bbr->params.min_rtt_win_sec = min(0x1FU, bbr_min_rtt_win_sec);
 | 
						|
+	bbr->params.probe_rtt_mode_ms = min(0x1FFU, bbr_probe_rtt_mode_ms);
 | 
						|
+	bbr->params.full_bw_cnt = min(0x7U, bbr_full_bw_cnt);
 | 
						|
+	bbr->params.bw_rtts = min(0x1F, bbr_bw_rtts);
 | 
						|
+	bbr->params.full_bw_thresh = min(0x3FFU, bbr_full_bw_thresh);
 | 
						|
+	bbr->params.extra_acked_gain = min(0x7FF, bbr_extra_acked_gain);
 | 
						|
+	bbr->params.extra_acked_win_rtts = min(0x1FU, bbr_extra_acked_win_rtts);
 | 
						|
+	bbr->params.drain_to_target = bbr_drain_to_target ? 1 : 0;
 | 
						|
+	bbr->params.precise_ece_ack = bbr_precise_ece_ack ? 1 : 0;
 | 
						|
+	bbr->params.extra_acked_in_startup = bbr_extra_acked_in_startup ? 1 : 0;
 | 
						|
+	bbr->params.probe_rtt_cwnd_gain = min(0xFFU, bbr_probe_rtt_cwnd_gain);
 | 
						|
+	bbr->params.probe_rtt_win_ms =
 | 
						|
+		min(0x3FFFU,
 | 
						|
+		    min_t(u32, bbr_probe_rtt_win_ms,
 | 
						|
+			  bbr->params.min_rtt_win_sec * MSEC_PER_SEC));
 | 
						|
+	for (i = 0; i < CYCLE_LEN; i++)
 | 
						|
+		bbr->params.pacing_gain[i] = min(0x3FF, bbr_pacing_gain[i]);
 | 
						|
+	bbr->params.usage_based_cwnd = bbr_usage_based_cwnd ? 1 : 0;
 | 
						|
+	bbr->params.tso_rtt_shift =  min(0xFU, bbr_tso_rtt_shift);
 | 
						|
+
 | 
						|
+	bbr->debug.snd_isn = tp->snd_una;
 | 
						|
+	bbr->debug.target_cwnd = 0;
 | 
						|
+	bbr->debug.undo = 0;
 | 
						|
+
 | 
						|
+	bbr->init_cwnd = min(0x7FU, tp->snd_cwnd);
 | 
						|
+	bbr->prior_cwnd = tp->prior_cwnd;
 | 
						|
+	tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
 | 
						|
+	bbr->next_rtt_delivered = 0;
 | 
						|
+	bbr->prev_ca_state = TCP_CA_Open;
 | 
						|
+	bbr->packet_conservation = 0;
 | 
						|
+
 | 
						|
+	bbr->probe_rtt_done_stamp = 0;
 | 
						|
+	bbr->probe_rtt_round_done = 0;
 | 
						|
+	bbr->probe_rtt_min_us = tcp_min_rtt(tp);
 | 
						|
+	bbr->probe_rtt_min_stamp = tcp_jiffies32;
 | 
						|
+	bbr->min_rtt_us = tcp_min_rtt(tp);
 | 
						|
+	bbr->min_rtt_stamp = tcp_jiffies32;
 | 
						|
+
 | 
						|
+	bbr->has_seen_rtt = 0;
 | 
						|
+	bbr_init_pacing_rate_from_rtt(sk);
 | 
						|
+
 | 
						|
+	bbr->round_start = 0;
 | 
						|
+	bbr->idle_restart = 0;
 | 
						|
+	bbr->full_bw_reached = 0;
 | 
						|
+	bbr->full_bw = 0;
 | 
						|
+	bbr->full_bw_cnt = 0;
 | 
						|
+	bbr->cycle_mstamp = 0;
 | 
						|
+	bbr->cycle_idx = 0;
 | 
						|
+	bbr->mode = BBR_STARTUP;
 | 
						|
+	bbr->debug.rs_bw = 0;
 | 
						|
+
 | 
						|
+	bbr->ack_epoch_mstamp = tp->tcp_mstamp;
 | 
						|
+	bbr->ack_epoch_acked = 0;
 | 
						|
+	bbr->extra_acked_win_rtts = 0;
 | 
						|
+	bbr->extra_acked_win_idx = 0;
 | 
						|
+	bbr->extra_acked[0] = 0;
 | 
						|
+	bbr->extra_acked[1] = 0;
 | 
						|
+
 | 
						|
+	bbr->ce_state = 0;
 | 
						|
+	bbr->prior_rcv_nxt = tp->rcv_nxt;
 | 
						|
+	bbr->try_fast_path = 0;
 | 
						|
+
 | 
						|
+	cmpxchg(&sk->sk_pacing_status, SK_PACING_NONE, SK_PACING_NEEDED);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static u32 bbr_sndbuf_expand(struct sock *sk)
 | 
						|
+{
 | 
						|
+	/* Provision 3 * cwnd since BBR may slow-start even during recovery. */
 | 
						|
+	return 3;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* __________________________________________________________________________
 | 
						|
+ *
 | 
						|
+ * Functions new to BBR v2 ("bbr") congestion control are below here.
 | 
						|
+ * __________________________________________________________________________
 | 
						|
+ */
 | 
						|
+
 | 
						|
+/* Incorporate a new bw sample into the current window of our max filter. */
 | 
						|
+static void bbr2_take_bw_hi_sample(struct sock *sk, u32 bw)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr->bw_hi[1] = max(bw, bbr->bw_hi[1]);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Keep max of last 1-2 cycles. Each PROBE_BW cycle, flip filter window. */
 | 
						|
+static void bbr2_advance_bw_hi_filter(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (!bbr->bw_hi[1])
 | 
						|
+		return;  /* no samples in this window; remember old window */
 | 
						|
+	bbr->bw_hi[0] = bbr->bw_hi[1];
 | 
						|
+	bbr->bw_hi[1] = 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* How much do we want in flight? Our BDP, unless congestion cut cwnd. */
 | 
						|
+static u32 bbr2_target_inflight(struct sock *sk)
 | 
						|
+{
 | 
						|
+	u32 bdp = bbr_inflight(sk, bbr_bw(sk), BBR_UNIT);
 | 
						|
+
 | 
						|
+	return min(bdp, tcp_sk(sk)->snd_cwnd);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static bool bbr2_is_probing_bandwidth(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	return (bbr->mode == BBR_STARTUP) ||
 | 
						|
+		(bbr->mode == BBR_PROBE_BW &&
 | 
						|
+		 (bbr->cycle_idx == BBR_BW_PROBE_REFILL ||
 | 
						|
+		  bbr->cycle_idx == BBR_BW_PROBE_UP));
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Has the given amount of time elapsed since we marked the phase start? */
 | 
						|
+static bool bbr2_has_elapsed_in_phase(const struct sock *sk, u32 interval_us)
 | 
						|
+{
 | 
						|
+	const struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	const struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	return tcp_stamp_us_delta(tp->tcp_mstamp,
 | 
						|
+				  bbr->cycle_mstamp + interval_us) > 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr2_handle_queue_too_high_in_startup(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr->full_bw_reached = 1;
 | 
						|
+	bbr->inflight_hi = bbr_inflight(sk, bbr_max_bw(sk), BBR_UNIT);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Exit STARTUP upon N consecutive rounds with ECN mark rate > ecn_thresh. */
 | 
						|
+static void bbr2_check_ecn_too_high_in_startup(struct sock *sk, u32 ce_ratio)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (bbr_full_bw_reached(sk) || !bbr->ecn_eligible ||
 | 
						|
+	    !bbr->params.full_ecn_cnt || !bbr->params.ecn_thresh)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	if (ce_ratio >= bbr->params.ecn_thresh)
 | 
						|
+		bbr->startup_ecn_rounds++;
 | 
						|
+	else
 | 
						|
+		bbr->startup_ecn_rounds = 0;
 | 
						|
+
 | 
						|
+	if (bbr->startup_ecn_rounds >= bbr->params.full_ecn_cnt) {
 | 
						|
+		bbr->debug.event = 'E';  /* ECN caused STARTUP exit */
 | 
						|
+		bbr2_handle_queue_too_high_in_startup(sk);
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr2_update_ecn_alpha(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	s32 delivered, delivered_ce;
 | 
						|
+	u64 alpha, ce_ratio;
 | 
						|
+	u32 gain;
 | 
						|
+
 | 
						|
+	if (bbr->params.ecn_factor == 0)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	delivered = tp->delivered - bbr->alpha_last_delivered;
 | 
						|
+	delivered_ce = tp->delivered_ce - bbr->alpha_last_delivered_ce;
 | 
						|
+
 | 
						|
+	if (delivered == 0 ||		/* avoid divide by zero */
 | 
						|
+	    WARN_ON_ONCE(delivered < 0 || delivered_ce < 0))  /* backwards? */
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	/* See if we should use ECN sender logic for this connection. */
 | 
						|
+	if (!bbr->ecn_eligible && bbr_ecn_enable &&
 | 
						|
+	    (bbr->min_rtt_us <= bbr->params.ecn_max_rtt_us ||
 | 
						|
+	     !bbr->params.ecn_max_rtt_us))
 | 
						|
+		bbr->ecn_eligible = 1;
 | 
						|
+
 | 
						|
+	ce_ratio = (u64)delivered_ce << BBR_SCALE;
 | 
						|
+	do_div(ce_ratio, delivered);
 | 
						|
+	gain = bbr->params.ecn_alpha_gain;
 | 
						|
+	alpha = ((BBR_UNIT - gain) * bbr->ecn_alpha) >> BBR_SCALE;
 | 
						|
+	alpha += (gain * ce_ratio) >> BBR_SCALE;
 | 
						|
+	bbr->ecn_alpha = min_t(u32, alpha, BBR_UNIT);
 | 
						|
+
 | 
						|
+	bbr->alpha_last_delivered = tp->delivered;
 | 
						|
+	bbr->alpha_last_delivered_ce = tp->delivered_ce;
 | 
						|
+
 | 
						|
+	bbr2_check_ecn_too_high_in_startup(sk, ce_ratio);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Each round trip of BBR_BW_PROBE_UP, double volume of probing data. */
 | 
						|
+static void bbr2_raise_inflight_hi_slope(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 growth_this_round, cnt;
 | 
						|
+
 | 
						|
+	/* Calculate "slope": packets S/Acked per inflight_hi increment. */
 | 
						|
+	growth_this_round = 1 << bbr->bw_probe_up_rounds;
 | 
						|
+	bbr->bw_probe_up_rounds = min(bbr->bw_probe_up_rounds + 1, 30);
 | 
						|
+	cnt = tp->snd_cwnd / growth_this_round;
 | 
						|
+	cnt = max(cnt, 1U);
 | 
						|
+	bbr->bw_probe_up_cnt = cnt;
 | 
						|
+	bbr->debug.event = 'G';  /* Grow inflight_hi slope */
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* In BBR_BW_PROBE_UP, not seeing high loss/ECN/queue, so raise inflight_hi. */
 | 
						|
+static void bbr2_probe_inflight_hi_upward(struct sock *sk,
 | 
						|
+					  const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 delta;
 | 
						|
+
 | 
						|
+	if (!tp->is_cwnd_limited || tp->snd_cwnd < bbr->inflight_hi) {
 | 
						|
+		bbr->bw_probe_up_acks = 0;  /* don't accmulate unused credits */
 | 
						|
+		return;  /* not fully using inflight_hi, so don't grow it */
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/* For each bw_probe_up_cnt packets ACKed, increase inflight_hi by 1. */
 | 
						|
+	bbr->bw_probe_up_acks += rs->acked_sacked;
 | 
						|
+	if (bbr->bw_probe_up_acks >=  bbr->bw_probe_up_cnt) {
 | 
						|
+		delta = bbr->bw_probe_up_acks / bbr->bw_probe_up_cnt;
 | 
						|
+		bbr->bw_probe_up_acks -= delta * bbr->bw_probe_up_cnt;
 | 
						|
+		bbr->inflight_hi += delta;
 | 
						|
+		bbr->debug.event = 'I';  /* Increment inflight_hi */
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (bbr->round_start)
 | 
						|
+		bbr2_raise_inflight_hi_slope(sk);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Does loss/ECN rate for this sample say inflight is "too high"?
 | 
						|
+ * This is used by both the bbr_check_loss_too_high_in_startup() function,
 | 
						|
+ * which can be used in either v1 or v2, and the PROBE_UP phase of v2, which
 | 
						|
+ * uses it to notice when loss/ECN rates suggest inflight is too high.
 | 
						|
+ */
 | 
						|
+static bool bbr2_is_inflight_too_high(const struct sock *sk,
 | 
						|
+				     const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	const struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 loss_thresh, ecn_thresh;
 | 
						|
+
 | 
						|
+	if (rs->lost > 0 && rs->tx_in_flight) {
 | 
						|
+		loss_thresh = (u64)rs->tx_in_flight * bbr->params.loss_thresh >>
 | 
						|
+				BBR_SCALE;
 | 
						|
+		if (rs->lost > loss_thresh)
 | 
						|
+			return true;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (rs->delivered_ce > 0 && rs->delivered > 0 &&
 | 
						|
+	    bbr->ecn_eligible && bbr->params.ecn_thresh) {
 | 
						|
+		ecn_thresh = (u64)rs->delivered * bbr->params.ecn_thresh >>
 | 
						|
+				BBR_SCALE;
 | 
						|
+		if (rs->delivered_ce >= ecn_thresh)
 | 
						|
+			return true;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return false;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Calculate the tx_in_flight level that corresponded to excessive loss.
 | 
						|
+ * We find "lost_prefix" segs of the skb where loss rate went too high,
 | 
						|
+ * by solving for "lost_prefix" in the following equation:
 | 
						|
+ *   lost                     /  inflight                     >= loss_thresh
 | 
						|
+ *  (lost_prev + lost_prefix) / (inflight_prev + lost_prefix) >= loss_thresh
 | 
						|
+ * Then we take that equation, convert it to fixed point, and
 | 
						|
+ * round up to the nearest packet.
 | 
						|
+ */
 | 
						|
+static u32 bbr2_inflight_hi_from_lost_skb(const struct sock *sk,
 | 
						|
+					  const struct rate_sample *rs,
 | 
						|
+					  const struct sk_buff *skb)
 | 
						|
+{
 | 
						|
+	const struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 loss_thresh  = bbr->params.loss_thresh;
 | 
						|
+	u32 pcount, divisor, inflight_hi;
 | 
						|
+	s32 inflight_prev, lost_prev;
 | 
						|
+	u64 loss_budget, lost_prefix;
 | 
						|
+
 | 
						|
+	pcount = tcp_skb_pcount(skb);
 | 
						|
+
 | 
						|
+	/* How much data was in flight before this skb? */
 | 
						|
+	inflight_prev = rs->tx_in_flight - pcount;
 | 
						|
+	if (WARN_ONCE(inflight_prev < 0,
 | 
						|
+		      "tx_in_flight: %u pcount: %u reneg: %u",
 | 
						|
+		      rs->tx_in_flight, pcount, tcp_sk(sk)->is_sack_reneg))
 | 
						|
+		return ~0U;
 | 
						|
+
 | 
						|
+	/* How much inflight data was marked lost before this skb? */
 | 
						|
+	lost_prev = rs->lost - pcount;
 | 
						|
+	if (WARN_ON_ONCE(lost_prev < 0))
 | 
						|
+		return ~0U;
 | 
						|
+
 | 
						|
+	/* At what prefix of this lost skb did losss rate exceed loss_thresh? */
 | 
						|
+	loss_budget = (u64)inflight_prev * loss_thresh + BBR_UNIT - 1;
 | 
						|
+	loss_budget >>= BBR_SCALE;
 | 
						|
+	if (lost_prev >= loss_budget) {
 | 
						|
+		lost_prefix = 0;   /* previous losses crossed loss_thresh */
 | 
						|
+	} else {
 | 
						|
+		lost_prefix = loss_budget - lost_prev;
 | 
						|
+		lost_prefix <<= BBR_SCALE;
 | 
						|
+		divisor = BBR_UNIT - loss_thresh;
 | 
						|
+		if (WARN_ON_ONCE(!divisor))  /* loss_thresh is 8 bits */
 | 
						|
+			return ~0U;
 | 
						|
+		do_div(lost_prefix, divisor);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	inflight_hi = inflight_prev + lost_prefix;
 | 
						|
+	return inflight_hi;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* If loss/ECN rates during probing indicated we may have overfilled a
 | 
						|
+ * buffer, return an operating point that tries to leave unutilized headroom in
 | 
						|
+ * the path for other flows, for fairness convergence and lower RTTs and loss.
 | 
						|
+ */
 | 
						|
+static u32 bbr2_inflight_with_headroom(const struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 headroom, headroom_fraction;
 | 
						|
+
 | 
						|
+	if (bbr->inflight_hi == ~0U)
 | 
						|
+		return ~0U;
 | 
						|
+
 | 
						|
+	headroom_fraction = bbr->params.inflight_headroom;
 | 
						|
+	headroom = ((u64)bbr->inflight_hi * headroom_fraction) >> BBR_SCALE;
 | 
						|
+	headroom = max(headroom, 1U);
 | 
						|
+	return max_t(s32, bbr->inflight_hi - headroom,
 | 
						|
+		     bbr->params.cwnd_min_target);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Bound cwnd to a sensible level, based on our current probing state
 | 
						|
+ * machine phase and model of a good inflight level (inflight_lo, inflight_hi).
 | 
						|
+ */
 | 
						|
+static void bbr2_bound_cwnd_for_inflight_model(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 cap;
 | 
						|
+
 | 
						|
+	/* tcp_rcv_synsent_state_process() currently calls tcp_ack()
 | 
						|
+	 * and thus cong_control() without first initializing us(!).
 | 
						|
+	 */
 | 
						|
+	if (!bbr->initialized)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	cap = ~0U;
 | 
						|
+	if (bbr->mode == BBR_PROBE_BW &&
 | 
						|
+	    bbr->cycle_idx != BBR_BW_PROBE_CRUISE) {
 | 
						|
+		/* Probe to see if more packets fit in the path. */
 | 
						|
+		cap = bbr->inflight_hi;
 | 
						|
+	} else {
 | 
						|
+		if (bbr->mode == BBR_PROBE_RTT ||
 | 
						|
+		    (bbr->mode == BBR_PROBE_BW &&
 | 
						|
+		     bbr->cycle_idx == BBR_BW_PROBE_CRUISE))
 | 
						|
+			cap = bbr2_inflight_with_headroom(sk);
 | 
						|
+	}
 | 
						|
+	/* Adapt to any loss/ECN since our last bw probe. */
 | 
						|
+	cap = min(cap, bbr->inflight_lo);
 | 
						|
+
 | 
						|
+	cap = max_t(u32, cap, bbr->params.cwnd_min_target);
 | 
						|
+	tp->snd_cwnd = min(cap, tp->snd_cwnd);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Estimate a short-term lower bound on the capacity available now, based
 | 
						|
+ * on measurements of the current delivery process and recent history. When we
 | 
						|
+ * are seeing loss/ECN at times when we are not probing bw, then conservatively
 | 
						|
+ * move toward flow balance by multiplicatively cutting our short-term
 | 
						|
+ * estimated safe rate and volume of data (bw_lo and inflight_lo). We use a
 | 
						|
+ * multiplicative decrease in order to converge to a lower capacity in time
 | 
						|
+ * logarithmic in the magnitude of the decrease.
 | 
						|
+ *
 | 
						|
+ * However, we do not cut our short-term estimates lower than the current rate
 | 
						|
+ * and volume of delivered data from this round trip, since from the current
 | 
						|
+ * delivery process we can estimate the measured capacity available now.
 | 
						|
+ *
 | 
						|
+ * Anything faster than that approach would knowingly risk high loss, which can
 | 
						|
+ * cause low bw for Reno/CUBIC and high loss recovery latency for
 | 
						|
+ * request/response flows using any congestion control.
 | 
						|
+ */
 | 
						|
+static void bbr2_adapt_lower_bounds(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 ecn_cut, ecn_inflight_lo, beta;
 | 
						|
+
 | 
						|
+	/* We only use lower-bound estimates when not probing bw.
 | 
						|
+	 * When probing we need to push inflight higher to probe bw.
 | 
						|
+	 */
 | 
						|
+	if (bbr2_is_probing_bandwidth(sk))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	/* ECN response. */
 | 
						|
+	if (bbr->ecn_in_round && bbr->ecn_eligible && bbr->params.ecn_factor) {
 | 
						|
+		/* Reduce inflight to (1 - alpha*ecn_factor). */
 | 
						|
+		ecn_cut = (BBR_UNIT -
 | 
						|
+			   ((bbr->ecn_alpha * bbr->params.ecn_factor) >>
 | 
						|
+			    BBR_SCALE));
 | 
						|
+		if (bbr->inflight_lo == ~0U)
 | 
						|
+			bbr->inflight_lo = tp->snd_cwnd;
 | 
						|
+		ecn_inflight_lo = (u64)bbr->inflight_lo * ecn_cut >> BBR_SCALE;
 | 
						|
+	} else {
 | 
						|
+		ecn_inflight_lo = ~0U;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/* Loss response. */
 | 
						|
+	if (bbr->loss_in_round) {
 | 
						|
+		/* Reduce bw and inflight to (1 - beta). */
 | 
						|
+		if (bbr->bw_lo == ~0U)
 | 
						|
+			bbr->bw_lo = bbr_max_bw(sk);
 | 
						|
+		if (bbr->inflight_lo == ~0U)
 | 
						|
+			bbr->inflight_lo = tp->snd_cwnd;
 | 
						|
+		beta = bbr->params.beta;
 | 
						|
+		bbr->bw_lo =
 | 
						|
+			max_t(u32, bbr->bw_latest,
 | 
						|
+			      (u64)bbr->bw_lo *
 | 
						|
+			      (BBR_UNIT - beta) >> BBR_SCALE);
 | 
						|
+		bbr->inflight_lo =
 | 
						|
+			max_t(u32, bbr->inflight_latest,
 | 
						|
+			      (u64)bbr->inflight_lo *
 | 
						|
+			      (BBR_UNIT - beta) >> BBR_SCALE);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/* Adjust to the lower of the levels implied by loss or ECN. */
 | 
						|
+	bbr->inflight_lo = min(bbr->inflight_lo, ecn_inflight_lo);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Reset any short-term lower-bound adaptation to congestion, so that we can
 | 
						|
+ * push our inflight up.
 | 
						|
+ */
 | 
						|
+static void bbr2_reset_lower_bounds(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr->bw_lo = ~0U;
 | 
						|
+	bbr->inflight_lo = ~0U;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* After bw probing (STARTUP/PROBE_UP), reset signals before entering a state
 | 
						|
+ * machine phase where we adapt our lower bound based on congestion signals.
 | 
						|
+ */
 | 
						|
+static void bbr2_reset_congestion_signals(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr->loss_in_round = 0;
 | 
						|
+	bbr->ecn_in_round = 0;
 | 
						|
+	bbr->loss_in_cycle = 0;
 | 
						|
+	bbr->ecn_in_cycle = 0;
 | 
						|
+	bbr->bw_latest = 0;
 | 
						|
+	bbr->inflight_latest = 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Update (most of) our congestion signals: track the recent rate and volume of
 | 
						|
+ * delivered data, presence of loss, and EWMA degree of ECN marking.
 | 
						|
+ */
 | 
						|
+static void bbr2_update_congestion_signals(
 | 
						|
+	struct sock *sk, const struct rate_sample *rs, struct bbr_context *ctx)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u64 bw;
 | 
						|
+
 | 
						|
+	bbr->loss_round_start = 0;
 | 
						|
+	if (rs->interval_us <= 0 || !rs->acked_sacked)
 | 
						|
+		return; /* Not a valid observation */
 | 
						|
+	bw = ctx->sample_bw;
 | 
						|
+
 | 
						|
+	if (!rs->is_app_limited || bw >= bbr_max_bw(sk))
 | 
						|
+		bbr2_take_bw_hi_sample(sk, bw);
 | 
						|
+
 | 
						|
+	bbr->loss_in_round |= (rs->losses > 0);
 | 
						|
+
 | 
						|
+	/* Update rate and volume of delivered data from latest round trip: */
 | 
						|
+	bbr->bw_latest       = max_t(u32, bbr->bw_latest,       ctx->sample_bw);
 | 
						|
+	bbr->inflight_latest = max_t(u32, bbr->inflight_latest, rs->delivered);
 | 
						|
+
 | 
						|
+	if (before(rs->prior_delivered, bbr->loss_round_delivered))
 | 
						|
+		return;		/* skip the per-round-trip updates */
 | 
						|
+	/* Now do per-round-trip updates. */
 | 
						|
+	bbr->loss_round_delivered = tp->delivered;  /* mark round trip */
 | 
						|
+	bbr->loss_round_start = 1;
 | 
						|
+	bbr2_adapt_lower_bounds(sk);
 | 
						|
+
 | 
						|
+	/* Update windowed "latest" (single-round-trip) filters. */
 | 
						|
+	bbr->loss_in_round = 0;
 | 
						|
+	bbr->ecn_in_round  = 0;
 | 
						|
+	bbr->bw_latest = ctx->sample_bw;
 | 
						|
+	bbr->inflight_latest = rs->delivered;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Bandwidth probing can cause loss. To help coexistence with loss-based
 | 
						|
+ * congestion control we spread out our probing in a Reno-conscious way. Due to
 | 
						|
+ * the shape of the Reno sawtooth, the time required between loss epochs for an
 | 
						|
+ * idealized Reno flow is a number of round trips that is the BDP of that
 | 
						|
+ * flow. We count packet-timed round trips directly, since measured RTT can
 | 
						|
+ * vary widely, and Reno is driven by packet-timed round trips.
 | 
						|
+ */
 | 
						|
+static bool bbr2_is_reno_coexistence_probe_time(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 inflight, rounds, reno_gain, reno_rounds;
 | 
						|
+
 | 
						|
+	/* Random loss can shave some small percentage off of our inflight
 | 
						|
+	 * in each round. To survive this, flows need robust periodic probes.
 | 
						|
+	 */
 | 
						|
+	rounds = bbr->params.bw_probe_max_rounds;
 | 
						|
+
 | 
						|
+	reno_gain = bbr->params.bw_probe_reno_gain;
 | 
						|
+	if (reno_gain) {
 | 
						|
+		inflight = bbr2_target_inflight(sk);
 | 
						|
+		reno_rounds = ((u64)inflight * reno_gain) >> BBR_SCALE;
 | 
						|
+		rounds = min(rounds, reno_rounds);
 | 
						|
+	}
 | 
						|
+	return bbr->rounds_since_probe >= rounds;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* How long do we want to wait before probing for bandwidth (and risking
 | 
						|
+ * loss)? We randomize the wait, for better mixing and fairness convergence.
 | 
						|
+ *
 | 
						|
+ * We bound the Reno-coexistence inter-bw-probe time to be 62-63 round trips.
 | 
						|
+ * This is calculated to allow fairness with a 25Mbps, 30ms Reno flow,
 | 
						|
+ * (eg 4K video to a broadband user):
 | 
						|
+ *   BDP = 25Mbps * .030sec /(1514bytes) = 61.9 packets
 | 
						|
+ *
 | 
						|
+ * We bound the BBR-native inter-bw-probe wall clock time to be:
 | 
						|
+ *  (a) higher than 2 sec: to try to avoid causing loss for a long enough time
 | 
						|
+ *      to allow Reno at 30ms to get 4K video bw, the inter-bw-probe time must
 | 
						|
+ *      be at least: 25Mbps * .030sec / (1514bytes) * 0.030sec = 1.9secs
 | 
						|
+ *  (b) lower than 3 sec: to ensure flows can start probing in a reasonable
 | 
						|
+ *      amount of time to discover unutilized bw on human-scale interactive
 | 
						|
+ *      time-scales (e.g. perhaps traffic from a web page download that we
 | 
						|
+ *      were competing with is now complete).
 | 
						|
+ */
 | 
						|
+static void bbr2_pick_probe_wait(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	/* Decide the random round-trip bound for wait until probe: */
 | 
						|
+	bbr->rounds_since_probe =
 | 
						|
+		prandom_u32_max(bbr->params.bw_probe_rand_rounds);
 | 
						|
+	/* Decide the random wall clock bound for wait until probe: */
 | 
						|
+	bbr->probe_wait_us = bbr->params.bw_probe_base_us +
 | 
						|
+			     prandom_u32_max(bbr->params.bw_probe_rand_us);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr2_set_cycle_idx(struct sock *sk, int cycle_idx)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr->cycle_idx = cycle_idx;
 | 
						|
+	/* New phase, so need to update cwnd and pacing rate. */
 | 
						|
+	bbr->try_fast_path = 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Send at estimated bw to fill the pipe, but not queue. We need this phase
 | 
						|
+ * before PROBE_UP, because as soon as we send faster than the available bw
 | 
						|
+ * we will start building a queue, and if the buffer is shallow we can cause
 | 
						|
+ * loss. If we do not fill the pipe before we cause this loss, our bw_hi and
 | 
						|
+ * inflight_hi estimates will underestimate.
 | 
						|
+ */
 | 
						|
+static void bbr2_start_bw_probe_refill(struct sock *sk, u32 bw_probe_up_rounds)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr2_reset_lower_bounds(sk);
 | 
						|
+	if (bbr->inflight_hi != ~0U)
 | 
						|
+		bbr->inflight_hi += bbr->params.refill_add_inc;
 | 
						|
+	bbr->bw_probe_up_rounds = bw_probe_up_rounds;
 | 
						|
+	bbr->bw_probe_up_acks = 0;
 | 
						|
+	bbr->stopped_risky_probe = 0;
 | 
						|
+	bbr->ack_phase = BBR_ACKS_REFILLING;
 | 
						|
+	bbr->next_rtt_delivered = tp->delivered;
 | 
						|
+	bbr2_set_cycle_idx(sk, BBR_BW_PROBE_REFILL);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Now probe max deliverable data rate and volume. */
 | 
						|
+static void bbr2_start_bw_probe_up(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr->ack_phase = BBR_ACKS_PROBE_STARTING;
 | 
						|
+	bbr->next_rtt_delivered = tp->delivered;
 | 
						|
+	bbr->cycle_mstamp = tp->tcp_mstamp;
 | 
						|
+	bbr2_set_cycle_idx(sk, BBR_BW_PROBE_UP);
 | 
						|
+	bbr2_raise_inflight_hi_slope(sk);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Start a new PROBE_BW probing cycle of some wall clock length. Pick a wall
 | 
						|
+ * clock time at which to probe beyond an inflight that we think to be
 | 
						|
+ * safe. This will knowingly risk packet loss, so we want to do this rarely, to
 | 
						|
+ * keep packet loss rates low. Also start a round-trip counter, to probe faster
 | 
						|
+ * if we estimate a Reno flow at our BDP would probe faster.
 | 
						|
+ */
 | 
						|
+static void bbr2_start_bw_probe_down(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr2_reset_congestion_signals(sk);
 | 
						|
+	bbr->bw_probe_up_cnt = ~0U;     /* not growing inflight_hi any more */
 | 
						|
+	bbr2_pick_probe_wait(sk);
 | 
						|
+	bbr->cycle_mstamp = tp->tcp_mstamp;		/* start wall clock */
 | 
						|
+	bbr->ack_phase = BBR_ACKS_PROBE_STOPPING;
 | 
						|
+	bbr->next_rtt_delivered = tp->delivered;
 | 
						|
+	bbr2_set_cycle_idx(sk, BBR_BW_PROBE_DOWN);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Cruise: maintain what we estimate to be a neutral, conservative
 | 
						|
+ * operating point, without attempting to probe up for bandwidth or down for
 | 
						|
+ * RTT, and only reducing inflight in response to loss/ECN signals.
 | 
						|
+ */
 | 
						|
+static void bbr2_start_bw_probe_cruise(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (bbr->inflight_lo != ~0U)
 | 
						|
+		bbr->inflight_lo = min(bbr->inflight_lo, bbr->inflight_hi);
 | 
						|
+
 | 
						|
+	bbr2_set_cycle_idx(sk, BBR_BW_PROBE_CRUISE);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Loss and/or ECN rate is too high while probing.
 | 
						|
+ * Adapt (once per bw probe) by cutting inflight_hi and then restarting cycle.
 | 
						|
+ */
 | 
						|
+static void bbr2_handle_inflight_too_high(struct sock *sk,
 | 
						|
+					  const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	const u32 beta = bbr->params.beta;
 | 
						|
+
 | 
						|
+	bbr->prev_probe_too_high = 1;
 | 
						|
+	bbr->bw_probe_samples = 0;  /* only react once per probe */
 | 
						|
+	bbr->debug.event = 'L';     /* Loss/ECN too high */
 | 
						|
+	/* If we are app-limited then we are not robustly
 | 
						|
+	 * probing the max volume of inflight data we think
 | 
						|
+	 * might be safe (analogous to how app-limited bw
 | 
						|
+	 * samples are not known to be robustly probing bw).
 | 
						|
+	 */
 | 
						|
+	if (!rs->is_app_limited)
 | 
						|
+		bbr->inflight_hi = max_t(u32, rs->tx_in_flight,
 | 
						|
+					 (u64)bbr2_target_inflight(sk) *
 | 
						|
+					 (BBR_UNIT - beta) >> BBR_SCALE);
 | 
						|
+	if (bbr->mode == BBR_PROBE_BW && bbr->cycle_idx == BBR_BW_PROBE_UP)
 | 
						|
+		bbr2_start_bw_probe_down(sk);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* If we're seeing bw and loss samples reflecting our bw probing, adapt
 | 
						|
+ * using the signals we see. If loss or ECN mark rate gets too high, then adapt
 | 
						|
+ * inflight_hi downward. If we're able to push inflight higher without such
 | 
						|
+ * signals, push higher: adapt inflight_hi upward.
 | 
						|
+ */
 | 
						|
+static bool bbr2_adapt_upper_bounds(struct sock *sk,
 | 
						|
+				   const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	/* Track when we'll see bw/loss samples resulting from our bw probes. */
 | 
						|
+	if (bbr->ack_phase == BBR_ACKS_PROBE_STARTING && bbr->round_start)
 | 
						|
+		bbr->ack_phase = BBR_ACKS_PROBE_FEEDBACK;
 | 
						|
+	if (bbr->ack_phase == BBR_ACKS_PROBE_STOPPING && bbr->round_start) {
 | 
						|
+		/* End of samples from bw probing phase. */
 | 
						|
+		bbr->bw_probe_samples = 0;
 | 
						|
+		bbr->ack_phase = BBR_ACKS_INIT;
 | 
						|
+		/* At this point in the cycle, our current bw sample is also
 | 
						|
+		 * our best recent chance at finding the highest available bw
 | 
						|
+		 * for this flow. So now is the best time to forget the bw
 | 
						|
+		 * samples from the previous cycle, by advancing the window.
 | 
						|
+		 */
 | 
						|
+		if (bbr->mode == BBR_PROBE_BW && !rs->is_app_limited)
 | 
						|
+			bbr2_advance_bw_hi_filter(sk);
 | 
						|
+		/* If we had an inflight_hi, then probed and pushed inflight all
 | 
						|
+		 * the way up to hit that inflight_hi without seeing any
 | 
						|
+		 * high loss/ECN in all the resulting ACKs from that probing,
 | 
						|
+		 * then probe up again, this time letting inflight persist at
 | 
						|
+		 * inflight_hi for a round trip, then accelerating beyond.
 | 
						|
+		 */
 | 
						|
+		if (bbr->mode == BBR_PROBE_BW &&
 | 
						|
+		    bbr->stopped_risky_probe && !bbr->prev_probe_too_high) {
 | 
						|
+			bbr->debug.event = 'R';  /* reprobe */
 | 
						|
+			bbr2_start_bw_probe_refill(sk, 0);
 | 
						|
+			return true;  /* yes, decided state transition */
 | 
						|
+		}
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (bbr2_is_inflight_too_high(sk, rs)) {
 | 
						|
+		if (bbr->bw_probe_samples)  /*  sample is from bw probing? */
 | 
						|
+			bbr2_handle_inflight_too_high(sk, rs);
 | 
						|
+	} else {
 | 
						|
+		/* Loss/ECN rate is declared safe. Adjust upper bound upward. */
 | 
						|
+		if (bbr->inflight_hi == ~0U)  /* no excess queue signals yet? */
 | 
						|
+			return false;
 | 
						|
+
 | 
						|
+		/* To be resilient to random loss, we must raise inflight_hi
 | 
						|
+		 * if we observe in any phase that a higher level is safe.
 | 
						|
+		 */
 | 
						|
+		if (rs->tx_in_flight > bbr->inflight_hi) {
 | 
						|
+			bbr->inflight_hi = rs->tx_in_flight;
 | 
						|
+			bbr->debug.event = 'U';  /* raise up inflight_hi */
 | 
						|
+		}
 | 
						|
+
 | 
						|
+		if (bbr->mode == BBR_PROBE_BW &&
 | 
						|
+		    bbr->cycle_idx == BBR_BW_PROBE_UP)
 | 
						|
+			bbr2_probe_inflight_hi_upward(sk, rs);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return false;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Check if it's time to probe for bandwidth now, and if so, kick it off. */
 | 
						|
+static bool bbr2_check_time_to_probe_bw(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 n;
 | 
						|
+
 | 
						|
+	/* If we seem to be at an operating point where we are not seeing loss
 | 
						|
+	 * but we are seeing ECN marks, then when the ECN marks cease we reprobe
 | 
						|
+	 * quickly (in case a burst of cross-traffic has ceased and freed up bw,
 | 
						|
+	 * or in case we are sharing with multiplicatively probing traffic).
 | 
						|
+	 */
 | 
						|
+	if (bbr->params.ecn_reprobe_gain && bbr->ecn_eligible &&
 | 
						|
+	    bbr->ecn_in_cycle && !bbr->loss_in_cycle &&
 | 
						|
+	    inet_csk(sk)->icsk_ca_state == TCP_CA_Open) {
 | 
						|
+		bbr->debug.event = 'A';  /* *A*ll clear to probe *A*gain */
 | 
						|
+		/* Calculate n so that when bbr2_raise_inflight_hi_slope()
 | 
						|
+		 * computes growth_this_round as 2^n it will be roughly the
 | 
						|
+		 * desired volume of data (inflight_hi*ecn_reprobe_gain).
 | 
						|
+		 */
 | 
						|
+		n = ilog2((((u64)bbr->inflight_hi *
 | 
						|
+			    bbr->params.ecn_reprobe_gain) >> BBR_SCALE));
 | 
						|
+		bbr2_start_bw_probe_refill(sk, n);
 | 
						|
+		return true;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (bbr2_has_elapsed_in_phase(sk, bbr->probe_wait_us) ||
 | 
						|
+	    bbr2_is_reno_coexistence_probe_time(sk)) {
 | 
						|
+		bbr2_start_bw_probe_refill(sk, 0);
 | 
						|
+		return true;
 | 
						|
+	}
 | 
						|
+	return false;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Is it time to transition from PROBE_DOWN to PROBE_CRUISE? */
 | 
						|
+static bool bbr2_check_time_to_cruise(struct sock *sk, u32 inflight, u32 bw)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	bool is_under_bdp, is_long_enough;
 | 
						|
+
 | 
						|
+	/* Always need to pull inflight down to leave headroom in queue. */
 | 
						|
+	if (inflight > bbr2_inflight_with_headroom(sk))
 | 
						|
+		return false;
 | 
						|
+
 | 
						|
+	is_under_bdp = inflight <= bbr_inflight(sk, bw, BBR_UNIT);
 | 
						|
+	if (bbr->params.drain_to_target)
 | 
						|
+		return is_under_bdp;
 | 
						|
+
 | 
						|
+	is_long_enough = bbr2_has_elapsed_in_phase(sk, bbr->min_rtt_us);
 | 
						|
+	return is_under_bdp || is_long_enough;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* PROBE_BW state machine: cruise, refill, probe for bw, or drain? */
 | 
						|
+static void bbr2_update_cycle_phase(struct sock *sk,
 | 
						|
+				    const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	bool is_risky = false, is_queuing = false;
 | 
						|
+	u32 inflight, bw;
 | 
						|
+
 | 
						|
+	if (!bbr_full_bw_reached(sk))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	/* In DRAIN, PROBE_BW, or PROBE_RTT, adjust upper bounds. */
 | 
						|
+	if (bbr2_adapt_upper_bounds(sk, rs))
 | 
						|
+		return;		/* already decided state transition */
 | 
						|
+
 | 
						|
+	if (bbr->mode != BBR_PROBE_BW)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	inflight = bbr_packets_in_net_at_edt(sk, rs->prior_in_flight);
 | 
						|
+	bw = bbr_max_bw(sk);
 | 
						|
+
 | 
						|
+	switch (bbr->cycle_idx) {
 | 
						|
+	/* First we spend most of our time cruising with a pacing_gain of 1.0,
 | 
						|
+	 * which paces at the estimated bw, to try to fully use the pipe
 | 
						|
+	 * without building queue. If we encounter loss/ECN marks, we adapt
 | 
						|
+	 * by slowing down.
 | 
						|
+	 */
 | 
						|
+	case BBR_BW_PROBE_CRUISE:
 | 
						|
+		if (bbr2_check_time_to_probe_bw(sk))
 | 
						|
+			return;		/* already decided state transition */
 | 
						|
+		break;
 | 
						|
+
 | 
						|
+	/* After cruising, when it's time to probe, we first "refill": we send
 | 
						|
+	 * at the estimated bw to fill the pipe, before probing higher and
 | 
						|
+	 * knowingly risking overflowing the bottleneck buffer (causing loss).
 | 
						|
+	 */
 | 
						|
+	case BBR_BW_PROBE_REFILL:
 | 
						|
+		if (bbr->round_start) {
 | 
						|
+			/* After one full round trip of sending in REFILL, we
 | 
						|
+			 * start to see bw samples reflecting our REFILL, which
 | 
						|
+			 * may be putting too much data in flight.
 | 
						|
+			 */
 | 
						|
+			bbr->bw_probe_samples = 1;
 | 
						|
+			bbr2_start_bw_probe_up(sk);
 | 
						|
+		}
 | 
						|
+		break;
 | 
						|
+
 | 
						|
+	/* After we refill the pipe, we probe by using a pacing_gain > 1.0, to
 | 
						|
+	 * probe for bw. If we have not seen loss/ECN, we try to raise inflight
 | 
						|
+	 * to at least pacing_gain*BDP; note that this may take more than
 | 
						|
+	 * min_rtt if min_rtt is small (e.g. on a LAN).
 | 
						|
+	 *
 | 
						|
+	 * We terminate PROBE_UP bandwidth probing upon any of the following:
 | 
						|
+	 *
 | 
						|
+	 * (1) We've pushed inflight up to hit the inflight_hi target set in the
 | 
						|
+	 *     most recent previous bw probe phase. Thus we want to start
 | 
						|
+	 *     draining the queue immediately because it's very likely the most
 | 
						|
+	 *     recently sent packets will fill the queue and cause drops.
 | 
						|
+	 *     (checked here)
 | 
						|
+	 * (2) We have probed for at least 1*min_rtt_us, and the
 | 
						|
+	 *     estimated queue is high enough (inflight > 1.25 * estimated_bdp).
 | 
						|
+	 *     (checked here)
 | 
						|
+	 * (3) Loss filter says loss rate is "too high".
 | 
						|
+	 *     (checked in bbr_is_inflight_too_high())
 | 
						|
+	 * (4) ECN filter says ECN mark rate is "too high".
 | 
						|
+	 *     (checked in bbr_is_inflight_too_high())
 | 
						|
+	 */
 | 
						|
+	case BBR_BW_PROBE_UP:
 | 
						|
+		if (bbr->prev_probe_too_high &&
 | 
						|
+		    inflight >= bbr->inflight_hi) {
 | 
						|
+			bbr->stopped_risky_probe = 1;
 | 
						|
+			is_risky = true;
 | 
						|
+			bbr->debug.event = 'D';   /* D for danger */
 | 
						|
+		} else if (bbr2_has_elapsed_in_phase(sk, bbr->min_rtt_us) &&
 | 
						|
+			   inflight >=
 | 
						|
+			   bbr_inflight(sk, bw,
 | 
						|
+					bbr->params.bw_probe_pif_gain)) {
 | 
						|
+			is_queuing = true;
 | 
						|
+			bbr->debug.event = 'Q'; /* building Queue */
 | 
						|
+		}
 | 
						|
+		if (is_risky || is_queuing) {
 | 
						|
+			bbr->prev_probe_too_high = 0;  /* no loss/ECN (yet) */
 | 
						|
+			bbr2_start_bw_probe_down(sk);  /* restart w/ down */
 | 
						|
+		}
 | 
						|
+		break;
 | 
						|
+
 | 
						|
+	/* After probing in PROBE_UP, we have usually accumulated some data in
 | 
						|
+	 * the bottleneck buffer (if bw probing didn't find more bw). We next
 | 
						|
+	 * enter PROBE_DOWN to try to drain any excess data from the queue. To
 | 
						|
+	 * do this, we use a pacing_gain < 1.0. We hold this pacing gain until
 | 
						|
+	 * our inflight is less then that target cruising point, which is the
 | 
						|
+	 * minimum of (a) the amount needed to leave headroom, and (b) the
 | 
						|
+	 * estimated BDP. Once inflight falls to match the target, we estimate
 | 
						|
+	 * the queue is drained; persisting would underutilize the pipe.
 | 
						|
+	 */
 | 
						|
+	case BBR_BW_PROBE_DOWN:
 | 
						|
+		if (bbr2_check_time_to_probe_bw(sk))
 | 
						|
+			return;		/* already decided state transition */
 | 
						|
+		if (bbr2_check_time_to_cruise(sk, inflight, bw))
 | 
						|
+			bbr2_start_bw_probe_cruise(sk);
 | 
						|
+		break;
 | 
						|
+
 | 
						|
+	default:
 | 
						|
+		WARN_ONCE(1, "BBR invalid cycle index %u\n", bbr->cycle_idx);
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Exiting PROBE_RTT, so return to bandwidth probing in STARTUP or PROBE_BW. */
 | 
						|
+static void bbr2_exit_probe_rtt(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr2_reset_lower_bounds(sk);
 | 
						|
+	if (bbr_full_bw_reached(sk)) {
 | 
						|
+		bbr->mode = BBR_PROBE_BW;
 | 
						|
+		/* Raising inflight after PROBE_RTT may cause loss, so reset
 | 
						|
+		 * the PROBE_BW clock and schedule the next bandwidth probe for
 | 
						|
+		 * a friendly and randomized future point in time.
 | 
						|
+		 */
 | 
						|
+		bbr2_start_bw_probe_down(sk);
 | 
						|
+		/* Since we are exiting PROBE_RTT, we know inflight is
 | 
						|
+		 * below our estimated BDP, so it is reasonable to cruise.
 | 
						|
+		 */
 | 
						|
+		bbr2_start_bw_probe_cruise(sk);
 | 
						|
+	} else {
 | 
						|
+		bbr->mode = BBR_STARTUP;
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Exit STARTUP based on loss rate > 1% and loss gaps in round >= N. Wait until
 | 
						|
+ * the end of the round in recovery to get a good estimate of how many packets
 | 
						|
+ * have been lost, and how many we need to drain with a low pacing rate.
 | 
						|
+ */
 | 
						|
+static void bbr2_check_loss_too_high_in_startup(struct sock *sk,
 | 
						|
+					       const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (bbr_full_bw_reached(sk))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	/* For STARTUP exit, check the loss rate at the end of each round trip
 | 
						|
+	 * of Recovery episodes in STARTUP. We check the loss rate at the end
 | 
						|
+	 * of the round trip to filter out noisy/low loss and have a better
 | 
						|
+	 * sense of inflight (extent of loss), so we can drain more accurately.
 | 
						|
+	 */
 | 
						|
+	if (rs->losses && bbr->loss_events_in_round < 0xf)
 | 
						|
+		bbr->loss_events_in_round++;  /* update saturating counter */
 | 
						|
+	if (bbr->params.full_loss_cnt && bbr->loss_round_start &&
 | 
						|
+	    inet_csk(sk)->icsk_ca_state == TCP_CA_Recovery &&
 | 
						|
+	    bbr->loss_events_in_round >= bbr->params.full_loss_cnt &&
 | 
						|
+	    bbr2_is_inflight_too_high(sk, rs)) {
 | 
						|
+		bbr->debug.event = 'P';  /* Packet loss caused STARTUP exit */
 | 
						|
+		bbr2_handle_queue_too_high_in_startup(sk);
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+	if (bbr->loss_round_start)
 | 
						|
+		bbr->loss_events_in_round = 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* If we are done draining, advance into steady state operation in PROBE_BW. */
 | 
						|
+static void bbr2_check_drain(struct sock *sk, const struct rate_sample *rs,
 | 
						|
+			     struct bbr_context *ctx)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (bbr_check_drain(sk, rs, ctx)) {
 | 
						|
+		bbr->mode = BBR_PROBE_BW;
 | 
						|
+		bbr2_start_bw_probe_down(sk);
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr2_update_model(struct sock *sk, const struct rate_sample *rs,
 | 
						|
+			      struct bbr_context *ctx)
 | 
						|
+{
 | 
						|
+	bbr2_update_congestion_signals(sk, rs, ctx);
 | 
						|
+	bbr_update_ack_aggregation(sk, rs);
 | 
						|
+	bbr2_check_loss_too_high_in_startup(sk, rs);
 | 
						|
+	bbr_check_full_bw_reached(sk, rs);
 | 
						|
+	bbr2_check_drain(sk, rs, ctx);
 | 
						|
+	bbr2_update_cycle_phase(sk, rs);
 | 
						|
+	bbr_update_min_rtt(sk, rs);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Fast path for app-limited case.
 | 
						|
+ *
 | 
						|
+ * On each ack, we execute bbr state machine, which primarily consists of:
 | 
						|
+ * 1) update model based on new rate sample, and
 | 
						|
+ * 2) update control based on updated model or state change.
 | 
						|
+ *
 | 
						|
+ * There are certain workload/scenarios, e.g. app-limited case, where
 | 
						|
+ * either we can skip updating model or we can skip update of both model
 | 
						|
+ * as well as control. This provides signifcant softirq cpu savings for
 | 
						|
+ * processing incoming acks.
 | 
						|
+ *
 | 
						|
+ * In case of app-limited, if there is no congestion (loss/ecn) and
 | 
						|
+ * if observed bw sample is less than current estimated bw, then we can
 | 
						|
+ * skip some of the computation in bbr state processing:
 | 
						|
+ *
 | 
						|
+ * - if there is no rtt/mode/phase change: In this case, since all the
 | 
						|
+ *   parameters of the network model are constant, we can skip model
 | 
						|
+ *   as well control update.
 | 
						|
+ *
 | 
						|
+ * - else we can skip rest of the model update. But we still need to
 | 
						|
+ *   update the control to account for the new rtt/mode/phase.
 | 
						|
+ *
 | 
						|
+ * Returns whether we can take fast path or not.
 | 
						|
+ */
 | 
						|
+static bool bbr2_fast_path(struct sock *sk, bool *update_model,
 | 
						|
+		const struct rate_sample *rs, struct bbr_context *ctx)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	u32 prev_min_rtt_us, prev_mode;
 | 
						|
+
 | 
						|
+	if (bbr->params.fast_path && bbr->try_fast_path &&
 | 
						|
+	    rs->is_app_limited && ctx->sample_bw < bbr_max_bw(sk) &&
 | 
						|
+	    !bbr->loss_in_round && !bbr->ecn_in_round) {
 | 
						|
+		prev_mode = bbr->mode;
 | 
						|
+		prev_min_rtt_us = bbr->min_rtt_us;
 | 
						|
+		bbr2_check_drain(sk, rs, ctx);
 | 
						|
+		bbr2_update_cycle_phase(sk, rs);
 | 
						|
+		bbr_update_min_rtt(sk, rs);
 | 
						|
+
 | 
						|
+		if (bbr->mode == prev_mode &&
 | 
						|
+		    bbr->min_rtt_us == prev_min_rtt_us &&
 | 
						|
+		    bbr->try_fast_path)
 | 
						|
+			return true;
 | 
						|
+
 | 
						|
+		/* Skip model update, but control still needs to be updated */
 | 
						|
+		*update_model = false;
 | 
						|
+	}
 | 
						|
+	return false;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr2_main(struct sock *sk, const struct rate_sample *rs)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	struct bbr_context ctx = { 0 };
 | 
						|
+	bool update_model = true;
 | 
						|
+	u32 bw;
 | 
						|
+
 | 
						|
+	bbr->debug.event = '.';  /* init to default NOP (no event yet) */
 | 
						|
+
 | 
						|
+	bbr_update_round_start(sk, rs, &ctx);
 | 
						|
+	if (bbr->round_start) {
 | 
						|
+		bbr->rounds_since_probe =
 | 
						|
+			min_t(s32, bbr->rounds_since_probe + 1, 0xFF);
 | 
						|
+		bbr2_update_ecn_alpha(sk);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	bbr->ecn_in_round  |= rs->is_ece;
 | 
						|
+	bbr_calculate_bw_sample(sk, rs, &ctx);
 | 
						|
+
 | 
						|
+	if (bbr2_fast_path(sk, &update_model, rs, &ctx))
 | 
						|
+		goto out;
 | 
						|
+
 | 
						|
+	if (update_model)
 | 
						|
+		bbr2_update_model(sk, rs, &ctx);
 | 
						|
+
 | 
						|
+	bbr_update_gains(sk);
 | 
						|
+	bw = bbr_bw(sk);
 | 
						|
+	bbr_set_pacing_rate(sk, bw, bbr->pacing_gain);
 | 
						|
+	bbr_set_cwnd(sk, rs, rs->acked_sacked, bw, bbr->cwnd_gain,
 | 
						|
+		     tp->snd_cwnd, &ctx);
 | 
						|
+	bbr2_bound_cwnd_for_inflight_model(sk);
 | 
						|
+
 | 
						|
+out:
 | 
						|
+	bbr->prev_ca_state = inet_csk(sk)->icsk_ca_state;
 | 
						|
+	bbr->loss_in_cycle |= rs->lost > 0;
 | 
						|
+	bbr->ecn_in_cycle  |= rs->delivered_ce > 0;
 | 
						|
+
 | 
						|
+	bbr_debug(sk, rs->acked_sacked, rs, &ctx);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Module parameters that are settable by TCP_CONGESTION_PARAMS are declared
 | 
						|
+ * down here, so that the algorithm functions that use the parameters must use
 | 
						|
+ * the per-socket parameters; if they accidentally use the global version
 | 
						|
+ * then there will be a compile error.
 | 
						|
+ * TODO(ncardwell): move all per-socket parameters down to this section.
 | 
						|
+ */
 | 
						|
+
 | 
						|
+/* On losses, scale down inflight and pacing rate by beta scaled by BBR_SCALE.
 | 
						|
+ * No loss response when 0. Max allwed value is 255.
 | 
						|
+ */
 | 
						|
+static u32 bbr_beta = BBR_UNIT * 30 / 100;
 | 
						|
+
 | 
						|
+/* Gain factor for ECN mark ratio samples, scaled by BBR_SCALE.
 | 
						|
+ * Max allowed value is 255.
 | 
						|
+ */
 | 
						|
+static u32 bbr_ecn_alpha_gain = BBR_UNIT * 1 / 16;  /* 1/16 = 6.25% */
 | 
						|
+
 | 
						|
+/* The initial value for the ecn_alpha state variable. Default and max
 | 
						|
+ * BBR_UNIT (256), representing 1.0. This allows a flow to respond quickly
 | 
						|
+ * to congestion if the bottleneck is congested when the flow starts up.
 | 
						|
+ */
 | 
						|
+static u32 bbr_ecn_alpha_init = BBR_UNIT;	/* 1.0, to respond quickly */
 | 
						|
+
 | 
						|
+/* On ECN, cut inflight_lo to (1 - ecn_factor * ecn_alpha) scaled by BBR_SCALE.
 | 
						|
+ * No ECN based bounding when 0. Max allwed value is 255.
 | 
						|
+ */
 | 
						|
+static u32 bbr_ecn_factor = BBR_UNIT * 1 / 3;	    /* 1/3 = 33% */
 | 
						|
+
 | 
						|
+/* Estimate bw probing has gone too far if CE ratio exceeds this threshold.
 | 
						|
+ * Scaled by BBR_SCALE. Disabled when 0. Max allowed is 255.
 | 
						|
+ */
 | 
						|
+static u32 bbr_ecn_thresh = BBR_UNIT * 1 / 2;  /* 1/2 = 50% */
 | 
						|
+
 | 
						|
+/* Max RTT (in usec) at which to use sender-side ECN logic.
 | 
						|
+ * Disabled when 0 (ECN allowed at any RTT).
 | 
						|
+ * Max allowed for the parameter is 524287 (0x7ffff) us, ~524 ms.
 | 
						|
+ */
 | 
						|
+static u32 bbr_ecn_max_rtt_us = 5000;
 | 
						|
+
 | 
						|
+/* If non-zero, if in a cycle with no losses but some ECN marks, after ECN
 | 
						|
+ * clears then use a multiplicative increase to quickly reprobe bw by
 | 
						|
+ * starting inflight probing at the given multiple of inflight_hi.
 | 
						|
+ * Default for this experimental knob is 0 (disabled).
 | 
						|
+ * Planned value for experiments: BBR_UNIT * 1 / 2 = 128, representing 0.5.
 | 
						|
+ */
 | 
						|
+static u32 bbr_ecn_reprobe_gain;
 | 
						|
+
 | 
						|
+/* Estimate bw probing has gone too far if loss rate exceeds this level. */
 | 
						|
+static u32 bbr_loss_thresh = BBR_UNIT * 2 / 100;  /* 2% loss */
 | 
						|
+
 | 
						|
+/* Exit STARTUP if number of loss marking events in a Recovery round is >= N,
 | 
						|
+ * and loss rate is higher than bbr_loss_thresh.
 | 
						|
+ * Disabled if 0. Max allowed value is 15 (0xF).
 | 
						|
+ */
 | 
						|
+static u32 bbr_full_loss_cnt = 8;
 | 
						|
+
 | 
						|
+/* Exit STARTUP if number of round trips with ECN mark rate above ecn_thresh
 | 
						|
+ * meets this count. Max allowed value is 3.
 | 
						|
+ */
 | 
						|
+static u32 bbr_full_ecn_cnt = 2;
 | 
						|
+
 | 
						|
+/* Fraction of unutilized headroom to try to leave in path upon high loss. */
 | 
						|
+static u32 bbr_inflight_headroom = BBR_UNIT * 15 / 100;
 | 
						|
+
 | 
						|
+/* Multiplier to get target inflight (as multiple of BDP) for PROBE_UP phase.
 | 
						|
+ * Default is 1.25x, as in BBR v1. Max allowed is 511.
 | 
						|
+ */
 | 
						|
+static u32 bbr_bw_probe_pif_gain = BBR_UNIT * 5 / 4;
 | 
						|
+
 | 
						|
+/* Multiplier to get Reno-style probe epoch duration as: k * BDP round trips.
 | 
						|
+ * If zero, disables this BBR v2 Reno-style BDP-scaled coexistence mechanism.
 | 
						|
+ * Max allowed is 511.
 | 
						|
+ */
 | 
						|
+static u32 bbr_bw_probe_reno_gain = BBR_UNIT;
 | 
						|
+
 | 
						|
+/* Max number of packet-timed rounds to wait before probing for bandwidth.  If
 | 
						|
+ * we want to tolerate 1% random loss per round, and not have this cut our
 | 
						|
+ * inflight too much, we must probe for bw periodically on roughly this scale.
 | 
						|
+ * If low, limits Reno/CUBIC coexistence; if high, limits loss tolerance.
 | 
						|
+ * We aim to be fair with Reno/CUBIC up to a BDP of at least:
 | 
						|
+ *  BDP = 25Mbps * .030sec /(1514bytes) = 61.9 packets
 | 
						|
+ */
 | 
						|
+static u32 bbr_bw_probe_max_rounds = 63;
 | 
						|
+
 | 
						|
+/* Max amount of randomness to inject in round counting for Reno-coexistence.
 | 
						|
+ * Max value is 15.
 | 
						|
+ */
 | 
						|
+static u32 bbr_bw_probe_rand_rounds = 2;
 | 
						|
+
 | 
						|
+/* Use BBR-native probe time scale starting at this many usec.
 | 
						|
+ * We aim to be fair with Reno/CUBIC up to an inter-loss time epoch of at least:
 | 
						|
+ *  BDP*RTT = 25Mbps * .030sec /(1514bytes) * 0.030sec = 1.9 secs
 | 
						|
+ */
 | 
						|
+static u32 bbr_bw_probe_base_us = 2 * USEC_PER_SEC;  /* 2 secs */
 | 
						|
+
 | 
						|
+/* Use BBR-native probes spread over this many usec: */
 | 
						|
+static u32 bbr_bw_probe_rand_us = 1 * USEC_PER_SEC;  /* 1 secs */
 | 
						|
+
 | 
						|
+/* Undo the model changes made in loss recovery if recovery was spurious? */
 | 
						|
+static bool bbr_undo = true;
 | 
						|
+
 | 
						|
+/* Use fast path if app-limited, no loss/ECN, and target cwnd was reached? */
 | 
						|
+static bool bbr_fast_path = true;	/* default: enabled */
 | 
						|
+
 | 
						|
+/* Use fast ack mode ? */
 | 
						|
+static int bbr_fast_ack_mode = 1;	/* default: rwnd check off */
 | 
						|
+
 | 
						|
+/* How much to additively increase inflight_hi when entering REFILL? */
 | 
						|
+static u32 bbr_refill_add_inc;		/* default: disabled */
 | 
						|
+
 | 
						|
+module_param_named(beta,                 bbr_beta,                 uint, 0644);
 | 
						|
+module_param_named(ecn_alpha_gain,       bbr_ecn_alpha_gain,       uint, 0644);
 | 
						|
+module_param_named(ecn_alpha_init,       bbr_ecn_alpha_init,       uint, 0644);
 | 
						|
+module_param_named(ecn_factor,           bbr_ecn_factor,           uint, 0644);
 | 
						|
+module_param_named(ecn_thresh,           bbr_ecn_thresh,           uint, 0644);
 | 
						|
+module_param_named(ecn_max_rtt_us,       bbr_ecn_max_rtt_us,       uint, 0644);
 | 
						|
+module_param_named(ecn_reprobe_gain,     bbr_ecn_reprobe_gain,     uint, 0644);
 | 
						|
+module_param_named(loss_thresh,          bbr_loss_thresh,          uint, 0664);
 | 
						|
+module_param_named(full_loss_cnt,        bbr_full_loss_cnt,        uint, 0664);
 | 
						|
+module_param_named(full_ecn_cnt,         bbr_full_ecn_cnt,         uint, 0664);
 | 
						|
+module_param_named(inflight_headroom,    bbr_inflight_headroom,    uint, 0664);
 | 
						|
+module_param_named(bw_probe_pif_gain,    bbr_bw_probe_pif_gain,    uint, 0664);
 | 
						|
+module_param_named(bw_probe_reno_gain,   bbr_bw_probe_reno_gain,   uint, 0664);
 | 
						|
+module_param_named(bw_probe_max_rounds,  bbr_bw_probe_max_rounds,  uint, 0664);
 | 
						|
+module_param_named(bw_probe_rand_rounds, bbr_bw_probe_rand_rounds, uint, 0664);
 | 
						|
+module_param_named(bw_probe_base_us,     bbr_bw_probe_base_us,     uint, 0664);
 | 
						|
+module_param_named(bw_probe_rand_us,     bbr_bw_probe_rand_us,     uint, 0664);
 | 
						|
+module_param_named(undo,                 bbr_undo,                 bool, 0664);
 | 
						|
+module_param_named(fast_path,		 bbr_fast_path,		   bool, 0664);
 | 
						|
+module_param_named(fast_ack_mode,	 bbr_fast_ack_mode,	   uint, 0664);
 | 
						|
+module_param_named(refill_add_inc,       bbr_refill_add_inc,       uint, 0664);
 | 
						|
+
 | 
						|
+static void bbr2_init(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr_init(sk);	/* run shared init code for v1 and v2 */
 | 
						|
+
 | 
						|
+	/* BBR v2 parameters: */
 | 
						|
+	bbr->params.beta = min_t(u32, 0xFFU, bbr_beta);
 | 
						|
+	bbr->params.ecn_alpha_gain = min_t(u32, 0xFFU, bbr_ecn_alpha_gain);
 | 
						|
+	bbr->params.ecn_alpha_init = min_t(u32, BBR_UNIT, bbr_ecn_alpha_init);
 | 
						|
+	bbr->params.ecn_factor = min_t(u32, 0xFFU, bbr_ecn_factor);
 | 
						|
+	bbr->params.ecn_thresh = min_t(u32, 0xFFU, bbr_ecn_thresh);
 | 
						|
+	bbr->params.ecn_max_rtt_us = min_t(u32, 0x7ffffU, bbr_ecn_max_rtt_us);
 | 
						|
+	bbr->params.ecn_reprobe_gain = min_t(u32, 0x1FF, bbr_ecn_reprobe_gain);
 | 
						|
+	bbr->params.loss_thresh = min_t(u32, 0xFFU, bbr_loss_thresh);
 | 
						|
+	bbr->params.full_loss_cnt = min_t(u32, 0xFU, bbr_full_loss_cnt);
 | 
						|
+	bbr->params.full_ecn_cnt = min_t(u32, 0x3U, bbr_full_ecn_cnt);
 | 
						|
+	bbr->params.inflight_headroom =
 | 
						|
+		min_t(u32, 0xFFU, bbr_inflight_headroom);
 | 
						|
+	bbr->params.bw_probe_pif_gain =
 | 
						|
+		min_t(u32, 0x1FFU, bbr_bw_probe_pif_gain);
 | 
						|
+	bbr->params.bw_probe_reno_gain =
 | 
						|
+		min_t(u32, 0x1FFU, bbr_bw_probe_reno_gain);
 | 
						|
+	bbr->params.bw_probe_max_rounds =
 | 
						|
+		min_t(u32, 0xFFU, bbr_bw_probe_max_rounds);
 | 
						|
+	bbr->params.bw_probe_rand_rounds =
 | 
						|
+		min_t(u32, 0xFU, bbr_bw_probe_rand_rounds);
 | 
						|
+	bbr->params.bw_probe_base_us =
 | 
						|
+		min_t(u32, (1 << 26) - 1, bbr_bw_probe_base_us);
 | 
						|
+	bbr->params.bw_probe_rand_us =
 | 
						|
+		min_t(u32, (1 << 26) - 1, bbr_bw_probe_rand_us);
 | 
						|
+	bbr->params.undo = bbr_undo;
 | 
						|
+	bbr->params.fast_path = bbr_fast_path ? 1 : 0;
 | 
						|
+	bbr->params.refill_add_inc = min_t(u32, 0x3U, bbr_refill_add_inc);
 | 
						|
+
 | 
						|
+	/* BBR v2 state: */
 | 
						|
+	bbr->initialized = 1;
 | 
						|
+	/* Start sampling ECN mark rate after first full flight is ACKed: */
 | 
						|
+	bbr->loss_round_delivered = tp->delivered + 1;
 | 
						|
+	bbr->loss_round_start = 0;
 | 
						|
+	bbr->undo_bw_lo = 0;
 | 
						|
+	bbr->undo_inflight_lo = 0;
 | 
						|
+	bbr->undo_inflight_hi = 0;
 | 
						|
+	bbr->loss_events_in_round = 0;
 | 
						|
+	bbr->startup_ecn_rounds = 0;
 | 
						|
+	bbr2_reset_congestion_signals(sk);
 | 
						|
+	bbr->bw_lo = ~0U;
 | 
						|
+	bbr->bw_hi[0] = 0;
 | 
						|
+	bbr->bw_hi[1] = 0;
 | 
						|
+	bbr->inflight_lo = ~0U;
 | 
						|
+	bbr->inflight_hi = ~0U;
 | 
						|
+	bbr->bw_probe_up_cnt = ~0U;
 | 
						|
+	bbr->bw_probe_up_acks = 0;
 | 
						|
+	bbr->bw_probe_up_rounds = 0;
 | 
						|
+	bbr->probe_wait_us = 0;
 | 
						|
+	bbr->stopped_risky_probe = 0;
 | 
						|
+	bbr->ack_phase = BBR_ACKS_INIT;
 | 
						|
+	bbr->rounds_since_probe = 0;
 | 
						|
+	bbr->bw_probe_samples = 0;
 | 
						|
+	bbr->prev_probe_too_high = 0;
 | 
						|
+	bbr->ecn_eligible = 0;
 | 
						|
+	bbr->ecn_alpha = bbr->params.ecn_alpha_init;
 | 
						|
+	bbr->alpha_last_delivered = 0;
 | 
						|
+	bbr->alpha_last_delivered_ce = 0;
 | 
						|
+
 | 
						|
+	tp->fast_ack_mode = min_t(u32, 0x2U, bbr_fast_ack_mode);
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Core TCP stack informs us that the given skb was just marked lost. */
 | 
						|
+static void bbr2_skb_marked_lost(struct sock *sk, const struct sk_buff *skb)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
 | 
						|
+	struct rate_sample rs;
 | 
						|
+
 | 
						|
+	/* Capture "current" data over the full round trip of loss,
 | 
						|
+	 * to have a better chance to see the full capacity of the path.
 | 
						|
+	*/
 | 
						|
+	if (!bbr->loss_in_round)  /* first loss in this round trip? */
 | 
						|
+		bbr->loss_round_delivered = tp->delivered;  /* set round trip */
 | 
						|
+	bbr->loss_in_round = 1;
 | 
						|
+	bbr->loss_in_cycle = 1;
 | 
						|
+
 | 
						|
+	if (!bbr->bw_probe_samples)
 | 
						|
+		return;  /* not an skb sent while probing for bandwidth */
 | 
						|
+	if (unlikely(!scb->tx.delivered_mstamp))
 | 
						|
+		return;  /* skb was SACKed, reneged, marked lost; ignore it */
 | 
						|
+	/* We are probing for bandwidth. Construct a rate sample that
 | 
						|
+	 * estimates what happened in the flight leading up to this lost skb,
 | 
						|
+	 * then see if the loss rate went too high, and if so at which packet.
 | 
						|
+	 */
 | 
						|
+	memset(&rs, 0, sizeof(rs));
 | 
						|
+	rs.tx_in_flight = scb->tx.in_flight;
 | 
						|
+	rs.lost = tp->lost - scb->tx.lost;
 | 
						|
+	rs.delivered_ce = tp->delivered_ce - scb->tx.delivered_ce;
 | 
						|
+	rs.is_app_limited = scb->tx.is_app_limited;
 | 
						|
+	if (bbr2_is_inflight_too_high(sk, &rs)) {
 | 
						|
+		rs.tx_in_flight = bbr2_inflight_hi_from_lost_skb(sk, &rs, skb);
 | 
						|
+		bbr2_handle_inflight_too_high(sk, &rs);
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Revert short-term model if current loss recovery event was spurious. */
 | 
						|
+static u32 bbr2_undo_cwnd(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr->debug.undo = 1;
 | 
						|
+	bbr->full_bw = 0;   /* spurious slow-down; reset full pipe detection */
 | 
						|
+	bbr->full_bw_cnt = 0;
 | 
						|
+	bbr->loss_in_round = 0;
 | 
						|
+
 | 
						|
+	if (!bbr->params.undo)
 | 
						|
+		return tp->snd_cwnd;
 | 
						|
+
 | 
						|
+	/* Revert to cwnd and other state saved before loss episode. */
 | 
						|
+	bbr->bw_lo = max(bbr->bw_lo, bbr->undo_bw_lo);
 | 
						|
+	bbr->inflight_lo = max(bbr->inflight_lo, bbr->undo_inflight_lo);
 | 
						|
+	bbr->inflight_hi = max(bbr->inflight_hi, bbr->undo_inflight_hi);
 | 
						|
+	return bbr->prior_cwnd;
 | 
						|
+}
 | 
						|
+
 | 
						|
+/* Entering loss recovery, so save state for when we undo recovery. */
 | 
						|
+static u32 bbr2_ssthresh(struct sock *sk)
 | 
						|
+{
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	bbr_save_cwnd(sk);
 | 
						|
+	/* For undo, save state that adapts based on loss signal. */
 | 
						|
+	bbr->undo_bw_lo		= bbr->bw_lo;
 | 
						|
+	bbr->undo_inflight_lo	= bbr->inflight_lo;
 | 
						|
+	bbr->undo_inflight_hi	= bbr->inflight_hi;
 | 
						|
+	return tcp_sk(sk)->snd_ssthresh;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static enum tcp_bbr2_phase bbr2_get_phase(struct bbr *bbr)
 | 
						|
+{
 | 
						|
+	switch (bbr->mode) {
 | 
						|
+	case BBR_STARTUP:
 | 
						|
+		return BBR2_PHASE_STARTUP;
 | 
						|
+	case BBR_DRAIN:
 | 
						|
+		return BBR2_PHASE_DRAIN;
 | 
						|
+	case BBR_PROBE_BW:
 | 
						|
+		break;
 | 
						|
+	case BBR_PROBE_RTT:
 | 
						|
+		return BBR2_PHASE_PROBE_RTT;
 | 
						|
+	default:
 | 
						|
+		return BBR2_PHASE_INVALID;
 | 
						|
+	}
 | 
						|
+	switch (bbr->cycle_idx) {
 | 
						|
+	case BBR_BW_PROBE_UP:
 | 
						|
+		return BBR2_PHASE_PROBE_BW_UP;
 | 
						|
+	case BBR_BW_PROBE_DOWN:
 | 
						|
+		return BBR2_PHASE_PROBE_BW_DOWN;
 | 
						|
+	case BBR_BW_PROBE_CRUISE:
 | 
						|
+		return BBR2_PHASE_PROBE_BW_CRUISE;
 | 
						|
+	case BBR_BW_PROBE_REFILL:
 | 
						|
+		return BBR2_PHASE_PROBE_BW_REFILL;
 | 
						|
+	default:
 | 
						|
+		return BBR2_PHASE_INVALID;
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+static size_t bbr2_get_info(struct sock *sk, u32 ext, int *attr,
 | 
						|
+			    union tcp_cc_info *info)
 | 
						|
+{
 | 
						|
+	if (ext & (1 << (INET_DIAG_BBRINFO - 1)) ||
 | 
						|
+	    ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
 | 
						|
+		struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+		u64 bw = bbr_bw_bytes_per_sec(sk, bbr_bw(sk));
 | 
						|
+		u64 bw_hi = bbr_bw_bytes_per_sec(sk, bbr_max_bw(sk));
 | 
						|
+		u64 bw_lo = bbr->bw_lo == ~0U ?
 | 
						|
+			~0ULL : bbr_bw_bytes_per_sec(sk, bbr->bw_lo);
 | 
						|
+
 | 
						|
+		memset(&info->bbr2, 0, sizeof(info->bbr2));
 | 
						|
+		info->bbr2.bbr_bw_lsb		= (u32)bw;
 | 
						|
+		info->bbr2.bbr_bw_msb		= (u32)(bw >> 32);
 | 
						|
+		info->bbr2.bbr_min_rtt		= bbr->min_rtt_us;
 | 
						|
+		info->bbr2.bbr_pacing_gain	= bbr->pacing_gain;
 | 
						|
+		info->bbr2.bbr_cwnd_gain	= bbr->cwnd_gain;
 | 
						|
+		info->bbr2.bbr_bw_hi_lsb	= (u32)bw_hi;
 | 
						|
+		info->bbr2.bbr_bw_hi_msb	= (u32)(bw_hi >> 32);
 | 
						|
+		info->bbr2.bbr_bw_lo_lsb	= (u32)bw_lo;
 | 
						|
+		info->bbr2.bbr_bw_lo_msb	= (u32)(bw_lo >> 32);
 | 
						|
+		info->bbr2.bbr_mode		= bbr->mode;
 | 
						|
+		info->bbr2.bbr_phase		= (__u8)bbr2_get_phase(bbr);
 | 
						|
+		info->bbr2.bbr_version		= (__u8)2;
 | 
						|
+		info->bbr2.bbr_inflight_lo	= bbr->inflight_lo;
 | 
						|
+		info->bbr2.bbr_inflight_hi	= bbr->inflight_hi;
 | 
						|
+		info->bbr2.bbr_extra_acked	= bbr_extra_acked(sk);
 | 
						|
+		*attr = INET_DIAG_BBRINFO;
 | 
						|
+		return sizeof(info->bbr2);
 | 
						|
+	}
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void bbr2_set_state(struct sock *sk, u8 new_state)
 | 
						|
+{
 | 
						|
+	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
+	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+
 | 
						|
+	if (new_state == TCP_CA_Loss) {
 | 
						|
+		struct rate_sample rs = { .losses = 1 };
 | 
						|
+		struct bbr_context ctx = { 0 };
 | 
						|
+
 | 
						|
+		bbr->prev_ca_state = TCP_CA_Loss;
 | 
						|
+		bbr->full_bw = 0;
 | 
						|
+		if (!bbr2_is_probing_bandwidth(sk) && bbr->inflight_lo == ~0U) {
 | 
						|
+			/* bbr_adapt_lower_bounds() needs cwnd before
 | 
						|
+			 * we suffered an RTO, to update inflight_lo:
 | 
						|
+			 */
 | 
						|
+			WARN_ON_ONCE(bbr->prior_cwnd == 0);
 | 
						|
+			WARN_ON_ONCE(bbr->prior_cwnd == ~0U);
 | 
						|
+			bbr->inflight_lo = bbr->prior_cwnd;
 | 
						|
+		}
 | 
						|
+		bbr_debug(sk, 0, &rs, &ctx);
 | 
						|
+	} else if (bbr->prev_ca_state == TCP_CA_Loss &&
 | 
						|
+		   new_state != TCP_CA_Loss) {
 | 
						|
+		WARN_ON_ONCE(bbr->prior_cwnd == 0);
 | 
						|
+		WARN_ON_ONCE(bbr->prior_cwnd == ~0U);
 | 
						|
+		tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd);
 | 
						|
+		bbr->try_fast_path = 0; /* bound cwnd using latest model */
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
+static struct tcp_congestion_ops tcp_bbr2_cong_ops __read_mostly = {
 | 
						|
+	.flags		= TCP_CONG_NON_RESTRICTED | TCP_CONG_WANTS_CE_EVENTS,
 | 
						|
+	.name		= "bbr2",
 | 
						|
+	.owner		= THIS_MODULE,
 | 
						|
+	.init		= bbr2_init,
 | 
						|
+	.cong_control	= bbr2_main,
 | 
						|
+	.sndbuf_expand	= bbr_sndbuf_expand,
 | 
						|
+	.skb_marked_lost = bbr2_skb_marked_lost,
 | 
						|
+	.undo_cwnd	= bbr2_undo_cwnd,
 | 
						|
+	.cwnd_event	= bbr_cwnd_event,
 | 
						|
+	.ssthresh	= bbr2_ssthresh,
 | 
						|
+	.tso_segs	= bbr_tso_segs,
 | 
						|
+	.get_info	= bbr2_get_info,
 | 
						|
+	.set_state	= bbr2_set_state,
 | 
						|
+};
 | 
						|
+
 | 
						|
+static int __init bbr_register(void)
 | 
						|
+{
 | 
						|
+	BUILD_BUG_ON(sizeof(struct bbr) > ICSK_CA_PRIV_SIZE);
 | 
						|
+	return tcp_register_congestion_control(&tcp_bbr2_cong_ops);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void __exit bbr_unregister(void)
 | 
						|
+{
 | 
						|
+	tcp_unregister_congestion_control(&tcp_bbr2_cong_ops);
 | 
						|
+}
 | 
						|
+
 | 
						|
+module_init(bbr_register);
 | 
						|
+module_exit(bbr_unregister);
 | 
						|
+
 | 
						|
+MODULE_AUTHOR("Van Jacobson <vanj@google.com>");
 | 
						|
+MODULE_AUTHOR("Neal Cardwell <ncardwell@google.com>");
 | 
						|
+MODULE_AUTHOR("Yuchung Cheng <ycheng@google.com>");
 | 
						|
+MODULE_AUTHOR("Soheil Hassas Yeganeh <soheil@google.com>");
 | 
						|
+MODULE_AUTHOR("Priyaranjan Jha <priyarjha@google.com>");
 | 
						|
+MODULE_AUTHOR("Yousuk Seung <ysseung@google.com>");
 | 
						|
+MODULE_AUTHOR("Kevin Yang <yyd@google.com>");
 | 
						|
+MODULE_AUTHOR("Arjun Roy <arjunroy@google.com>");
 | 
						|
+
 | 
						|
+MODULE_LICENSE("Dual BSD/GPL");
 | 
						|
+MODULE_DESCRIPTION("TCP BBR (Bottleneck Bandwidth and RTT)");
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 0a65dddf457f76a09570a284f260eda9eb6504de Mon Sep 17 00:00:00 2001
 | 
						|
From: Soheil Hassas Yeganeh <soheil@google.com>
 | 
						|
Date: Sat, 23 Jan 2016 20:51:41 -0500
 | 
						|
Subject: [PATCH 15/27] net-test: add .config for kernel circa v5.10, with many
 | 
						|
 TCP CC modules enabled
 | 
						|
 | 
						|
This commit provides a kernel config file for GCE. It builds most
 | 
						|
(all?) of the available congestion control modules and uses bbr2 as
 | 
						|
the default.
 | 
						|
 | 
						|
Tested: On GCE.
 | 
						|
Effort: net-test
 | 
						|
Change-Id: Ibc4dfdc119c804f1ad2853b3ee2c1c503bca01a9
 | 
						|
---
 | 
						|
 config.gce | 3807 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 | 
						|
 1 file changed, 3807 insertions(+)
 | 
						|
 create mode 100644 config.gce
 | 
						|
 | 
						|
diff --git a/config.gce b/config.gce
 | 
						|
new file mode 100644
 | 
						|
index 000000000000..1538acf6818b
 | 
						|
--- /dev/null
 | 
						|
+++ b/config.gce
 | 
						|
@@ -0,0 +1,3807 @@
 | 
						|
+#
 | 
						|
+# Automatically generated file; DO NOT EDIT.
 | 
						|
+# Linux/x86 4.8.0 Kernel Configuration
 | 
						|
+#
 | 
						|
+CONFIG_64BIT=y
 | 
						|
+CONFIG_X86_64=y
 | 
						|
+CONFIG_X86=y
 | 
						|
+CONFIG_INSTRUCTION_DECODER=y
 | 
						|
+CONFIG_OUTPUT_FORMAT="elf64-x86-64"
 | 
						|
+CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
 | 
						|
+CONFIG_LOCKDEP_SUPPORT=y
 | 
						|
+CONFIG_STACKTRACE_SUPPORT=y
 | 
						|
+CONFIG_MMU=y
 | 
						|
+CONFIG_ARCH_MMAP_RND_BITS_MIN=28
 | 
						|
+CONFIG_ARCH_MMAP_RND_BITS_MAX=32
 | 
						|
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
 | 
						|
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
 | 
						|
+CONFIG_NEED_DMA_MAP_STATE=y
 | 
						|
+CONFIG_NEED_SG_DMA_LENGTH=y
 | 
						|
+CONFIG_GENERIC_BUG=y
 | 
						|
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
 | 
						|
+CONFIG_GENERIC_HWEIGHT=y
 | 
						|
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 | 
						|
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 | 
						|
+CONFIG_ARCH_HAS_CPU_RELAX=y
 | 
						|
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
 | 
						|
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
 | 
						|
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
 | 
						|
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
 | 
						|
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 | 
						|
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 | 
						|
+CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
 | 
						|
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
 | 
						|
+CONFIG_ZONE_DMA32=y
 | 
						|
+CONFIG_AUDIT_ARCH=y
 | 
						|
+CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
 | 
						|
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 | 
						|
+CONFIG_HAVE_INTEL_TXT=y
 | 
						|
+CONFIG_X86_64_SMP=y
 | 
						|
+CONFIG_ARCH_SUPPORTS_UPROBES=y
 | 
						|
+CONFIG_FIX_EARLYCON_MEM=y
 | 
						|
+CONFIG_DEBUG_RODATA=y
 | 
						|
+CONFIG_PGTABLE_LEVELS=4
 | 
						|
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 | 
						|
+CONFIG_IRQ_WORK=y
 | 
						|
+CONFIG_BUILDTIME_EXTABLE_SORT=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# General setup
 | 
						|
+#
 | 
						|
+CONFIG_INIT_ENV_ARG_LIMIT=32
 | 
						|
+CONFIG_CROSS_COMPILE=""
 | 
						|
+# CONFIG_COMPILE_TEST is not set
 | 
						|
+CONFIG_LOCALVERSION=""
 | 
						|
+# CONFIG_LOCALVERSION_AUTO is not set
 | 
						|
+CONFIG_HAVE_KERNEL_GZIP=y
 | 
						|
+CONFIG_HAVE_KERNEL_BZIP2=y
 | 
						|
+CONFIG_HAVE_KERNEL_LZMA=y
 | 
						|
+CONFIG_HAVE_KERNEL_XZ=y
 | 
						|
+CONFIG_HAVE_KERNEL_LZO=y
 | 
						|
+CONFIG_HAVE_KERNEL_LZ4=y
 | 
						|
+# CONFIG_KERNEL_GZIP is not set
 | 
						|
+# CONFIG_KERNEL_BZIP2 is not set
 | 
						|
+CONFIG_KERNEL_LZMA=y
 | 
						|
+# CONFIG_KERNEL_XZ is not set
 | 
						|
+# CONFIG_KERNEL_LZO is not set
 | 
						|
+# CONFIG_KERNEL_LZ4 is not set
 | 
						|
+CONFIG_DEFAULT_HOSTNAME="(none)"
 | 
						|
+CONFIG_SWAP=y
 | 
						|
+CONFIG_SYSVIPC=y
 | 
						|
+CONFIG_SYSVIPC_SYSCTL=y
 | 
						|
+CONFIG_POSIX_MQUEUE=y
 | 
						|
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 | 
						|
+CONFIG_CROSS_MEMORY_ATTACH=y
 | 
						|
+CONFIG_FHANDLE=y
 | 
						|
+CONFIG_USELIB=y
 | 
						|
+CONFIG_AUDIT=y
 | 
						|
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
 | 
						|
+CONFIG_AUDITSYSCALL=y
 | 
						|
+CONFIG_AUDIT_WATCH=y
 | 
						|
+CONFIG_AUDIT_TREE=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# IRQ subsystem
 | 
						|
+#
 | 
						|
+CONFIG_GENERIC_IRQ_PROBE=y
 | 
						|
+CONFIG_GENERIC_IRQ_SHOW=y
 | 
						|
+CONFIG_GENERIC_PENDING_IRQ=y
 | 
						|
+CONFIG_IRQ_DOMAIN=y
 | 
						|
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
 | 
						|
+CONFIG_GENERIC_MSI_IRQ=y
 | 
						|
+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
 | 
						|
+# CONFIG_IRQ_DOMAIN_DEBUG is not set
 | 
						|
+CONFIG_IRQ_FORCED_THREADING=y
 | 
						|
+CONFIG_SPARSE_IRQ=y
 | 
						|
+CONFIG_CLOCKSOURCE_WATCHDOG=y
 | 
						|
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
 | 
						|
+CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
 | 
						|
+CONFIG_GENERIC_TIME_VSYSCALL=y
 | 
						|
+CONFIG_GENERIC_CLOCKEVENTS=y
 | 
						|
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
 | 
						|
+CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
 | 
						|
+CONFIG_GENERIC_CMOS_UPDATE=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Timers subsystem
 | 
						|
+#
 | 
						|
+CONFIG_TICK_ONESHOT=y
 | 
						|
+CONFIG_NO_HZ_COMMON=y
 | 
						|
+# CONFIG_HZ_PERIODIC is not set
 | 
						|
+CONFIG_NO_HZ_IDLE=y
 | 
						|
+# CONFIG_NO_HZ_FULL is not set
 | 
						|
+CONFIG_NO_HZ=y
 | 
						|
+CONFIG_HIGH_RES_TIMERS=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# CPU/Task time and stats accounting
 | 
						|
+#
 | 
						|
+CONFIG_TICK_CPU_ACCOUNTING=y
 | 
						|
+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
 | 
						|
+CONFIG_IRQ_TIME_ACCOUNTING=y
 | 
						|
+CONFIG_BSD_PROCESS_ACCT=y
 | 
						|
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
 | 
						|
+CONFIG_TASKSTATS=y
 | 
						|
+CONFIG_TASK_DELAY_ACCT=y
 | 
						|
+CONFIG_TASK_XACCT=y
 | 
						|
+CONFIG_TASK_IO_ACCOUNTING=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# RCU Subsystem
 | 
						|
+#
 | 
						|
+CONFIG_TREE_RCU=y
 | 
						|
+# CONFIG_RCU_EXPERT is not set
 | 
						|
+CONFIG_SRCU=y
 | 
						|
+# CONFIG_TASKS_RCU is not set
 | 
						|
+CONFIG_RCU_STALL_COMMON=y
 | 
						|
+# CONFIG_TREE_RCU_TRACE is not set
 | 
						|
+# CONFIG_RCU_EXPEDITE_BOOT is not set
 | 
						|
+CONFIG_BUILD_BIN2C=y
 | 
						|
+CONFIG_IKCONFIG=y
 | 
						|
+CONFIG_IKCONFIG_PROC=y
 | 
						|
+CONFIG_LOG_BUF_SHIFT=20
 | 
						|
+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
 | 
						|
+CONFIG_NMI_LOG_BUF_SHIFT=13
 | 
						|
+CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
 | 
						|
+CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
 | 
						|
+CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y
 | 
						|
+CONFIG_ARCH_SUPPORTS_INT128=y
 | 
						|
+# CONFIG_NUMA_BALANCING is not set
 | 
						|
+CONFIG_CGROUPS=y
 | 
						|
+CONFIG_PAGE_COUNTER=y
 | 
						|
+CONFIG_MEMCG=y
 | 
						|
+# CONFIG_MEMCG_SWAP is not set
 | 
						|
+CONFIG_BLK_CGROUP=y
 | 
						|
+CONFIG_DEBUG_BLK_CGROUP=y
 | 
						|
+CONFIG_CGROUP_WRITEBACK=y
 | 
						|
+CONFIG_CGROUP_SCHED=y
 | 
						|
+CONFIG_FAIR_GROUP_SCHED=y
 | 
						|
+CONFIG_CFS_BANDWIDTH=y
 | 
						|
+# CONFIG_RT_GROUP_SCHED is not set
 | 
						|
+# CONFIG_CGROUP_PIDS is not set
 | 
						|
+CONFIG_CGROUP_FREEZER=y
 | 
						|
+CONFIG_CGROUP_HUGETLB=y
 | 
						|
+CONFIG_CPUSETS=y
 | 
						|
+CONFIG_PROC_PID_CPUSET=y
 | 
						|
+CONFIG_CGROUP_DEVICE=y
 | 
						|
+CONFIG_CGROUP_CPUACCT=y
 | 
						|
+CONFIG_CGROUP_PERF=y
 | 
						|
+# CONFIG_CGROUP_DEBUG is not set
 | 
						|
+CONFIG_CHECKPOINT_RESTORE=y
 | 
						|
+CONFIG_NAMESPACES=y
 | 
						|
+CONFIG_UTS_NS=y
 | 
						|
+CONFIG_IPC_NS=y
 | 
						|
+CONFIG_USER_NS=y
 | 
						|
+CONFIG_PID_NS=y
 | 
						|
+CONFIG_NET_NS=y
 | 
						|
+# CONFIG_SCHED_AUTOGROUP is not set
 | 
						|
+# CONFIG_SYSFS_DEPRECATED is not set
 | 
						|
+CONFIG_RELAY=y
 | 
						|
+CONFIG_BLK_DEV_INITRD=y
 | 
						|
+CONFIG_INITRAMFS_SOURCE=""
 | 
						|
+CONFIG_RD_GZIP=y
 | 
						|
+CONFIG_RD_BZIP2=y
 | 
						|
+CONFIG_RD_LZMA=y
 | 
						|
+CONFIG_RD_XZ=y
 | 
						|
+CONFIG_RD_LZO=y
 | 
						|
+CONFIG_RD_LZ4=y
 | 
						|
+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
 | 
						|
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 | 
						|
+CONFIG_SYSCTL=y
 | 
						|
+CONFIG_ANON_INODES=y
 | 
						|
+CONFIG_HAVE_UID16=y
 | 
						|
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
 | 
						|
+CONFIG_HAVE_PCSPKR_PLATFORM=y
 | 
						|
+CONFIG_BPF=y
 | 
						|
+CONFIG_EXPERT=y
 | 
						|
+CONFIG_UID16=y
 | 
						|
+CONFIG_MULTIUSER=y
 | 
						|
+CONFIG_SGETMASK_SYSCALL=y
 | 
						|
+CONFIG_SYSFS_SYSCALL=y
 | 
						|
+# CONFIG_SYSCTL_SYSCALL is not set
 | 
						|
+CONFIG_KALLSYMS=y
 | 
						|
+CONFIG_KALLSYMS_ALL=y
 | 
						|
+CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y
 | 
						|
+CONFIG_KALLSYMS_BASE_RELATIVE=y
 | 
						|
+CONFIG_PRINTK=y
 | 
						|
+CONFIG_PRINTK_NMI=y
 | 
						|
+CONFIG_BUG=y
 | 
						|
+CONFIG_ELF_CORE=y
 | 
						|
+CONFIG_PCSPKR_PLATFORM=y
 | 
						|
+CONFIG_BASE_FULL=y
 | 
						|
+CONFIG_FUTEX=y
 | 
						|
+CONFIG_EPOLL=y
 | 
						|
+CONFIG_SIGNALFD=y
 | 
						|
+CONFIG_TIMERFD=y
 | 
						|
+CONFIG_EVENTFD=y
 | 
						|
+CONFIG_BPF_SYSCALL=y
 | 
						|
+CONFIG_SHMEM=y
 | 
						|
+CONFIG_AIO=y
 | 
						|
+CONFIG_ADVISE_SYSCALLS=y
 | 
						|
+# CONFIG_USERFAULTFD is not set
 | 
						|
+CONFIG_PCI_QUIRKS=y
 | 
						|
+CONFIG_MEMBARRIER=y
 | 
						|
+# CONFIG_EMBEDDED is not set
 | 
						|
+CONFIG_HAVE_PERF_EVENTS=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Kernel Performance Events And Counters
 | 
						|
+#
 | 
						|
+CONFIG_PERF_EVENTS=y
 | 
						|
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 | 
						|
+CONFIG_VM_EVENT_COUNTERS=y
 | 
						|
+# CONFIG_COMPAT_BRK is not set
 | 
						|
+CONFIG_SLAB=y
 | 
						|
+# CONFIG_SLUB is not set
 | 
						|
+# CONFIG_SLOB is not set
 | 
						|
+# CONFIG_SLAB_FREELIST_RANDOM is not set
 | 
						|
+# CONFIG_SYSTEM_DATA_VERIFICATION is not set
 | 
						|
+CONFIG_PROFILING=y
 | 
						|
+CONFIG_TRACEPOINTS=y
 | 
						|
+CONFIG_KEXEC_CORE=y
 | 
						|
+# CONFIG_OPROFILE is not set
 | 
						|
+CONFIG_HAVE_OPROFILE=y
 | 
						|
+CONFIG_OPROFILE_NMI_TIMER=y
 | 
						|
+CONFIG_KPROBES=y
 | 
						|
+CONFIG_JUMP_LABEL=y
 | 
						|
+# CONFIG_STATIC_KEYS_SELFTEST is not set
 | 
						|
+CONFIG_OPTPROBES=y
 | 
						|
+CONFIG_KPROBES_ON_FTRACE=y
 | 
						|
+# CONFIG_UPROBES is not set
 | 
						|
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
 | 
						|
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 | 
						|
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
 | 
						|
+CONFIG_KRETPROBES=y
 | 
						|
+CONFIG_USER_RETURN_NOTIFIER=y
 | 
						|
+CONFIG_HAVE_IOREMAP_PROT=y
 | 
						|
+CONFIG_HAVE_KPROBES=y
 | 
						|
+CONFIG_HAVE_KRETPROBES=y
 | 
						|
+CONFIG_HAVE_OPTPROBES=y
 | 
						|
+CONFIG_HAVE_KPROBES_ON_FTRACE=y
 | 
						|
+CONFIG_HAVE_NMI=y
 | 
						|
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 | 
						|
+CONFIG_HAVE_DMA_CONTIGUOUS=y
 | 
						|
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
 | 
						|
+CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y
 | 
						|
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
 | 
						|
+CONFIG_HAVE_DMA_API_DEBUG=y
 | 
						|
+CONFIG_HAVE_HW_BREAKPOINT=y
 | 
						|
+CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
 | 
						|
+CONFIG_HAVE_USER_RETURN_NOTIFIER=y
 | 
						|
+CONFIG_HAVE_PERF_EVENTS_NMI=y
 | 
						|
+CONFIG_HAVE_PERF_REGS=y
 | 
						|
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
 | 
						|
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
 | 
						|
+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
 | 
						|
+CONFIG_HAVE_CMPXCHG_LOCAL=y
 | 
						|
+CONFIG_HAVE_CMPXCHG_DOUBLE=y
 | 
						|
+CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
 | 
						|
+CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y
 | 
						|
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
 | 
						|
+CONFIG_SECCOMP_FILTER=y
 | 
						|
+CONFIG_HAVE_GCC_PLUGINS=y
 | 
						|
+# CONFIG_GCC_PLUGINS is not set
 | 
						|
+CONFIG_HAVE_CC_STACKPROTECTOR=y
 | 
						|
+# CONFIG_CC_STACKPROTECTOR is not set
 | 
						|
+CONFIG_CC_STACKPROTECTOR_NONE=y
 | 
						|
+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
 | 
						|
+# CONFIG_CC_STACKPROTECTOR_STRONG is not set
 | 
						|
+CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
 | 
						|
+CONFIG_HAVE_CONTEXT_TRACKING=y
 | 
						|
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
 | 
						|
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
 | 
						|
+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
 | 
						|
+CONFIG_HAVE_ARCH_HUGE_VMAP=y
 | 
						|
+CONFIG_HAVE_ARCH_SOFT_DIRTY=y
 | 
						|
+CONFIG_MODULES_USE_ELF_RELA=y
 | 
						|
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
 | 
						|
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
 | 
						|
+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
 | 
						|
+CONFIG_HAVE_EXIT_THREAD=y
 | 
						|
+CONFIG_ARCH_MMAP_RND_BITS=28
 | 
						|
+CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y
 | 
						|
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=8
 | 
						|
+CONFIG_HAVE_COPY_THREAD_TLS=y
 | 
						|
+CONFIG_HAVE_STACK_VALIDATION=y
 | 
						|
+# CONFIG_HAVE_ARCH_HASH is not set
 | 
						|
+# CONFIG_ISA_BUS_API is not set
 | 
						|
+CONFIG_OLD_SIGSUSPEND3=y
 | 
						|
+CONFIG_COMPAT_OLD_SIGACTION=y
 | 
						|
+# CONFIG_CPU_NO_EFFICIENT_FFS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# GCOV-based kernel profiling
 | 
						|
+#
 | 
						|
+# CONFIG_GCOV_KERNEL is not set
 | 
						|
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
 | 
						|
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 | 
						|
+CONFIG_SLABINFO=y
 | 
						|
+CONFIG_RT_MUTEXES=y
 | 
						|
+CONFIG_BASE_SMALL=0
 | 
						|
+CONFIG_MODULES=y
 | 
						|
+# CONFIG_MODULE_FORCE_LOAD is not set
 | 
						|
+CONFIG_MODULE_UNLOAD=y
 | 
						|
+CONFIG_MODULE_FORCE_UNLOAD=y
 | 
						|
+CONFIG_MODVERSIONS=y
 | 
						|
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 | 
						|
+# CONFIG_MODULE_SIG is not set
 | 
						|
+# CONFIG_MODULE_COMPRESS is not set
 | 
						|
+# CONFIG_TRIM_UNUSED_KSYMS is not set
 | 
						|
+CONFIG_MODULES_TREE_LOOKUP=y
 | 
						|
+CONFIG_BLOCK=y
 | 
						|
+CONFIG_BLK_DEV_BSG=y
 | 
						|
+CONFIG_BLK_DEV_BSGLIB=y
 | 
						|
+# CONFIG_BLK_DEV_INTEGRITY is not set
 | 
						|
+# CONFIG_BLK_DEV_THROTTLING is not set
 | 
						|
+# CONFIG_BLK_CMDLINE_PARSER is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Partition Types
 | 
						|
+#
 | 
						|
+CONFIG_PARTITION_ADVANCED=y
 | 
						|
+# CONFIG_ACORN_PARTITION is not set
 | 
						|
+# CONFIG_AIX_PARTITION is not set
 | 
						|
+# CONFIG_OSF_PARTITION is not set
 | 
						|
+# CONFIG_AMIGA_PARTITION is not set
 | 
						|
+# CONFIG_ATARI_PARTITION is not set
 | 
						|
+# CONFIG_MAC_PARTITION is not set
 | 
						|
+CONFIG_MSDOS_PARTITION=y
 | 
						|
+# CONFIG_BSD_DISKLABEL is not set
 | 
						|
+# CONFIG_MINIX_SUBPARTITION is not set
 | 
						|
+# CONFIG_SOLARIS_X86_PARTITION is not set
 | 
						|
+# CONFIG_UNIXWARE_DISKLABEL is not set
 | 
						|
+# CONFIG_LDM_PARTITION is not set
 | 
						|
+# CONFIG_SGI_PARTITION is not set
 | 
						|
+# CONFIG_ULTRIX_PARTITION is not set
 | 
						|
+# CONFIG_SUN_PARTITION is not set
 | 
						|
+# CONFIG_KARMA_PARTITION is not set
 | 
						|
+CONFIG_EFI_PARTITION=y
 | 
						|
+# CONFIG_SYSV68_PARTITION is not set
 | 
						|
+# CONFIG_CMDLINE_PARTITION is not set
 | 
						|
+CONFIG_BLOCK_COMPAT=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# IO Schedulers
 | 
						|
+#
 | 
						|
+CONFIG_IOSCHED_NOOP=y
 | 
						|
+CONFIG_IOSCHED_DEADLINE=y
 | 
						|
+CONFIG_IOSCHED_CFQ=y
 | 
						|
+# CONFIG_CFQ_GROUP_IOSCHED is not set
 | 
						|
+# CONFIG_DEFAULT_DEADLINE is not set
 | 
						|
+CONFIG_DEFAULT_CFQ=y
 | 
						|
+# CONFIG_DEFAULT_NOOP is not set
 | 
						|
+CONFIG_DEFAULT_IOSCHED="cfq"
 | 
						|
+CONFIG_PREEMPT_NOTIFIERS=y
 | 
						|
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
 | 
						|
+CONFIG_INLINE_READ_UNLOCK=y
 | 
						|
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
 | 
						|
+CONFIG_INLINE_WRITE_UNLOCK=y
 | 
						|
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
 | 
						|
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
 | 
						|
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 | 
						|
+CONFIG_RWSEM_SPIN_ON_OWNER=y
 | 
						|
+CONFIG_LOCK_SPIN_ON_OWNER=y
 | 
						|
+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
 | 
						|
+CONFIG_QUEUED_SPINLOCKS=y
 | 
						|
+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
 | 
						|
+CONFIG_QUEUED_RWLOCKS=y
 | 
						|
+CONFIG_FREEZER=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Processor type and features
 | 
						|
+#
 | 
						|
+# CONFIG_ZONE_DMA is not set
 | 
						|
+CONFIG_SMP=y
 | 
						|
+CONFIG_X86_FEATURE_NAMES=y
 | 
						|
+CONFIG_X86_FAST_FEATURE_TESTS=y
 | 
						|
+CONFIG_X86_X2APIC=y
 | 
						|
+CONFIG_X86_MPPARSE=y
 | 
						|
+# CONFIG_GOLDFISH is not set
 | 
						|
+CONFIG_X86_EXTENDED_PLATFORM=y
 | 
						|
+# CONFIG_X86_NUMACHIP is not set
 | 
						|
+# CONFIG_X86_VSMP is not set
 | 
						|
+# CONFIG_X86_UV is not set
 | 
						|
+# CONFIG_X86_GOLDFISH is not set
 | 
						|
+# CONFIG_X86_INTEL_MID is not set
 | 
						|
+# CONFIG_X86_INTEL_LPSS is not set
 | 
						|
+# CONFIG_X86_AMD_PLATFORM_DEVICE is not set
 | 
						|
+# CONFIG_IOSF_MBI is not set
 | 
						|
+CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
 | 
						|
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 | 
						|
+CONFIG_HYPERVISOR_GUEST=y
 | 
						|
+CONFIG_PARAVIRT=y
 | 
						|
+# CONFIG_PARAVIRT_DEBUG is not set
 | 
						|
+# CONFIG_PARAVIRT_SPINLOCKS is not set
 | 
						|
+# CONFIG_XEN is not set
 | 
						|
+CONFIG_KVM_GUEST=y
 | 
						|
+# CONFIG_KVM_DEBUG_FS is not set
 | 
						|
+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
 | 
						|
+CONFIG_PARAVIRT_CLOCK=y
 | 
						|
+CONFIG_NO_BOOTMEM=y
 | 
						|
+# CONFIG_MK8 is not set
 | 
						|
+# CONFIG_MPSC is not set
 | 
						|
+# CONFIG_MCORE2 is not set
 | 
						|
+# CONFIG_MATOM is not set
 | 
						|
+CONFIG_GENERIC_CPU=y
 | 
						|
+CONFIG_X86_INTERNODE_CACHE_SHIFT=6
 | 
						|
+CONFIG_X86_L1_CACHE_SHIFT=6
 | 
						|
+CONFIG_X86_TSC=y
 | 
						|
+CONFIG_X86_CMPXCHG64=y
 | 
						|
+CONFIG_X86_CMOV=y
 | 
						|
+CONFIG_X86_MINIMUM_CPU_FAMILY=64
 | 
						|
+CONFIG_X86_DEBUGCTLMSR=y
 | 
						|
+# CONFIG_PROCESSOR_SELECT is not set
 | 
						|
+CONFIG_CPU_SUP_INTEL=y
 | 
						|
+CONFIG_CPU_SUP_AMD=y
 | 
						|
+CONFIG_CPU_SUP_CENTAUR=y
 | 
						|
+CONFIG_HPET_TIMER=y
 | 
						|
+CONFIG_DMI=y
 | 
						|
+# CONFIG_GART_IOMMU is not set
 | 
						|
+# CONFIG_CALGARY_IOMMU is not set
 | 
						|
+CONFIG_SWIOTLB=y
 | 
						|
+CONFIG_IOMMU_HELPER=y
 | 
						|
+# CONFIG_MAXSMP is not set
 | 
						|
+CONFIG_NR_CPUS=96
 | 
						|
+CONFIG_SCHED_SMT=y
 | 
						|
+CONFIG_SCHED_MC=y
 | 
						|
+CONFIG_PREEMPT_NONE=y
 | 
						|
+# CONFIG_PREEMPT_VOLUNTARY is not set
 | 
						|
+# CONFIG_PREEMPT is not set
 | 
						|
+CONFIG_X86_LOCAL_APIC=y
 | 
						|
+CONFIG_X86_IO_APIC=y
 | 
						|
+CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
 | 
						|
+CONFIG_X86_MCE=y
 | 
						|
+CONFIG_X86_MCE_INTEL=y
 | 
						|
+CONFIG_X86_MCE_AMD=y
 | 
						|
+CONFIG_X86_MCE_THRESHOLD=y
 | 
						|
+CONFIG_X86_MCE_INJECT=m
 | 
						|
+CONFIG_X86_THERMAL_VECTOR=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Performance monitoring
 | 
						|
+#
 | 
						|
+CONFIG_PERF_EVENTS_INTEL_UNCORE=y
 | 
						|
+CONFIG_PERF_EVENTS_INTEL_RAPL=y
 | 
						|
+CONFIG_PERF_EVENTS_INTEL_CSTATE=y
 | 
						|
+# CONFIG_PERF_EVENTS_AMD_POWER is not set
 | 
						|
+# CONFIG_VM86 is not set
 | 
						|
+CONFIG_X86_16BIT=y
 | 
						|
+CONFIG_X86_ESPFIX64=y
 | 
						|
+CONFIG_X86_VSYSCALL_EMULATION=y
 | 
						|
+# CONFIG_I8K is not set
 | 
						|
+CONFIG_MICROCODE=y
 | 
						|
+CONFIG_MICROCODE_INTEL=y
 | 
						|
+CONFIG_MICROCODE_AMD=y
 | 
						|
+CONFIG_MICROCODE_OLD_INTERFACE=y
 | 
						|
+CONFIG_X86_MSR=m
 | 
						|
+CONFIG_X86_CPUID=m
 | 
						|
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 | 
						|
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
 | 
						|
+CONFIG_X86_DIRECT_GBPAGES=y
 | 
						|
+CONFIG_NUMA=y
 | 
						|
+CONFIG_AMD_NUMA=y
 | 
						|
+CONFIG_X86_64_ACPI_NUMA=y
 | 
						|
+CONFIG_NODES_SPAN_OTHER_NODES=y
 | 
						|
+# CONFIG_NUMA_EMU is not set
 | 
						|
+CONFIG_NODES_SHIFT=2
 | 
						|
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
 | 
						|
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 | 
						|
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 | 
						|
+CONFIG_ARCH_PROC_KCORE_TEXT=y
 | 
						|
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
 | 
						|
+CONFIG_SELECT_MEMORY_MODEL=y
 | 
						|
+CONFIG_SPARSEMEM_MANUAL=y
 | 
						|
+CONFIG_SPARSEMEM=y
 | 
						|
+CONFIG_NEED_MULTIPLE_NODES=y
 | 
						|
+CONFIG_HAVE_MEMORY_PRESENT=y
 | 
						|
+CONFIG_SPARSEMEM_EXTREME=y
 | 
						|
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 | 
						|
+CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
 | 
						|
+CONFIG_SPARSEMEM_VMEMMAP=y
 | 
						|
+CONFIG_HAVE_MEMBLOCK=y
 | 
						|
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
 | 
						|
+CONFIG_ARCH_DISCARD_MEMBLOCK=y
 | 
						|
+# CONFIG_MOVABLE_NODE is not set
 | 
						|
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
 | 
						|
+# CONFIG_MEMORY_HOTPLUG is not set
 | 
						|
+CONFIG_SPLIT_PTLOCK_CPUS=4
 | 
						|
+CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
 | 
						|
+CONFIG_COMPACTION=y
 | 
						|
+CONFIG_MIGRATION=y
 | 
						|
+CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y
 | 
						|
+CONFIG_PHYS_ADDR_T_64BIT=y
 | 
						|
+CONFIG_VIRT_TO_BUS=y
 | 
						|
+CONFIG_MMU_NOTIFIER=y
 | 
						|
+# CONFIG_KSM is not set
 | 
						|
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
 | 
						|
+CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
 | 
						|
+# CONFIG_MEMORY_FAILURE is not set
 | 
						|
+CONFIG_TRANSPARENT_HUGEPAGE=y
 | 
						|
+CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
 | 
						|
+# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set
 | 
						|
+CONFIG_TRANSPARENT_HUGE_PAGECACHE=y
 | 
						|
+# CONFIG_CLEANCACHE is not set
 | 
						|
+CONFIG_FRONTSWAP=y
 | 
						|
+# CONFIG_CMA is not set
 | 
						|
+CONFIG_MEM_SOFT_DIRTY=y
 | 
						|
+CONFIG_ZSWAP=y
 | 
						|
+CONFIG_ZPOOL=y
 | 
						|
+# CONFIG_ZBUD is not set
 | 
						|
+# CONFIG_Z3FOLD is not set
 | 
						|
+# CONFIG_ZSMALLOC is not set
 | 
						|
+CONFIG_GENERIC_EARLY_IOREMAP=y
 | 
						|
+CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y
 | 
						|
+# CONFIG_IDLE_PAGE_TRACKING is not set
 | 
						|
+CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
 | 
						|
+CONFIG_ARCH_HAS_PKEYS=y
 | 
						|
+# CONFIG_X86_PMEM_LEGACY is not set
 | 
						|
+# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
 | 
						|
+CONFIG_X86_RESERVE_LOW=64
 | 
						|
+CONFIG_MTRR=y
 | 
						|
+# CONFIG_MTRR_SANITIZER is not set
 | 
						|
+CONFIG_X86_PAT=y
 | 
						|
+CONFIG_ARCH_USES_PG_UNCACHED=y
 | 
						|
+CONFIG_ARCH_RANDOM=y
 | 
						|
+CONFIG_X86_SMAP=y
 | 
						|
+# CONFIG_X86_INTEL_MPX is not set
 | 
						|
+CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y
 | 
						|
+CONFIG_EFI=y
 | 
						|
+CONFIG_EFI_STUB=y
 | 
						|
+CONFIG_SECCOMP=y
 | 
						|
+# CONFIG_HZ_100 is not set
 | 
						|
+# CONFIG_HZ_250 is not set
 | 
						|
+# CONFIG_HZ_300 is not set
 | 
						|
+CONFIG_HZ_1000=y
 | 
						|
+CONFIG_HZ=1000
 | 
						|
+CONFIG_SCHED_HRTICK=y
 | 
						|
+CONFIG_KEXEC=y
 | 
						|
+# CONFIG_KEXEC_FILE is not set
 | 
						|
+CONFIG_CRASH_DUMP=y
 | 
						|
+CONFIG_PHYSICAL_START=0x1000000
 | 
						|
+CONFIG_RELOCATABLE=y
 | 
						|
+# CONFIG_RANDOMIZE_BASE is not set
 | 
						|
+CONFIG_PHYSICAL_ALIGN=0x200000
 | 
						|
+CONFIG_HOTPLUG_CPU=y
 | 
						|
+# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set
 | 
						|
+# CONFIG_DEBUG_HOTPLUG_CPU0 is not set
 | 
						|
+# CONFIG_COMPAT_VDSO is not set
 | 
						|
+# CONFIG_LEGACY_VSYSCALL_NATIVE is not set
 | 
						|
+CONFIG_LEGACY_VSYSCALL_EMULATE=y
 | 
						|
+# CONFIG_LEGACY_VSYSCALL_NONE is not set
 | 
						|
+CONFIG_CMDLINE_BOOL=y
 | 
						|
+CONFIG_CMDLINE="oops=panic panic=10 io_delay=0xed libata.allow_tpm=1 nmi_watchdog=panic tco_start=1 quiet svm.nested=0 acpi_enforce_resources=lax"
 | 
						|
+# CONFIG_CMDLINE_OVERRIDE is not set
 | 
						|
+CONFIG_MODIFY_LDT_SYSCALL=y
 | 
						|
+CONFIG_HAVE_LIVEPATCH=y
 | 
						|
+# CONFIG_LIVEPATCH is not set
 | 
						|
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 | 
						|
+CONFIG_USE_PERCPU_NUMA_NODE_ID=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Power management and ACPI options
 | 
						|
+#
 | 
						|
+CONFIG_SUSPEND=y
 | 
						|
+CONFIG_SUSPEND_FREEZER=y
 | 
						|
+# CONFIG_SUSPEND_SKIP_SYNC is not set
 | 
						|
+# CONFIG_HIBERNATION is not set
 | 
						|
+CONFIG_PM_SLEEP=y
 | 
						|
+CONFIG_PM_SLEEP_SMP=y
 | 
						|
+# CONFIG_PM_AUTOSLEEP is not set
 | 
						|
+# CONFIG_PM_WAKELOCKS is not set
 | 
						|
+CONFIG_PM=y
 | 
						|
+CONFIG_PM_DEBUG=y
 | 
						|
+# CONFIG_PM_ADVANCED_DEBUG is not set
 | 
						|
+CONFIG_PM_SLEEP_DEBUG=y
 | 
						|
+CONFIG_PM_TRACE=y
 | 
						|
+CONFIG_PM_TRACE_RTC=y
 | 
						|
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
 | 
						|
+CONFIG_ACPI=y
 | 
						|
+CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y
 | 
						|
+CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y
 | 
						|
+CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y
 | 
						|
+# CONFIG_ACPI_DEBUGGER is not set
 | 
						|
+CONFIG_ACPI_SLEEP=y
 | 
						|
+# CONFIG_ACPI_PROCFS_POWER is not set
 | 
						|
+CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y
 | 
						|
+# CONFIG_ACPI_EC_DEBUGFS is not set
 | 
						|
+CONFIG_ACPI_AC=y
 | 
						|
+CONFIG_ACPI_BATTERY=y
 | 
						|
+CONFIG_ACPI_BUTTON=y
 | 
						|
+CONFIG_ACPI_FAN=y
 | 
						|
+# CONFIG_ACPI_DOCK is not set
 | 
						|
+CONFIG_ACPI_CPU_FREQ_PSS=y
 | 
						|
+CONFIG_ACPI_PROCESSOR_CSTATE=y
 | 
						|
+CONFIG_ACPI_PROCESSOR_IDLE=y
 | 
						|
+CONFIG_ACPI_PROCESSOR=m
 | 
						|
+# CONFIG_ACPI_IPMI is not set
 | 
						|
+CONFIG_ACPI_HOTPLUG_CPU=y
 | 
						|
+# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set
 | 
						|
+CONFIG_ACPI_THERMAL=m
 | 
						|
+CONFIG_ACPI_NUMA=y
 | 
						|
+# CONFIG_ACPI_CUSTOM_DSDT is not set
 | 
						|
+CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y
 | 
						|
+CONFIG_ACPI_TABLE_UPGRADE=y
 | 
						|
+# CONFIG_ACPI_DEBUG is not set
 | 
						|
+# CONFIG_ACPI_PCI_SLOT is not set
 | 
						|
+CONFIG_X86_PM_TIMER=y
 | 
						|
+CONFIG_ACPI_CONTAINER=y
 | 
						|
+CONFIG_ACPI_HOTPLUG_IOAPIC=y
 | 
						|
+# CONFIG_ACPI_SBS is not set
 | 
						|
+# CONFIG_ACPI_HED is not set
 | 
						|
+# CONFIG_ACPI_CUSTOM_METHOD is not set
 | 
						|
+# CONFIG_ACPI_BGRT is not set
 | 
						|
+# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set
 | 
						|
+# CONFIG_ACPI_NFIT is not set
 | 
						|
+CONFIG_HAVE_ACPI_APEI=y
 | 
						|
+CONFIG_HAVE_ACPI_APEI_NMI=y
 | 
						|
+# CONFIG_ACPI_APEI is not set
 | 
						|
+# CONFIG_DPTF_POWER is not set
 | 
						|
+# CONFIG_ACPI_EXTLOG is not set
 | 
						|
+# CONFIG_PMIC_OPREGION is not set
 | 
						|
+# CONFIG_ACPI_CONFIGFS is not set
 | 
						|
+# CONFIG_SFI is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# CPU Frequency scaling
 | 
						|
+#
 | 
						|
+CONFIG_CPU_FREQ=y
 | 
						|
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
 | 
						|
+CONFIG_CPU_FREQ_GOV_COMMON=y
 | 
						|
+# CONFIG_CPU_FREQ_STAT is not set
 | 
						|
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
 | 
						|
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
 | 
						|
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
 | 
						|
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
 | 
						|
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
 | 
						|
+# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
 | 
						|
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 | 
						|
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
 | 
						|
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
 | 
						|
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
 | 
						|
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
 | 
						|
+# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# CPU frequency scaling drivers
 | 
						|
+#
 | 
						|
+# CONFIG_X86_INTEL_PSTATE is not set
 | 
						|
+# CONFIG_X86_PCC_CPUFREQ is not set
 | 
						|
+CONFIG_X86_ACPI_CPUFREQ=m
 | 
						|
+CONFIG_X86_ACPI_CPUFREQ_CPB=y
 | 
						|
+CONFIG_X86_POWERNOW_K8=m
 | 
						|
+# CONFIG_X86_AMD_FREQ_SENSITIVITY is not set
 | 
						|
+CONFIG_X86_SPEEDSTEP_CENTRINO=m
 | 
						|
+# CONFIG_X86_P4_CLOCKMOD is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# shared options
 | 
						|
+#
 | 
						|
+# CONFIG_X86_SPEEDSTEP_LIB is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# CPU Idle
 | 
						|
+#
 | 
						|
+CONFIG_CPU_IDLE=y
 | 
						|
+CONFIG_CPU_IDLE_GOV_LADDER=y
 | 
						|
+CONFIG_CPU_IDLE_GOV_MENU=y
 | 
						|
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
 | 
						|
+CONFIG_INTEL_IDLE=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Memory power savings
 | 
						|
+#
 | 
						|
+# CONFIG_I7300_IDLE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Bus options (PCI etc.)
 | 
						|
+#
 | 
						|
+CONFIG_PCI=y
 | 
						|
+CONFIG_PCI_DIRECT=y
 | 
						|
+CONFIG_PCI_MMCONFIG=y
 | 
						|
+CONFIG_PCI_DOMAINS=y
 | 
						|
+# CONFIG_PCI_CNB20LE_QUIRK is not set
 | 
						|
+# CONFIG_PCIEPORTBUS is not set
 | 
						|
+CONFIG_PCI_BUS_ADDR_T_64BIT=y
 | 
						|
+CONFIG_PCI_MSI=y
 | 
						|
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
 | 
						|
+# CONFIG_PCI_DEBUG is not set
 | 
						|
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
 | 
						|
+# CONFIG_PCI_STUB is not set
 | 
						|
+CONFIG_HT_IRQ=y
 | 
						|
+CONFIG_PCI_ATS=y
 | 
						|
+# CONFIG_PCI_IOV is not set
 | 
						|
+CONFIG_PCI_PRI=y
 | 
						|
+CONFIG_PCI_PASID=y
 | 
						|
+CONFIG_PCI_LABEL=y
 | 
						|
+CONFIG_HOTPLUG_PCI=y
 | 
						|
+# CONFIG_HOTPLUG_PCI_ACPI is not set
 | 
						|
+# CONFIG_HOTPLUG_PCI_CPCI is not set
 | 
						|
+# CONFIG_HOTPLUG_PCI_SHPC is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PCI host controller drivers
 | 
						|
+#
 | 
						|
+# CONFIG_PCIE_DW_PLAT is not set
 | 
						|
+# CONFIG_ISA_BUS is not set
 | 
						|
+# CONFIG_ISA_DMA_API is not set
 | 
						|
+CONFIG_AMD_NB=y
 | 
						|
+# CONFIG_PCCARD is not set
 | 
						|
+# CONFIG_RAPIDIO is not set
 | 
						|
+# CONFIG_X86_SYSFB is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Executable file formats / Emulations
 | 
						|
+#
 | 
						|
+CONFIG_BINFMT_ELF=y
 | 
						|
+CONFIG_COMPAT_BINFMT_ELF=y
 | 
						|
+CONFIG_ELFCORE=y
 | 
						|
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
 | 
						|
+CONFIG_BINFMT_SCRIPT=y
 | 
						|
+# CONFIG_HAVE_AOUT is not set
 | 
						|
+CONFIG_BINFMT_MISC=y
 | 
						|
+CONFIG_COREDUMP=y
 | 
						|
+CONFIG_IA32_EMULATION=y
 | 
						|
+# CONFIG_IA32_AOUT is not set
 | 
						|
+# CONFIG_X86_X32 is not set
 | 
						|
+CONFIG_COMPAT=y
 | 
						|
+CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
 | 
						|
+CONFIG_SYSVIPC_COMPAT=y
 | 
						|
+CONFIG_KEYS_COMPAT=y
 | 
						|
+CONFIG_X86_DEV_DMA_OPS=y
 | 
						|
+CONFIG_PMC_ATOM=y
 | 
						|
+CONFIG_VMD=y
 | 
						|
+CONFIG_NET=y
 | 
						|
+CONFIG_NET_INGRESS=y
 | 
						|
+CONFIG_NET_EGRESS=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Networking options
 | 
						|
+#
 | 
						|
+CONFIG_PACKET=y
 | 
						|
+CONFIG_PACKET_DIAG=y
 | 
						|
+CONFIG_UNIX=y
 | 
						|
+CONFIG_UNIX_DIAG=y
 | 
						|
+# CONFIG_XFRM_USER is not set
 | 
						|
+# CONFIG_NET_KEY is not set
 | 
						|
+CONFIG_INET=y
 | 
						|
+CONFIG_IP_MULTICAST=y
 | 
						|
+CONFIG_IP_ADVANCED_ROUTER=y
 | 
						|
+# CONFIG_IP_FIB_TRIE_STATS is not set
 | 
						|
+CONFIG_IP_MULTIPLE_TABLES=y
 | 
						|
+CONFIG_IP_ROUTE_MULTIPATH=y
 | 
						|
+CONFIG_IP_ROUTE_VERBOSE=y
 | 
						|
+CONFIG_IP_ROUTE_CLASSID=y
 | 
						|
+# CONFIG_IP_PNP is not set
 | 
						|
+CONFIG_NET_IPIP=m
 | 
						|
+CONFIG_NET_IPGRE_DEMUX=y
 | 
						|
+CONFIG_NET_IP_TUNNEL=y
 | 
						|
+CONFIG_NET_IPGRE=y
 | 
						|
+# CONFIG_NET_IPGRE_BROADCAST is not set
 | 
						|
+# CONFIG_IP_MROUTE is not set
 | 
						|
+CONFIG_SYN_COOKIES=y
 | 
						|
+# CONFIG_NET_UDP_TUNNEL is not set
 | 
						|
+# CONFIG_NET_FOU is not set
 | 
						|
+# CONFIG_NET_FOU_IP_TUNNELS is not set
 | 
						|
+# CONFIG_INET_AH is not set
 | 
						|
+# CONFIG_INET_ESP is not set
 | 
						|
+# CONFIG_INET_IPCOMP is not set
 | 
						|
+# CONFIG_INET_XFRM_TUNNEL is not set
 | 
						|
+CONFIG_INET_TUNNEL=y
 | 
						|
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 | 
						|
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
 | 
						|
+# CONFIG_INET_XFRM_MODE_BEET is not set
 | 
						|
+CONFIG_INET_DIAG=y
 | 
						|
+CONFIG_INET_TCP_DIAG=y
 | 
						|
+CONFIG_INET_UDP_DIAG=y
 | 
						|
+CONFIG_INET_DIAG_DESTROY=y
 | 
						|
+CONFIG_TCP_CONG_ADVANCED=y
 | 
						|
+CONFIG_TCP_CONG_BIC=y
 | 
						|
+CONFIG_TCP_CONG_CUBIC=y
 | 
						|
+CONFIG_TCP_CONG_WESTWOOD=y
 | 
						|
+CONFIG_TCP_CONG_HTCP=y
 | 
						|
+CONFIG_TCP_CONG_HSTCP=y
 | 
						|
+CONFIG_TCP_CONG_HYBLA=y
 | 
						|
+CONFIG_TCP_CONG_VEGAS=y
 | 
						|
+CONFIG_TCP_CONG_NV=y
 | 
						|
+CONFIG_TCP_CONG_SCALABLE=y
 | 
						|
+CONFIG_TCP_CONG_LP=y
 | 
						|
+CONFIG_TCP_CONG_VENO=y
 | 
						|
+CONFIG_TCP_CONG_YEAH=y
 | 
						|
+CONFIG_TCP_CONG_ILLINOIS=y
 | 
						|
+CONFIG_TCP_CONG_DCTCP=y
 | 
						|
+CONFIG_TCP_CONG_CDG=y
 | 
						|
+CONFIG_TCP_CONG_BBR=y
 | 
						|
+CONFIG_TCP_CONG_BBR2=y
 | 
						|
+# CONFIG_DEFAULT_CUBIC is not set
 | 
						|
+# CONFIG_DEFAULT_DCTCP is not set
 | 
						|
+CONFIG_DEFAULT_BBR2=y
 | 
						|
+# CONFIG_DEFAULT_RENO is not set
 | 
						|
+CONFIG_DEFAULT_TCP_CONG="bbr2"
 | 
						|
+CONFIG_TCP_MD5SIG=y
 | 
						|
+CONFIG_IPV6=y
 | 
						|
+# CONFIG_IPV6_ROUTER_PREF is not set
 | 
						|
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
 | 
						|
+# CONFIG_INET6_AH is not set
 | 
						|
+# CONFIG_INET6_ESP is not set
 | 
						|
+# CONFIG_INET6_IPCOMP is not set
 | 
						|
+# CONFIG_IPV6_MIP6 is not set
 | 
						|
+# CONFIG_IPV6_ILA is not set
 | 
						|
+# CONFIG_INET6_XFRM_TUNNEL is not set
 | 
						|
+CONFIG_INET6_TUNNEL=y
 | 
						|
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
 | 
						|
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
 | 
						|
+# CONFIG_INET6_XFRM_MODE_BEET is not set
 | 
						|
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 | 
						|
+CONFIG_IPV6_SIT=y
 | 
						|
+CONFIG_IPV6_SIT_6RD=y
 | 
						|
+CONFIG_IPV6_NDISC_NODETYPE=y
 | 
						|
+CONFIG_IPV6_TUNNEL=y
 | 
						|
+CONFIG_IPV6_GRE=y
 | 
						|
+# CONFIG_IPV6_FOU is not set
 | 
						|
+# CONFIG_IPV6_FOU_TUNNEL is not set
 | 
						|
+CONFIG_IPV6_MULTIPLE_TABLES=y
 | 
						|
+# CONFIG_IPV6_SUBTREES is not set
 | 
						|
+# CONFIG_IPV6_MROUTE is not set
 | 
						|
+# CONFIG_NETLABEL is not set
 | 
						|
+# CONFIG_NETWORK_SECMARK is not set
 | 
						|
+CONFIG_NET_PTP_CLASSIFY=y
 | 
						|
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
 | 
						|
+CONFIG_NETFILTER=y
 | 
						|
+# CONFIG_NETFILTER_DEBUG is not set
 | 
						|
+CONFIG_NETFILTER_ADVANCED=y
 | 
						|
+# CONFIG_BRIDGE_NETFILTER is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Core Netfilter Configuration
 | 
						|
+#
 | 
						|
+CONFIG_NETFILTER_INGRESS=y
 | 
						|
+CONFIG_NETFILTER_NETLINK=m
 | 
						|
+# CONFIG_NETFILTER_NETLINK_ACCT is not set
 | 
						|
+CONFIG_NETFILTER_NETLINK_QUEUE=m
 | 
						|
+CONFIG_NETFILTER_NETLINK_LOG=m
 | 
						|
+CONFIG_NF_CONNTRACK=m
 | 
						|
+CONFIG_NF_LOG_COMMON=m
 | 
						|
+CONFIG_NF_CONNTRACK_MARK=y
 | 
						|
+# CONFIG_NF_CONNTRACK_ZONES is not set
 | 
						|
+CONFIG_NF_CONNTRACK_PROCFS=y
 | 
						|
+CONFIG_NF_CONNTRACK_EVENTS=y
 | 
						|
+# CONFIG_NF_CONNTRACK_TIMEOUT is not set
 | 
						|
+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
 | 
						|
+# CONFIG_NF_CT_PROTO_DCCP is not set
 | 
						|
+# CONFIG_NF_CT_PROTO_SCTP is not set
 | 
						|
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
 | 
						|
+# CONFIG_NF_CONNTRACK_AMANDA is not set
 | 
						|
+CONFIG_NF_CONNTRACK_FTP=m
 | 
						|
+# CONFIG_NF_CONNTRACK_H323 is not set
 | 
						|
+# CONFIG_NF_CONNTRACK_IRC is not set
 | 
						|
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
 | 
						|
+# CONFIG_NF_CONNTRACK_SNMP is not set
 | 
						|
+# CONFIG_NF_CONNTRACK_PPTP is not set
 | 
						|
+# CONFIG_NF_CONNTRACK_SANE is not set
 | 
						|
+# CONFIG_NF_CONNTRACK_SIP is not set
 | 
						|
+# CONFIG_NF_CONNTRACK_TFTP is not set
 | 
						|
+CONFIG_NF_CT_NETLINK=m
 | 
						|
+# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
 | 
						|
+# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set
 | 
						|
+CONFIG_NF_NAT=m
 | 
						|
+CONFIG_NF_NAT_NEEDED=y
 | 
						|
+# CONFIG_NF_NAT_AMANDA is not set
 | 
						|
+CONFIG_NF_NAT_FTP=m
 | 
						|
+# CONFIG_NF_NAT_IRC is not set
 | 
						|
+# CONFIG_NF_NAT_SIP is not set
 | 
						|
+# CONFIG_NF_NAT_TFTP is not set
 | 
						|
+# CONFIG_NF_NAT_REDIRECT is not set
 | 
						|
+# CONFIG_NF_TABLES is not set
 | 
						|
+CONFIG_NETFILTER_XTABLES=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Xtables combined modules
 | 
						|
+#
 | 
						|
+CONFIG_NETFILTER_XT_MARK=m
 | 
						|
+CONFIG_NETFILTER_XT_CONNMARK=m
 | 
						|
+CONFIG_NETFILTER_XT_SET=m
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Xtables targets
 | 
						|
+#
 | 
						|
+# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set
 | 
						|
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_CT=m
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_DSCP=y
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_HL=m
 | 
						|
+# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
 | 
						|
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_MARK=m
 | 
						|
+CONFIG_NETFILTER_XT_NAT=m
 | 
						|
+# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 | 
						|
+# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set
 | 
						|
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
 | 
						|
+# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 | 
						|
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Xtables matches
 | 
						|
+#
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_BPF is not set
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_ECN=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_ESP=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_HL=m
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_MAC=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_MARK=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_REALM=m
 | 
						|
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_STRING=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_TIME=m
 | 
						|
+CONFIG_NETFILTER_XT_MATCH_U32=m
 | 
						|
+CONFIG_IP_SET=m
 | 
						|
+CONFIG_IP_SET_MAX=1024
 | 
						|
+# CONFIG_IP_SET_BITMAP_IP is not set
 | 
						|
+# CONFIG_IP_SET_BITMAP_IPMAC is not set
 | 
						|
+# CONFIG_IP_SET_BITMAP_PORT is not set
 | 
						|
+CONFIG_IP_SET_HASH_IP=m
 | 
						|
+# CONFIG_IP_SET_HASH_IPMARK is not set
 | 
						|
+# CONFIG_IP_SET_HASH_IPPORT is not set
 | 
						|
+# CONFIG_IP_SET_HASH_IPPORTIP is not set
 | 
						|
+# CONFIG_IP_SET_HASH_IPPORTNET is not set
 | 
						|
+# CONFIG_IP_SET_HASH_MAC is not set
 | 
						|
+# CONFIG_IP_SET_HASH_NETPORTNET is not set
 | 
						|
+CONFIG_IP_SET_HASH_NET=m
 | 
						|
+# CONFIG_IP_SET_HASH_NETNET is not set
 | 
						|
+# CONFIG_IP_SET_HASH_NETPORT is not set
 | 
						|
+# CONFIG_IP_SET_HASH_NETIFACE is not set
 | 
						|
+# CONFIG_IP_SET_LIST_SET is not set
 | 
						|
+# CONFIG_IP_VS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# IP: Netfilter Configuration
 | 
						|
+#
 | 
						|
+CONFIG_NF_DEFRAG_IPV4=m
 | 
						|
+CONFIG_NF_CONNTRACK_IPV4=m
 | 
						|
+# CONFIG_NF_DUP_IPV4 is not set
 | 
						|
+# CONFIG_NF_LOG_ARP is not set
 | 
						|
+CONFIG_NF_LOG_IPV4=m
 | 
						|
+CONFIG_NF_REJECT_IPV4=m
 | 
						|
+CONFIG_NF_NAT_IPV4=m
 | 
						|
+CONFIG_NF_NAT_MASQUERADE_IPV4=m
 | 
						|
+# CONFIG_NF_NAT_PPTP is not set
 | 
						|
+# CONFIG_NF_NAT_H323 is not set
 | 
						|
+CONFIG_IP_NF_IPTABLES=y
 | 
						|
+# CONFIG_IP_NF_MATCH_AH is not set
 | 
						|
+CONFIG_IP_NF_MATCH_ECN=m
 | 
						|
+# CONFIG_IP_NF_MATCH_RPFILTER is not set
 | 
						|
+CONFIG_IP_NF_MATCH_TTL=m
 | 
						|
+CONFIG_IP_NF_FILTER=m
 | 
						|
+CONFIG_IP_NF_TARGET_REJECT=m
 | 
						|
+# CONFIG_IP_NF_TARGET_SYNPROXY is not set
 | 
						|
+CONFIG_IP_NF_NAT=m
 | 
						|
+CONFIG_IP_NF_TARGET_MASQUERADE=m
 | 
						|
+# CONFIG_IP_NF_TARGET_NETMAP is not set
 | 
						|
+# CONFIG_IP_NF_TARGET_REDIRECT is not set
 | 
						|
+CONFIG_IP_NF_MANGLE=y
 | 
						|
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
 | 
						|
+CONFIG_IP_NF_TARGET_ECN=m
 | 
						|
+CONFIG_IP_NF_TARGET_TTL=m
 | 
						|
+CONFIG_IP_NF_RAW=m
 | 
						|
+# CONFIG_IP_NF_SECURITY is not set
 | 
						|
+# CONFIG_IP_NF_ARPTABLES is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# IPv6: Netfilter Configuration
 | 
						|
+#
 | 
						|
+CONFIG_NF_DEFRAG_IPV6=m
 | 
						|
+CONFIG_NF_CONNTRACK_IPV6=m
 | 
						|
+# CONFIG_NF_DUP_IPV6 is not set
 | 
						|
+CONFIG_NF_REJECT_IPV6=m
 | 
						|
+CONFIG_NF_LOG_IPV6=m
 | 
						|
+# CONFIG_NF_NAT_IPV6 is not set
 | 
						|
+CONFIG_IP6_NF_IPTABLES=y
 | 
						|
+# CONFIG_IP6_NF_MATCH_AH is not set
 | 
						|
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
 | 
						|
+CONFIG_IP6_NF_MATCH_FRAG=m
 | 
						|
+# CONFIG_IP6_NF_MATCH_OPTS is not set
 | 
						|
+CONFIG_IP6_NF_MATCH_HL=m
 | 
						|
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
 | 
						|
+# CONFIG_IP6_NF_MATCH_MH is not set
 | 
						|
+# CONFIG_IP6_NF_MATCH_RPFILTER is not set
 | 
						|
+# CONFIG_IP6_NF_MATCH_RT is not set
 | 
						|
+CONFIG_IP6_NF_TARGET_HL=m
 | 
						|
+CONFIG_IP6_NF_FILTER=m
 | 
						|
+CONFIG_IP6_NF_TARGET_REJECT=m
 | 
						|
+# CONFIG_IP6_NF_TARGET_SYNPROXY is not set
 | 
						|
+CONFIG_IP6_NF_MANGLE=y
 | 
						|
+CONFIG_IP6_NF_RAW=m
 | 
						|
+# CONFIG_IP6_NF_SECURITY is not set
 | 
						|
+# CONFIG_IP6_NF_NAT is not set
 | 
						|
+# CONFIG_BRIDGE_NF_EBTABLES is not set
 | 
						|
+# CONFIG_IP_DCCP is not set
 | 
						|
+# CONFIG_IP_SCTP is not set
 | 
						|
+# CONFIG_RDS is not set
 | 
						|
+# CONFIG_TIPC is not set
 | 
						|
+# CONFIG_ATM is not set
 | 
						|
+# CONFIG_L2TP is not set
 | 
						|
+CONFIG_STP=m
 | 
						|
+CONFIG_BRIDGE=m
 | 
						|
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 | 
						|
+# CONFIG_BRIDGE_VLAN_FILTERING is not set
 | 
						|
+CONFIG_HAVE_NET_DSA=y
 | 
						|
+CONFIG_VLAN_8021Q=m
 | 
						|
+# CONFIG_VLAN_8021Q_GVRP is not set
 | 
						|
+# CONFIG_VLAN_8021Q_MVRP is not set
 | 
						|
+# CONFIG_DECNET is not set
 | 
						|
+CONFIG_LLC=m
 | 
						|
+# CONFIG_LLC2 is not set
 | 
						|
+# CONFIG_IPX is not set
 | 
						|
+# CONFIG_ATALK is not set
 | 
						|
+# CONFIG_X25 is not set
 | 
						|
+# CONFIG_LAPB is not set
 | 
						|
+# CONFIG_PHONET is not set
 | 
						|
+# CONFIG_6LOWPAN is not set
 | 
						|
+# CONFIG_IEEE802154 is not set
 | 
						|
+CONFIG_NET_SCHED=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Queueing/Scheduling
 | 
						|
+#
 | 
						|
+CONFIG_NET_SCH_CBQ=m
 | 
						|
+CONFIG_NET_SCH_HTB=y
 | 
						|
+CONFIG_NET_SCH_HFSC=m
 | 
						|
+CONFIG_NET_SCH_PRIO=y
 | 
						|
+CONFIG_NET_SCH_MULTIQ=m
 | 
						|
+CONFIG_NET_SCH_RED=m
 | 
						|
+# CONFIG_NET_SCH_SFB is not set
 | 
						|
+CONFIG_NET_SCH_SFQ=m
 | 
						|
+CONFIG_NET_SCH_TEQL=m
 | 
						|
+CONFIG_NET_SCH_TBF=m
 | 
						|
+CONFIG_NET_SCH_GRED=m
 | 
						|
+CONFIG_NET_SCH_DSMARK=y
 | 
						|
+CONFIG_NET_SCH_NETEM=m
 | 
						|
+CONFIG_NET_SCH_DRR=m
 | 
						|
+CONFIG_NET_SCH_MQPRIO=m
 | 
						|
+# CONFIG_NET_SCH_CHOKE is not set
 | 
						|
+# CONFIG_NET_SCH_QFQ is not set
 | 
						|
+CONFIG_NET_SCH_CODEL=y
 | 
						|
+CONFIG_NET_SCH_FQ_CODEL=y
 | 
						|
+CONFIG_NET_SCH_FQ=y
 | 
						|
+# CONFIG_NET_SCH_HHF is not set
 | 
						|
+# CONFIG_NET_SCH_PIE is not set
 | 
						|
+CONFIG_NET_SCH_INGRESS=m
 | 
						|
+# CONFIG_NET_SCH_PLUG is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Classification
 | 
						|
+#
 | 
						|
+CONFIG_NET_CLS=y
 | 
						|
+CONFIG_NET_CLS_BASIC=m
 | 
						|
+CONFIG_NET_CLS_TCINDEX=y
 | 
						|
+CONFIG_NET_CLS_ROUTE4=m
 | 
						|
+CONFIG_NET_CLS_FW=m
 | 
						|
+CONFIG_NET_CLS_U32=y
 | 
						|
+# CONFIG_CLS_U32_PERF is not set
 | 
						|
+# CONFIG_CLS_U32_MARK is not set
 | 
						|
+CONFIG_NET_CLS_RSVP=m
 | 
						|
+CONFIG_NET_CLS_RSVP6=m
 | 
						|
+CONFIG_NET_CLS_FLOW=m
 | 
						|
+# CONFIG_NET_CLS_CGROUP is not set
 | 
						|
+# CONFIG_NET_CLS_BPF is not set
 | 
						|
+# CONFIG_NET_CLS_FLOWER is not set
 | 
						|
+# CONFIG_NET_CLS_MATCHALL is not set
 | 
						|
+CONFIG_NET_EMATCH=y
 | 
						|
+CONFIG_NET_EMATCH_STACK=32
 | 
						|
+CONFIG_NET_EMATCH_CMP=m
 | 
						|
+CONFIG_NET_EMATCH_NBYTE=m
 | 
						|
+CONFIG_NET_EMATCH_U32=m
 | 
						|
+CONFIG_NET_EMATCH_META=m
 | 
						|
+CONFIG_NET_EMATCH_TEXT=m
 | 
						|
+# CONFIG_NET_EMATCH_IPSET is not set
 | 
						|
+CONFIG_NET_CLS_ACT=y
 | 
						|
+CONFIG_NET_ACT_POLICE=m
 | 
						|
+CONFIG_NET_ACT_GACT=m
 | 
						|
+# CONFIG_GACT_PROB is not set
 | 
						|
+CONFIG_NET_ACT_MIRRED=y
 | 
						|
+CONFIG_NET_ACT_IPT=m
 | 
						|
+CONFIG_NET_ACT_NAT=m
 | 
						|
+CONFIG_NET_ACT_PEDIT=m
 | 
						|
+CONFIG_NET_ACT_SIMP=m
 | 
						|
+CONFIG_NET_ACT_SKBEDIT=m
 | 
						|
+# CONFIG_NET_ACT_CSUM is not set
 | 
						|
+# CONFIG_NET_ACT_VLAN is not set
 | 
						|
+# CONFIG_NET_ACT_BPF is not set
 | 
						|
+# CONFIG_NET_ACT_CONNMARK is not set
 | 
						|
+# CONFIG_NET_ACT_SKBMOD is not set
 | 
						|
+CONFIG_NET_ACT_IFE=m
 | 
						|
+# CONFIG_NET_ACT_TUNNEL_KEY is not set
 | 
						|
+CONFIG_NET_IFE_SKBMARK=m
 | 
						|
+CONFIG_NET_IFE_SKBPRIO=m
 | 
						|
+# CONFIG_NET_IFE_SKBTCINDEX is not set
 | 
						|
+# CONFIG_NET_CLS_IND is not set
 | 
						|
+CONFIG_NET_SCH_FIFO=y
 | 
						|
+CONFIG_DCB=y
 | 
						|
+CONFIG_DNS_RESOLVER=m
 | 
						|
+# CONFIG_BATMAN_ADV is not set
 | 
						|
+CONFIG_OPENVSWITCH=m
 | 
						|
+CONFIG_OPENVSWITCH_GRE=m
 | 
						|
+# CONFIG_VSOCKETS is not set
 | 
						|
+CONFIG_NETLINK_DIAG=y
 | 
						|
+CONFIG_MPLS=y
 | 
						|
+CONFIG_NET_MPLS_GSO=m
 | 
						|
+# CONFIG_MPLS_ROUTING is not set
 | 
						|
+# CONFIG_HSR is not set
 | 
						|
+# CONFIG_NET_SWITCHDEV is not set
 | 
						|
+# CONFIG_NET_L3_MASTER_DEV is not set
 | 
						|
+# CONFIG_NET_NCSI is not set
 | 
						|
+CONFIG_RPS=y
 | 
						|
+CONFIG_RFS_ACCEL=y
 | 
						|
+CONFIG_XPS=y
 | 
						|
+# CONFIG_SOCK_CGROUP_DATA is not set
 | 
						|
+# CONFIG_CGROUP_NET_PRIO is not set
 | 
						|
+# CONFIG_CGROUP_NET_CLASSID is not set
 | 
						|
+CONFIG_NET_RX_BUSY_POLL=y
 | 
						|
+CONFIG_BQL=y
 | 
						|
+CONFIG_BPF_JIT=y
 | 
						|
+CONFIG_NET_FLOW_LIMIT=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Network testing
 | 
						|
+#
 | 
						|
+CONFIG_NET_PKTGEN=m
 | 
						|
+# CONFIG_NET_TCPPROBE is not set
 | 
						|
+# CONFIG_NET_DROP_MONITOR is not set
 | 
						|
+# CONFIG_HAMRADIO is not set
 | 
						|
+# CONFIG_CAN is not set
 | 
						|
+# CONFIG_IRDA is not set
 | 
						|
+# CONFIG_BT is not set
 | 
						|
+# CONFIG_AF_RXRPC is not set
 | 
						|
+# CONFIG_AF_KCM is not set
 | 
						|
+# CONFIG_STREAM_PARSER is not set
 | 
						|
+CONFIG_FIB_RULES=y
 | 
						|
+# CONFIG_WIRELESS is not set
 | 
						|
+# CONFIG_WIMAX is not set
 | 
						|
+# CONFIG_RFKILL is not set
 | 
						|
+# CONFIG_NET_9P is not set
 | 
						|
+# CONFIG_CAIF is not set
 | 
						|
+# CONFIG_CEPH_LIB is not set
 | 
						|
+# CONFIG_NFC is not set
 | 
						|
+# CONFIG_LWTUNNEL is not set
 | 
						|
+CONFIG_DST_CACHE=y
 | 
						|
+CONFIG_NET_DEVLINK=y
 | 
						|
+CONFIG_MAY_USE_DEVLINK=y
 | 
						|
+CONFIG_HAVE_EBPF_JIT=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Device Drivers
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Generic Driver Options
 | 
						|
+#
 | 
						|
+CONFIG_UEVENT_HELPER=y
 | 
						|
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 | 
						|
+CONFIG_DEVTMPFS=y
 | 
						|
+# CONFIG_DEVTMPFS_MOUNT is not set
 | 
						|
+CONFIG_STANDALONE=y
 | 
						|
+CONFIG_PREVENT_FIRMWARE_BUILD=y
 | 
						|
+CONFIG_FW_LOADER=y
 | 
						|
+CONFIG_FIRMWARE_IN_KERNEL=y
 | 
						|
+CONFIG_EXTRA_FIRMWARE=""
 | 
						|
+CONFIG_FW_LOADER_USER_HELPER=y
 | 
						|
+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
 | 
						|
+CONFIG_ALLOW_DEV_COREDUMP=y
 | 
						|
+# CONFIG_DEBUG_DRIVER is not set
 | 
						|
+CONFIG_DEBUG_DEVRES=y
 | 
						|
+# CONFIG_SYS_HYPERVISOR is not set
 | 
						|
+# CONFIG_GENERIC_CPU_DEVICES is not set
 | 
						|
+CONFIG_GENERIC_CPU_AUTOPROBE=y
 | 
						|
+# CONFIG_DMA_SHARED_BUFFER is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Bus devices
 | 
						|
+#
 | 
						|
+CONFIG_CONNECTOR=y
 | 
						|
+CONFIG_PROC_EVENTS=y
 | 
						|
+# CONFIG_MTD is not set
 | 
						|
+# CONFIG_OF is not set
 | 
						|
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
 | 
						|
+# CONFIG_PARPORT is not set
 | 
						|
+CONFIG_PNP=y
 | 
						|
+CONFIG_PNP_DEBUG_MESSAGES=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Protocols
 | 
						|
+#
 | 
						|
+CONFIG_PNPACPI=y
 | 
						|
+CONFIG_BLK_DEV=y
 | 
						|
+# CONFIG_BLK_DEV_NULL_BLK is not set
 | 
						|
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
 | 
						|
+# CONFIG_BLK_CPQ_CISS_DA is not set
 | 
						|
+# CONFIG_BLK_DEV_DAC960 is not set
 | 
						|
+# CONFIG_BLK_DEV_UMEM is not set
 | 
						|
+# CONFIG_BLK_DEV_COW_COMMON is not set
 | 
						|
+CONFIG_BLK_DEV_LOOP=m
 | 
						|
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
 | 
						|
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
 | 
						|
+# CONFIG_BLK_DEV_DRBD is not set
 | 
						|
+CONFIG_BLK_DEV_NBD=m
 | 
						|
+# CONFIG_BLK_DEV_SKD is not set
 | 
						|
+# CONFIG_BLK_DEV_SX8 is not set
 | 
						|
+CONFIG_BLK_DEV_RAM=y
 | 
						|
+CONFIG_BLK_DEV_RAM_COUNT=16
 | 
						|
+CONFIG_BLK_DEV_RAM_SIZE=16384
 | 
						|
+# CONFIG_CDROM_PKTCDVD is not set
 | 
						|
+# CONFIG_ATA_OVER_ETH is not set
 | 
						|
+# CONFIG_VIRTIO_BLK is not set
 | 
						|
+# CONFIG_BLK_DEV_HD is not set
 | 
						|
+# CONFIG_BLK_DEV_RBD is not set
 | 
						|
+# CONFIG_BLK_DEV_RSXX is not set
 | 
						|
+# CONFIG_BLK_DEV_NVME is not set
 | 
						|
+# CONFIG_NVME_RDMA is not set
 | 
						|
+# CONFIG_NVME_TARGET is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Misc devices
 | 
						|
+#
 | 
						|
+# CONFIG_SENSORS_LIS3LV02D is not set
 | 
						|
+# CONFIG_AD525X_DPOT is not set
 | 
						|
+# CONFIG_DUMMY_IRQ is not set
 | 
						|
+# CONFIG_IBM_ASM is not set
 | 
						|
+# CONFIG_PHANTOM is not set
 | 
						|
+# CONFIG_SGI_IOC4 is not set
 | 
						|
+# CONFIG_TIFM_CORE is not set
 | 
						|
+# CONFIG_ICS932S401 is not set
 | 
						|
+# CONFIG_ENCLOSURE_SERVICES is not set
 | 
						|
+# CONFIG_HP_ILO is not set
 | 
						|
+# CONFIG_APDS9802ALS is not set
 | 
						|
+# CONFIG_ISL29003 is not set
 | 
						|
+# CONFIG_ISL29020 is not set
 | 
						|
+# CONFIG_SENSORS_TSL2550 is not set
 | 
						|
+# CONFIG_SENSORS_BH1770 is not set
 | 
						|
+# CONFIG_SENSORS_APDS990X is not set
 | 
						|
+# CONFIG_HMC6352 is not set
 | 
						|
+# CONFIG_DS1682 is not set
 | 
						|
+# CONFIG_BMP085_I2C is not set
 | 
						|
+# CONFIG_USB_SWITCH_FSA9480 is not set
 | 
						|
+# CONFIG_SRAM is not set
 | 
						|
+# CONFIG_C2PORT is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# EEPROM support
 | 
						|
+#
 | 
						|
+# CONFIG_EEPROM_AT24 is not set
 | 
						|
+CONFIG_EEPROM_LEGACY=m
 | 
						|
+# CONFIG_EEPROM_MAX6875 is not set
 | 
						|
+# CONFIG_EEPROM_93CX6 is not set
 | 
						|
+# CONFIG_CB710_CORE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Texas Instruments shared transport line discipline
 | 
						|
+#
 | 
						|
+# CONFIG_TI_ST is not set
 | 
						|
+# CONFIG_SENSORS_LIS3_I2C is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Altera FPGA firmware download module
 | 
						|
+#
 | 
						|
+# CONFIG_ALTERA_STAPL is not set
 | 
						|
+# CONFIG_INTEL_MEI is not set
 | 
						|
+# CONFIG_INTEL_MEI_ME is not set
 | 
						|
+# CONFIG_INTEL_MEI_TXE is not set
 | 
						|
+# CONFIG_VMWARE_VMCI is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Intel MIC Bus Driver
 | 
						|
+#
 | 
						|
+# CONFIG_INTEL_MIC_BUS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# SCIF Bus Driver
 | 
						|
+#
 | 
						|
+# CONFIG_SCIF_BUS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# VOP Bus Driver
 | 
						|
+#
 | 
						|
+# CONFIG_VOP_BUS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Intel MIC Host Driver
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Intel MIC Card Driver
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# SCIF Driver
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Intel MIC Coprocessor State Management (COSM) Drivers
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# VOP Driver
 | 
						|
+#
 | 
						|
+# CONFIG_GENWQE is not set
 | 
						|
+# CONFIG_ECHO is not set
 | 
						|
+# CONFIG_CXL_BASE is not set
 | 
						|
+# CONFIG_CXL_AFU_DRIVER_OPS is not set
 | 
						|
+CONFIG_HAVE_IDE=y
 | 
						|
+# CONFIG_IDE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# SCSI device support
 | 
						|
+#
 | 
						|
+CONFIG_SCSI_MOD=y
 | 
						|
+# CONFIG_RAID_ATTRS is not set
 | 
						|
+CONFIG_SCSI=y
 | 
						|
+CONFIG_SCSI_DMA=y
 | 
						|
+# CONFIG_SCSI_NETLINK is not set
 | 
						|
+# CONFIG_SCSI_MQ_DEFAULT is not set
 | 
						|
+CONFIG_SCSI_PROC_FS=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# SCSI support type (disk, tape, CD-ROM)
 | 
						|
+#
 | 
						|
+CONFIG_BLK_DEV_SD=y
 | 
						|
+CONFIG_CHR_DEV_ST=m
 | 
						|
+# CONFIG_CHR_DEV_OSST is not set
 | 
						|
+CONFIG_BLK_DEV_SR=m
 | 
						|
+CONFIG_BLK_DEV_SR_VENDOR=y
 | 
						|
+CONFIG_CHR_DEV_SG=y
 | 
						|
+# CONFIG_CHR_DEV_SCH is not set
 | 
						|
+CONFIG_SCSI_CONSTANTS=y
 | 
						|
+CONFIG_SCSI_LOGGING=y
 | 
						|
+# CONFIG_SCSI_SCAN_ASYNC is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# SCSI Transports
 | 
						|
+#
 | 
						|
+CONFIG_SCSI_SPI_ATTRS=m
 | 
						|
+# CONFIG_SCSI_FC_ATTRS is not set
 | 
						|
+CONFIG_SCSI_ISCSI_ATTRS=y
 | 
						|
+# CONFIG_SCSI_SAS_ATTRS is not set
 | 
						|
+# CONFIG_SCSI_SAS_LIBSAS is not set
 | 
						|
+# CONFIG_SCSI_SRP_ATTRS is not set
 | 
						|
+CONFIG_SCSI_LOWLEVEL=y
 | 
						|
+CONFIG_ISCSI_TCP=y
 | 
						|
+# CONFIG_ISCSI_BOOT_SYSFS is not set
 | 
						|
+# CONFIG_SCSI_CXGB3_ISCSI is not set
 | 
						|
+# CONFIG_SCSI_CXGB4_ISCSI is not set
 | 
						|
+# CONFIG_SCSI_BNX2_ISCSI is not set
 | 
						|
+# CONFIG_BE2ISCSI is not set
 | 
						|
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 | 
						|
+# CONFIG_SCSI_HPSA is not set
 | 
						|
+# CONFIG_SCSI_3W_9XXX is not set
 | 
						|
+# CONFIG_SCSI_3W_SAS is not set
 | 
						|
+# CONFIG_SCSI_ACARD is not set
 | 
						|
+# CONFIG_SCSI_AACRAID is not set
 | 
						|
+CONFIG_SCSI_AIC7XXX=m
 | 
						|
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
 | 
						|
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 | 
						|
+CONFIG_AIC7XXX_DEBUG_ENABLE=y
 | 
						|
+CONFIG_AIC7XXX_DEBUG_MASK=0
 | 
						|
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
 | 
						|
+# CONFIG_SCSI_AIC79XX is not set
 | 
						|
+# CONFIG_SCSI_AIC94XX is not set
 | 
						|
+# CONFIG_SCSI_MVSAS is not set
 | 
						|
+# CONFIG_SCSI_MVUMI is not set
 | 
						|
+# CONFIG_SCSI_DPT_I2O is not set
 | 
						|
+# CONFIG_SCSI_ADVANSYS is not set
 | 
						|
+# CONFIG_SCSI_ARCMSR is not set
 | 
						|
+# CONFIG_SCSI_ESAS2R is not set
 | 
						|
+CONFIG_MEGARAID_NEWGEN=y
 | 
						|
+CONFIG_MEGARAID_MM=y
 | 
						|
+CONFIG_MEGARAID_MAILBOX=y
 | 
						|
+# CONFIG_MEGARAID_LEGACY is not set
 | 
						|
+CONFIG_MEGARAID_SAS=y
 | 
						|
+# CONFIG_SCSI_MPT3SAS is not set
 | 
						|
+# CONFIG_SCSI_MPT2SAS is not set
 | 
						|
+# CONFIG_SCSI_UFSHCD is not set
 | 
						|
+# CONFIG_SCSI_HPTIOP is not set
 | 
						|
+# CONFIG_VMWARE_PVSCSI is not set
 | 
						|
+# CONFIG_SCSI_SNIC is not set
 | 
						|
+# CONFIG_SCSI_DMX3191D is not set
 | 
						|
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
 | 
						|
+# CONFIG_SCSI_ISCI is not set
 | 
						|
+# CONFIG_SCSI_IPS is not set
 | 
						|
+# CONFIG_SCSI_INITIO is not set
 | 
						|
+# CONFIG_SCSI_INIA100 is not set
 | 
						|
+# CONFIG_SCSI_STEX is not set
 | 
						|
+# CONFIG_SCSI_SYM53C8XX_2 is not set
 | 
						|
+# CONFIG_SCSI_IPR is not set
 | 
						|
+# CONFIG_SCSI_QLOGIC_1280 is not set
 | 
						|
+# CONFIG_SCSI_QLA_ISCSI is not set
 | 
						|
+# CONFIG_SCSI_DC395x is not set
 | 
						|
+# CONFIG_SCSI_AM53C974 is not set
 | 
						|
+# CONFIG_SCSI_WD719X is not set
 | 
						|
+# CONFIG_SCSI_DEBUG is not set
 | 
						|
+# CONFIG_SCSI_PMCRAID is not set
 | 
						|
+# CONFIG_SCSI_PM8001 is not set
 | 
						|
+CONFIG_SCSI_VIRTIO=y
 | 
						|
+# CONFIG_SCSI_DH is not set
 | 
						|
+# CONFIG_SCSI_OSD_INITIATOR is not set
 | 
						|
+CONFIG_ATA=y
 | 
						|
+# CONFIG_ATA_NONSTANDARD is not set
 | 
						|
+CONFIG_ATA_VERBOSE_ERROR=y
 | 
						|
+CONFIG_ATA_ACPI=y
 | 
						|
+# CONFIG_SATA_ZPODD is not set
 | 
						|
+CONFIG_SATA_PMP=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Controllers with non-SFF native interface
 | 
						|
+#
 | 
						|
+CONFIG_SATA_AHCI=y
 | 
						|
+# CONFIG_SATA_AHCI_PLATFORM is not set
 | 
						|
+# CONFIG_SATA_INIC162X is not set
 | 
						|
+# CONFIG_SATA_ACARD_AHCI is not set
 | 
						|
+CONFIG_SATA_SIL24=m
 | 
						|
+CONFIG_ATA_SFF=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# SFF controllers with custom DMA interface
 | 
						|
+#
 | 
						|
+# CONFIG_PDC_ADMA is not set
 | 
						|
+# CONFIG_SATA_QSTOR is not set
 | 
						|
+# CONFIG_SATA_SX4 is not set
 | 
						|
+CONFIG_ATA_BMDMA=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# SATA SFF controllers with BMDMA
 | 
						|
+#
 | 
						|
+CONFIG_ATA_PIIX=y
 | 
						|
+# CONFIG_SATA_DWC is not set
 | 
						|
+CONFIG_SATA_MV=m
 | 
						|
+CONFIG_SATA_NV=y
 | 
						|
+# CONFIG_SATA_PROMISE is not set
 | 
						|
+CONFIG_SATA_SIL=m
 | 
						|
+# CONFIG_SATA_SIS is not set
 | 
						|
+# CONFIG_SATA_SVW is not set
 | 
						|
+# CONFIG_SATA_ULI is not set
 | 
						|
+# CONFIG_SATA_VIA is not set
 | 
						|
+# CONFIG_SATA_VITESSE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PATA SFF controllers with BMDMA
 | 
						|
+#
 | 
						|
+# CONFIG_PATA_ALI is not set
 | 
						|
+CONFIG_PATA_AMD=y
 | 
						|
+# CONFIG_PATA_ARTOP is not set
 | 
						|
+# CONFIG_PATA_ATIIXP is not set
 | 
						|
+CONFIG_PATA_ATP867X=m
 | 
						|
+# CONFIG_PATA_CMD64X is not set
 | 
						|
+# CONFIG_PATA_CYPRESS is not set
 | 
						|
+# CONFIG_PATA_EFAR is not set
 | 
						|
+# CONFIG_PATA_HPT366 is not set
 | 
						|
+# CONFIG_PATA_HPT37X is not set
 | 
						|
+# CONFIG_PATA_HPT3X2N is not set
 | 
						|
+# CONFIG_PATA_HPT3X3 is not set
 | 
						|
+# CONFIG_PATA_IT8213 is not set
 | 
						|
+# CONFIG_PATA_IT821X is not set
 | 
						|
+# CONFIG_PATA_JMICRON is not set
 | 
						|
+# CONFIG_PATA_MARVELL is not set
 | 
						|
+# CONFIG_PATA_NETCELL is not set
 | 
						|
+# CONFIG_PATA_NINJA32 is not set
 | 
						|
+# CONFIG_PATA_NS87415 is not set
 | 
						|
+CONFIG_PATA_OLDPIIX=y
 | 
						|
+# CONFIG_PATA_OPTIDMA is not set
 | 
						|
+# CONFIG_PATA_PDC2027X is not set
 | 
						|
+# CONFIG_PATA_PDC_OLD is not set
 | 
						|
+# CONFIG_PATA_RADISYS is not set
 | 
						|
+# CONFIG_PATA_RDC is not set
 | 
						|
+CONFIG_PATA_SCH=y
 | 
						|
+# CONFIG_PATA_SERVERWORKS is not set
 | 
						|
+# CONFIG_PATA_SIL680 is not set
 | 
						|
+# CONFIG_PATA_SIS is not set
 | 
						|
+# CONFIG_PATA_TOSHIBA is not set
 | 
						|
+# CONFIG_PATA_TRIFLEX is not set
 | 
						|
+# CONFIG_PATA_VIA is not set
 | 
						|
+# CONFIG_PATA_WINBOND is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PIO-only SFF controllers
 | 
						|
+#
 | 
						|
+# CONFIG_PATA_CMD640_PCI is not set
 | 
						|
+# CONFIG_PATA_MPIIX is not set
 | 
						|
+# CONFIG_PATA_NS87410 is not set
 | 
						|
+# CONFIG_PATA_OPTI is not set
 | 
						|
+# CONFIG_PATA_PLATFORM is not set
 | 
						|
+# CONFIG_PATA_RZ1000 is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Generic fallback / legacy drivers
 | 
						|
+#
 | 
						|
+# CONFIG_PATA_ACPI is not set
 | 
						|
+# CONFIG_ATA_GENERIC is not set
 | 
						|
+# CONFIG_PATA_LEGACY is not set
 | 
						|
+CONFIG_MD=y
 | 
						|
+CONFIG_BLK_DEV_MD=y
 | 
						|
+CONFIG_MD_AUTODETECT=y
 | 
						|
+CONFIG_MD_LINEAR=m
 | 
						|
+CONFIG_MD_RAID0=m
 | 
						|
+CONFIG_MD_RAID1=y
 | 
						|
+CONFIG_MD_RAID10=m
 | 
						|
+# CONFIG_MD_RAID456 is not set
 | 
						|
+# CONFIG_MD_MULTIPATH is not set
 | 
						|
+# CONFIG_MD_FAULTY is not set
 | 
						|
+# CONFIG_BCACHE is not set
 | 
						|
+CONFIG_BLK_DEV_DM_BUILTIN=y
 | 
						|
+CONFIG_BLK_DEV_DM=y
 | 
						|
+# CONFIG_DM_MQ_DEFAULT is not set
 | 
						|
+# CONFIG_DM_DEBUG is not set
 | 
						|
+CONFIG_DM_BUFIO=y
 | 
						|
+# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set
 | 
						|
+CONFIG_DM_BIO_PRISON=y
 | 
						|
+CONFIG_DM_PERSISTENT_DATA=y
 | 
						|
+CONFIG_DM_CRYPT=y
 | 
						|
+# CONFIG_DM_SNAPSHOT is not set
 | 
						|
+CONFIG_DM_THIN_PROVISIONING=y
 | 
						|
+# CONFIG_DM_CACHE is not set
 | 
						|
+# CONFIG_DM_ERA is not set
 | 
						|
+CONFIG_DM_MIRROR=y
 | 
						|
+# CONFIG_DM_LOG_USERSPACE is not set
 | 
						|
+# CONFIG_DM_RAID is not set
 | 
						|
+CONFIG_DM_ZERO=y
 | 
						|
+CONFIG_DM_MULTIPATH=y
 | 
						|
+CONFIG_DM_MULTIPATH_QL=y
 | 
						|
+CONFIG_DM_MULTIPATH_ST=y
 | 
						|
+# CONFIG_DM_DELAY is not set
 | 
						|
+# CONFIG_DM_UEVENT is not set
 | 
						|
+# CONFIG_DM_FLAKEY is not set
 | 
						|
+CONFIG_DM_VERITY=y
 | 
						|
+# CONFIG_DM_VERITY_FEC is not set
 | 
						|
+# CONFIG_DM_SWITCH is not set
 | 
						|
+# CONFIG_DM_LOG_WRITES is not set
 | 
						|
+# CONFIG_TARGET_CORE is not set
 | 
						|
+# CONFIG_FUSION is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# IEEE 1394 (FireWire) support
 | 
						|
+#
 | 
						|
+CONFIG_FIREWIRE=m
 | 
						|
+CONFIG_FIREWIRE_OHCI=m
 | 
						|
+# CONFIG_FIREWIRE_SBP2 is not set
 | 
						|
+# CONFIG_FIREWIRE_NET is not set
 | 
						|
+# CONFIG_FIREWIRE_NOSY is not set
 | 
						|
+# CONFIG_MACINTOSH_DRIVERS is not set
 | 
						|
+CONFIG_NETDEVICES=y
 | 
						|
+CONFIG_NET_CORE=y
 | 
						|
+CONFIG_BONDING=m
 | 
						|
+# CONFIG_DUMMY is not set
 | 
						|
+# CONFIG_EQUALIZER is not set
 | 
						|
+# CONFIG_NET_FC is not set
 | 
						|
+CONFIG_IFB=m
 | 
						|
+# CONFIG_NET_TEAM is not set
 | 
						|
+CONFIG_MACVLAN=m
 | 
						|
+# CONFIG_MACVTAP is not set
 | 
						|
+# CONFIG_VXLAN is not set
 | 
						|
+# CONFIG_MACSEC is not set
 | 
						|
+CONFIG_NETCONSOLE=m
 | 
						|
+# CONFIG_NETCONSOLE_DYNAMIC is not set
 | 
						|
+CONFIG_NETPOLL=y
 | 
						|
+CONFIG_NET_POLL_CONTROLLER=y
 | 
						|
+CONFIG_TUN=y
 | 
						|
+# CONFIG_TUN_VNET_CROSS_LE is not set
 | 
						|
+CONFIG_VETH=y
 | 
						|
+CONFIG_VIRTIO_NET=y
 | 
						|
+# CONFIG_NLMON is not set
 | 
						|
+# CONFIG_ARCNET is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# CAIF transport drivers
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Distributed Switch Architecture drivers
 | 
						|
+#
 | 
						|
+CONFIG_ETHERNET=y
 | 
						|
+CONFIG_MDIO=m
 | 
						|
+CONFIG_NET_VENDOR_3COM=y
 | 
						|
+# CONFIG_VORTEX is not set
 | 
						|
+# CONFIG_TYPHOON is not set
 | 
						|
+CONFIG_NET_VENDOR_ADAPTEC=y
 | 
						|
+# CONFIG_ADAPTEC_STARFIRE is not set
 | 
						|
+CONFIG_NET_VENDOR_AGERE=y
 | 
						|
+# CONFIG_ET131X is not set
 | 
						|
+CONFIG_NET_VENDOR_ALTEON=y
 | 
						|
+# CONFIG_ACENIC is not set
 | 
						|
+# CONFIG_ALTERA_TSE is not set
 | 
						|
+CONFIG_NET_VENDOR_AMAZON=y
 | 
						|
+# CONFIG_ENA_ETHERNET is not set
 | 
						|
+CONFIG_NET_VENDOR_AMD=y
 | 
						|
+# CONFIG_AMD8111_ETH is not set
 | 
						|
+# CONFIG_PCNET32 is not set
 | 
						|
+CONFIG_NET_VENDOR_ARC=y
 | 
						|
+CONFIG_NET_VENDOR_ATHEROS=y
 | 
						|
+# CONFIG_ATL2 is not set
 | 
						|
+# CONFIG_ATL1 is not set
 | 
						|
+# CONFIG_ATL1E is not set
 | 
						|
+# CONFIG_ATL1C is not set
 | 
						|
+# CONFIG_ALX is not set
 | 
						|
+# CONFIG_NET_VENDOR_AURORA is not set
 | 
						|
+CONFIG_NET_CADENCE=y
 | 
						|
+# CONFIG_MACB is not set
 | 
						|
+CONFIG_NET_VENDOR_BROADCOM=y
 | 
						|
+# CONFIG_B44 is not set
 | 
						|
+# CONFIG_BCMGENET is not set
 | 
						|
+CONFIG_BNX2=m
 | 
						|
+# CONFIG_CNIC is not set
 | 
						|
+CONFIG_TIGON3=m
 | 
						|
+CONFIG_BNX2X=m
 | 
						|
+# CONFIG_BNXT is not set
 | 
						|
+CONFIG_NET_VENDOR_BROCADE=y
 | 
						|
+# CONFIG_BNA is not set
 | 
						|
+CONFIG_NET_VENDOR_CAVIUM=y
 | 
						|
+# CONFIG_THUNDER_NIC_PF is not set
 | 
						|
+# CONFIG_THUNDER_NIC_VF is not set
 | 
						|
+# CONFIG_THUNDER_NIC_BGX is not set
 | 
						|
+# CONFIG_THUNDER_NIC_RGX is not set
 | 
						|
+# CONFIG_LIQUIDIO is not set
 | 
						|
+CONFIG_NET_VENDOR_CHELSIO=y
 | 
						|
+# CONFIG_CHELSIO_T1 is not set
 | 
						|
+CONFIG_CHELSIO_T3=m
 | 
						|
+# CONFIG_CHELSIO_T4 is not set
 | 
						|
+# CONFIG_CHELSIO_T4VF is not set
 | 
						|
+CONFIG_NET_VENDOR_CISCO=y
 | 
						|
+# CONFIG_ENIC is not set
 | 
						|
+# CONFIG_CX_ECAT is not set
 | 
						|
+# CONFIG_DNET is not set
 | 
						|
+CONFIG_NET_VENDOR_DEC=y
 | 
						|
+# CONFIG_NET_TULIP is not set
 | 
						|
+CONFIG_NET_VENDOR_DLINK=y
 | 
						|
+# CONFIG_DL2K is not set
 | 
						|
+# CONFIG_SUNDANCE is not set
 | 
						|
+CONFIG_NET_VENDOR_EMULEX=y
 | 
						|
+# CONFIG_BE2NET is not set
 | 
						|
+CONFIG_NET_VENDOR_EZCHIP=y
 | 
						|
+CONFIG_NET_VENDOR_EXAR=y
 | 
						|
+# CONFIG_S2IO is not set
 | 
						|
+# CONFIG_VXGE is not set
 | 
						|
+CONFIG_NET_VENDOR_HP=y
 | 
						|
+# CONFIG_HP100 is not set
 | 
						|
+CONFIG_NET_VENDOR_INTEL=y
 | 
						|
+# CONFIG_E100 is not set
 | 
						|
+CONFIG_E1000=y
 | 
						|
+CONFIG_E1000E=m
 | 
						|
+CONFIG_E1000E_HWTS=y
 | 
						|
+# CONFIG_IGB is not set
 | 
						|
+# CONFIG_IGBVF is not set
 | 
						|
+# CONFIG_IXGB is not set
 | 
						|
+# CONFIG_IXGBE is not set
 | 
						|
+# CONFIG_IXGBEVF is not set
 | 
						|
+# CONFIG_I40E is not set
 | 
						|
+# CONFIG_I40EVF is not set
 | 
						|
+# CONFIG_FM10K is not set
 | 
						|
+CONFIG_NET_VENDOR_I825XX=y
 | 
						|
+# CONFIG_JME is not set
 | 
						|
+CONFIG_NET_VENDOR_MARVELL=y
 | 
						|
+# CONFIG_MVMDIO is not set
 | 
						|
+# CONFIG_MVNETA_BM is not set
 | 
						|
+# CONFIG_SKGE is not set
 | 
						|
+CONFIG_SKY2=m
 | 
						|
+# CONFIG_SKY2_DEBUG is not set
 | 
						|
+CONFIG_NET_VENDOR_MELLANOX=y
 | 
						|
+CONFIG_MLX4_EN=m
 | 
						|
+# CONFIG_MLX4_EN_DCB is not set
 | 
						|
+CONFIG_MLX4_CORE=m
 | 
						|
+CONFIG_MLX4_DEBUG=y
 | 
						|
+# CONFIG_MLX5_CORE is not set
 | 
						|
+# CONFIG_MLXSW_CORE is not set
 | 
						|
+CONFIG_NET_VENDOR_MICREL=y
 | 
						|
+# CONFIG_KS8851_MLL is not set
 | 
						|
+# CONFIG_KSZ884X_PCI is not set
 | 
						|
+CONFIG_NET_VENDOR_MYRI=y
 | 
						|
+# CONFIG_MYRI10GE is not set
 | 
						|
+# CONFIG_FEALNX is not set
 | 
						|
+CONFIG_NET_VENDOR_NATSEMI=y
 | 
						|
+# CONFIG_NATSEMI is not set
 | 
						|
+# CONFIG_NS83820 is not set
 | 
						|
+CONFIG_NET_VENDOR_NETRONOME=y
 | 
						|
+# CONFIG_NFP_NETVF is not set
 | 
						|
+CONFIG_NET_VENDOR_8390=y
 | 
						|
+# CONFIG_NE2K_PCI is not set
 | 
						|
+CONFIG_NET_VENDOR_NVIDIA=y
 | 
						|
+# CONFIG_FORCEDETH is not set
 | 
						|
+CONFIG_NET_VENDOR_OKI=y
 | 
						|
+# CONFIG_ETHOC is not set
 | 
						|
+CONFIG_NET_PACKET_ENGINE=y
 | 
						|
+# CONFIG_HAMACHI is not set
 | 
						|
+# CONFIG_YELLOWFIN is not set
 | 
						|
+CONFIG_NET_VENDOR_QLOGIC=y
 | 
						|
+# CONFIG_QLA3XXX is not set
 | 
						|
+# CONFIG_QLCNIC is not set
 | 
						|
+# CONFIG_QLGE is not set
 | 
						|
+# CONFIG_NETXEN_NIC is not set
 | 
						|
+# CONFIG_QED is not set
 | 
						|
+CONFIG_NET_VENDOR_QUALCOMM=y
 | 
						|
+# CONFIG_QCOM_EMAC is not set
 | 
						|
+CONFIG_NET_VENDOR_REALTEK=y
 | 
						|
+# CONFIG_8139CP is not set
 | 
						|
+# CONFIG_8139TOO is not set
 | 
						|
+# CONFIG_R8169 is not set
 | 
						|
+CONFIG_NET_VENDOR_RENESAS=y
 | 
						|
+CONFIG_NET_VENDOR_RDC=y
 | 
						|
+# CONFIG_R6040 is not set
 | 
						|
+CONFIG_NET_VENDOR_ROCKER=y
 | 
						|
+CONFIG_NET_VENDOR_SAMSUNG=y
 | 
						|
+# CONFIG_SXGBE_ETH is not set
 | 
						|
+CONFIG_NET_VENDOR_SEEQ=y
 | 
						|
+CONFIG_NET_VENDOR_SILAN=y
 | 
						|
+# CONFIG_SC92031 is not set
 | 
						|
+CONFIG_NET_VENDOR_SIS=y
 | 
						|
+# CONFIG_SIS900 is not set
 | 
						|
+# CONFIG_SIS190 is not set
 | 
						|
+# CONFIG_SFC is not set
 | 
						|
+CONFIG_NET_VENDOR_SMSC=y
 | 
						|
+# CONFIG_EPIC100 is not set
 | 
						|
+# CONFIG_SMSC911X is not set
 | 
						|
+# CONFIG_SMSC9420 is not set
 | 
						|
+CONFIG_NET_VENDOR_STMICRO=y
 | 
						|
+# CONFIG_STMMAC_ETH is not set
 | 
						|
+CONFIG_NET_VENDOR_SUN=y
 | 
						|
+# CONFIG_HAPPYMEAL is not set
 | 
						|
+# CONFIG_SUNGEM is not set
 | 
						|
+# CONFIG_CASSINI is not set
 | 
						|
+# CONFIG_NIU is not set
 | 
						|
+CONFIG_NET_VENDOR_SYNOPSYS=y
 | 
						|
+CONFIG_NET_VENDOR_TEHUTI=y
 | 
						|
+# CONFIG_TEHUTI is not set
 | 
						|
+CONFIG_NET_VENDOR_TI=y
 | 
						|
+# CONFIG_TI_CPSW_ALE is not set
 | 
						|
+# CONFIG_TLAN is not set
 | 
						|
+CONFIG_NET_VENDOR_VIA=y
 | 
						|
+# CONFIG_VIA_RHINE is not set
 | 
						|
+# CONFIG_VIA_VELOCITY is not set
 | 
						|
+CONFIG_NET_VENDOR_WIZNET=y
 | 
						|
+# CONFIG_WIZNET_W5100 is not set
 | 
						|
+# CONFIG_WIZNET_W5300 is not set
 | 
						|
+# CONFIG_FDDI is not set
 | 
						|
+# CONFIG_HIPPI is not set
 | 
						|
+# CONFIG_NET_SB1000 is not set
 | 
						|
+CONFIG_PHYLIB=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# MDIO bus device drivers
 | 
						|
+#
 | 
						|
+# CONFIG_MDIO_BCM_UNIMAC is not set
 | 
						|
+# CONFIG_MDIO_BITBANG is not set
 | 
						|
+# CONFIG_MDIO_OCTEON is not set
 | 
						|
+# CONFIG_MDIO_THUNDER is not set
 | 
						|
+# CONFIG_MDIO_XGENE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# MII PHY device drivers
 | 
						|
+#
 | 
						|
+# CONFIG_AMD_PHY is not set
 | 
						|
+# CONFIG_AQUANTIA_PHY is not set
 | 
						|
+# CONFIG_AT803X_PHY is not set
 | 
						|
+# CONFIG_BCM7XXX_PHY is not set
 | 
						|
+# CONFIG_BCM87XX_PHY is not set
 | 
						|
+# CONFIG_BROADCOM_PHY is not set
 | 
						|
+# CONFIG_CICADA_PHY is not set
 | 
						|
+# CONFIG_DAVICOM_PHY is not set
 | 
						|
+# CONFIG_DP83848_PHY is not set
 | 
						|
+# CONFIG_DP83867_PHY is not set
 | 
						|
+# CONFIG_FIXED_PHY is not set
 | 
						|
+# CONFIG_ICPLUS_PHY is not set
 | 
						|
+# CONFIG_INTEL_XWAY_PHY is not set
 | 
						|
+# CONFIG_LSI_ET1011C_PHY is not set
 | 
						|
+# CONFIG_LXT_PHY is not set
 | 
						|
+# CONFIG_MARVELL_PHY is not set
 | 
						|
+# CONFIG_MICREL_PHY is not set
 | 
						|
+# CONFIG_MICROCHIP_PHY is not set
 | 
						|
+# CONFIG_MICROSEMI_PHY is not set
 | 
						|
+# CONFIG_NATIONAL_PHY is not set
 | 
						|
+# CONFIG_QSEMI_PHY is not set
 | 
						|
+# CONFIG_REALTEK_PHY is not set
 | 
						|
+# CONFIG_SMSC_PHY is not set
 | 
						|
+# CONFIG_STE10XP is not set
 | 
						|
+# CONFIG_TERANETICS_PHY is not set
 | 
						|
+# CONFIG_VITESSE_PHY is not set
 | 
						|
+# CONFIG_XILINX_GMII2RGMII is not set
 | 
						|
+# CONFIG_PPP is not set
 | 
						|
+# CONFIG_SLIP is not set
 | 
						|
+CONFIG_USB_NET_DRIVERS=y
 | 
						|
+# CONFIG_USB_CATC is not set
 | 
						|
+# CONFIG_USB_KAWETH is not set
 | 
						|
+# CONFIG_USB_PEGASUS is not set
 | 
						|
+# CONFIG_USB_RTL8150 is not set
 | 
						|
+# CONFIG_USB_RTL8152 is not set
 | 
						|
+# CONFIG_USB_LAN78XX is not set
 | 
						|
+# CONFIG_USB_USBNET is not set
 | 
						|
+# CONFIG_USB_IPHETH is not set
 | 
						|
+# CONFIG_WLAN is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 | 
						|
+#
 | 
						|
+# CONFIG_WAN is not set
 | 
						|
+# CONFIG_VMXNET3 is not set
 | 
						|
+# CONFIG_FUJITSU_ES is not set
 | 
						|
+# CONFIG_ISDN is not set
 | 
						|
+# CONFIG_NVM is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Input device support
 | 
						|
+#
 | 
						|
+CONFIG_INPUT=y
 | 
						|
+# CONFIG_INPUT_FF_MEMLESS is not set
 | 
						|
+# CONFIG_INPUT_POLLDEV is not set
 | 
						|
+CONFIG_INPUT_SPARSEKMAP=m
 | 
						|
+# CONFIG_INPUT_MATRIXKMAP is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Userland interfaces
 | 
						|
+#
 | 
						|
+CONFIG_INPUT_MOUSEDEV=y
 | 
						|
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 | 
						|
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 | 
						|
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 | 
						|
+# CONFIG_INPUT_JOYDEV is not set
 | 
						|
+CONFIG_INPUT_EVDEV=m
 | 
						|
+# CONFIG_INPUT_EVBUG is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Input Device Drivers
 | 
						|
+#
 | 
						|
+CONFIG_INPUT_KEYBOARD=y
 | 
						|
+# CONFIG_KEYBOARD_ADP5588 is not set
 | 
						|
+# CONFIG_KEYBOARD_ADP5589 is not set
 | 
						|
+CONFIG_KEYBOARD_ATKBD=y
 | 
						|
+# CONFIG_KEYBOARD_QT1070 is not set
 | 
						|
+# CONFIG_KEYBOARD_QT2160 is not set
 | 
						|
+# CONFIG_KEYBOARD_LKKBD is not set
 | 
						|
+# CONFIG_KEYBOARD_GPIO is not set
 | 
						|
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
 | 
						|
+# CONFIG_KEYBOARD_TCA6416 is not set
 | 
						|
+# CONFIG_KEYBOARD_TCA8418 is not set
 | 
						|
+# CONFIG_KEYBOARD_MATRIX is not set
 | 
						|
+# CONFIG_KEYBOARD_LM8333 is not set
 | 
						|
+# CONFIG_KEYBOARD_MAX7359 is not set
 | 
						|
+# CONFIG_KEYBOARD_MCS is not set
 | 
						|
+# CONFIG_KEYBOARD_MPR121 is not set
 | 
						|
+# CONFIG_KEYBOARD_NEWTON is not set
 | 
						|
+# CONFIG_KEYBOARD_OPENCORES is not set
 | 
						|
+# CONFIG_KEYBOARD_STOWAWAY is not set
 | 
						|
+# CONFIG_KEYBOARD_SUNKBD is not set
 | 
						|
+# CONFIG_KEYBOARD_XTKBD is not set
 | 
						|
+# CONFIG_INPUT_MOUSE is not set
 | 
						|
+# CONFIG_INPUT_JOYSTICK is not set
 | 
						|
+# CONFIG_INPUT_TABLET is not set
 | 
						|
+# CONFIG_INPUT_TOUCHSCREEN is not set
 | 
						|
+CONFIG_INPUT_MISC=y
 | 
						|
+# CONFIG_INPUT_AD714X is not set
 | 
						|
+# CONFIG_INPUT_BMA150 is not set
 | 
						|
+# CONFIG_INPUT_E3X0_BUTTON is not set
 | 
						|
+CONFIG_INPUT_PCSPKR=m
 | 
						|
+# CONFIG_INPUT_MMA8450 is not set
 | 
						|
+# CONFIG_INPUT_MPU3050 is not set
 | 
						|
+# CONFIG_INPUT_GP2A is not set
 | 
						|
+# CONFIG_INPUT_GPIO_BEEPER is not set
 | 
						|
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
 | 
						|
+# CONFIG_INPUT_ATLAS_BTNS is not set
 | 
						|
+# CONFIG_INPUT_ATI_REMOTE2 is not set
 | 
						|
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
 | 
						|
+# CONFIG_INPUT_KXTJ9 is not set
 | 
						|
+# CONFIG_INPUT_POWERMATE is not set
 | 
						|
+# CONFIG_INPUT_YEALINK is not set
 | 
						|
+# CONFIG_INPUT_CM109 is not set
 | 
						|
+# CONFIG_INPUT_UINPUT is not set
 | 
						|
+# CONFIG_INPUT_PCF8574 is not set
 | 
						|
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
 | 
						|
+# CONFIG_INPUT_ADXL34X is not set
 | 
						|
+# CONFIG_INPUT_CMA3000 is not set
 | 
						|
+# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set
 | 
						|
+# CONFIG_INPUT_DRV260X_HAPTICS is not set
 | 
						|
+# CONFIG_INPUT_DRV2665_HAPTICS is not set
 | 
						|
+# CONFIG_INPUT_DRV2667_HAPTICS is not set
 | 
						|
+# CONFIG_RMI4_CORE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Hardware I/O ports
 | 
						|
+#
 | 
						|
+CONFIG_SERIO=y
 | 
						|
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
 | 
						|
+CONFIG_SERIO_I8042=y
 | 
						|
+CONFIG_SERIO_SERPORT=y
 | 
						|
+# CONFIG_SERIO_CT82C710 is not set
 | 
						|
+# CONFIG_SERIO_PCIPS2 is not set
 | 
						|
+CONFIG_SERIO_LIBPS2=y
 | 
						|
+# CONFIG_SERIO_RAW is not set
 | 
						|
+# CONFIG_SERIO_ALTERA_PS2 is not set
 | 
						|
+# CONFIG_SERIO_PS2MULT is not set
 | 
						|
+# CONFIG_SERIO_ARC_PS2 is not set
 | 
						|
+# CONFIG_USERIO is not set
 | 
						|
+# CONFIG_GAMEPORT is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Character devices
 | 
						|
+#
 | 
						|
+CONFIG_TTY=y
 | 
						|
+CONFIG_VT=y
 | 
						|
+CONFIG_CONSOLE_TRANSLATIONS=y
 | 
						|
+CONFIG_VT_CONSOLE=y
 | 
						|
+CONFIG_VT_CONSOLE_SLEEP=y
 | 
						|
+CONFIG_HW_CONSOLE=y
 | 
						|
+CONFIG_VT_HW_CONSOLE_BINDING=y
 | 
						|
+CONFIG_UNIX98_PTYS=y
 | 
						|
+CONFIG_LEGACY_PTYS=y
 | 
						|
+CONFIG_LEGACY_PTY_COUNT=256
 | 
						|
+# CONFIG_SERIAL_NONSTANDARD is not set
 | 
						|
+# CONFIG_NOZOMI is not set
 | 
						|
+# CONFIG_N_GSM is not set
 | 
						|
+# CONFIG_TRACE_SINK is not set
 | 
						|
+CONFIG_DEVMEM=y
 | 
						|
+CONFIG_DEVKMEM=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Serial drivers
 | 
						|
+#
 | 
						|
+CONFIG_SERIAL_EARLYCON=y
 | 
						|
+CONFIG_SERIAL_8250=y
 | 
						|
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
 | 
						|
+CONFIG_SERIAL_8250_PNP=y
 | 
						|
+# CONFIG_SERIAL_8250_FINTEK is not set
 | 
						|
+CONFIG_SERIAL_8250_CONSOLE=y
 | 
						|
+CONFIG_SERIAL_8250_DMA=y
 | 
						|
+CONFIG_SERIAL_8250_PCI=y
 | 
						|
+CONFIG_SERIAL_8250_NR_UARTS=32
 | 
						|
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 | 
						|
+CONFIG_SERIAL_8250_EXTENDED=y
 | 
						|
+CONFIG_SERIAL_8250_MANY_PORTS=y
 | 
						|
+CONFIG_SERIAL_8250_SHARE_IRQ=y
 | 
						|
+CONFIG_SERIAL_8250_DETECT_IRQ=y
 | 
						|
+CONFIG_SERIAL_8250_RSA=y
 | 
						|
+# CONFIG_SERIAL_8250_FSL is not set
 | 
						|
+# CONFIG_SERIAL_8250_DW is not set
 | 
						|
+# CONFIG_SERIAL_8250_RT288X is not set
 | 
						|
+# CONFIG_SERIAL_8250_MID is not set
 | 
						|
+# CONFIG_SERIAL_8250_MOXA is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Non-8250 serial port support
 | 
						|
+#
 | 
						|
+# CONFIG_SERIAL_UARTLITE is not set
 | 
						|
+CONFIG_SERIAL_CORE=y
 | 
						|
+CONFIG_SERIAL_CORE_CONSOLE=y
 | 
						|
+# CONFIG_SERIAL_JSM is not set
 | 
						|
+# CONFIG_SERIAL_SCCNXP is not set
 | 
						|
+# CONFIG_SERIAL_SC16IS7XX is not set
 | 
						|
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
 | 
						|
+# CONFIG_SERIAL_ALTERA_UART is not set
 | 
						|
+# CONFIG_SERIAL_ARC is not set
 | 
						|
+# CONFIG_SERIAL_RP2 is not set
 | 
						|
+# CONFIG_SERIAL_FSL_LPUART is not set
 | 
						|
+# CONFIG_TTY_PRINTK is not set
 | 
						|
+# CONFIG_VIRTIO_CONSOLE is not set
 | 
						|
+CONFIG_IPMI_HANDLER=m
 | 
						|
+# CONFIG_IPMI_PANIC_EVENT is not set
 | 
						|
+CONFIG_IPMI_DEVICE_INTERFACE=m
 | 
						|
+CONFIG_IPMI_SI=m
 | 
						|
+# CONFIG_IPMI_SSIF is not set
 | 
						|
+# CONFIG_IPMI_WATCHDOG is not set
 | 
						|
+CONFIG_IPMI_POWEROFF=m
 | 
						|
+# CONFIG_HW_RANDOM is not set
 | 
						|
+CONFIG_NVRAM=m
 | 
						|
+# CONFIG_R3964 is not set
 | 
						|
+# CONFIG_APPLICOM is not set
 | 
						|
+# CONFIG_MWAVE is not set
 | 
						|
+# CONFIG_RAW_DRIVER is not set
 | 
						|
+CONFIG_HPET=y
 | 
						|
+CONFIG_HPET_MMAP=y
 | 
						|
+CONFIG_HPET_MMAP_DEFAULT=y
 | 
						|
+# CONFIG_HANGCHECK_TIMER is not set
 | 
						|
+# CONFIG_TCG_TPM is not set
 | 
						|
+# CONFIG_TELCLOCK is not set
 | 
						|
+CONFIG_DEVPORT=y
 | 
						|
+# CONFIG_XILLYBUS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# I2C support
 | 
						|
+#
 | 
						|
+CONFIG_I2C=m
 | 
						|
+CONFIG_I2C_BOARDINFO=y
 | 
						|
+CONFIG_I2C_COMPAT=y
 | 
						|
+CONFIG_I2C_CHARDEV=m
 | 
						|
+CONFIG_I2C_MUX=m
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Multiplexer I2C Chip support
 | 
						|
+#
 | 
						|
+# CONFIG_I2C_MUX_GPIO is not set
 | 
						|
+CONFIG_I2C_MUX_PCA9541=m
 | 
						|
+CONFIG_I2C_MUX_PCA954x=m
 | 
						|
+# CONFIG_I2C_MUX_REG is not set
 | 
						|
+CONFIG_I2C_HELPER_AUTO=y
 | 
						|
+CONFIG_I2C_SMBUS=m
 | 
						|
+CONFIG_I2C_ALGOBIT=m
 | 
						|
+
 | 
						|
+#
 | 
						|
+# I2C Hardware Bus support
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PC SMBus host controller drivers
 | 
						|
+#
 | 
						|
+# CONFIG_I2C_ALI1535 is not set
 | 
						|
+# CONFIG_I2C_ALI1563 is not set
 | 
						|
+# CONFIG_I2C_ALI15X3 is not set
 | 
						|
+# CONFIG_I2C_AMD756 is not set
 | 
						|
+# CONFIG_I2C_AMD8111 is not set
 | 
						|
+CONFIG_I2C_I801=m
 | 
						|
+# CONFIG_I2C_ISCH is not set
 | 
						|
+# CONFIG_I2C_ISMT is not set
 | 
						|
+CONFIG_I2C_PIIX4=m
 | 
						|
+CONFIG_I2C_NFORCE2=m
 | 
						|
+# CONFIG_I2C_NFORCE2_S4985 is not set
 | 
						|
+# CONFIG_I2C_SIS5595 is not set
 | 
						|
+# CONFIG_I2C_SIS630 is not set
 | 
						|
+# CONFIG_I2C_SIS96X is not set
 | 
						|
+# CONFIG_I2C_VIA is not set
 | 
						|
+# CONFIG_I2C_VIAPRO is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# ACPI drivers
 | 
						|
+#
 | 
						|
+# CONFIG_I2C_SCMI is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# I2C system bus drivers (mostly embedded / system-on-chip)
 | 
						|
+#
 | 
						|
+# CONFIG_I2C_CBUS_GPIO is not set
 | 
						|
+# CONFIG_I2C_DESIGNWARE_PCI is not set
 | 
						|
+# CONFIG_I2C_GPIO is not set
 | 
						|
+# CONFIG_I2C_OCORES is not set
 | 
						|
+# CONFIG_I2C_PCA_PLATFORM is not set
 | 
						|
+# CONFIG_I2C_PXA_PCI is not set
 | 
						|
+# CONFIG_I2C_SIMTEC is not set
 | 
						|
+# CONFIG_I2C_XILINX is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# External I2C/SMBus adapter drivers
 | 
						|
+#
 | 
						|
+# CONFIG_I2C_DIOLAN_U2C is not set
 | 
						|
+# CONFIG_I2C_PARPORT_LIGHT is not set
 | 
						|
+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
 | 
						|
+# CONFIG_I2C_TAOS_EVM is not set
 | 
						|
+# CONFIG_I2C_TINY_USB is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Other I2C/SMBus bus drivers
 | 
						|
+#
 | 
						|
+# CONFIG_I2C_STUB is not set
 | 
						|
+# CONFIG_I2C_SLAVE is not set
 | 
						|
+# CONFIG_I2C_DEBUG_CORE is not set
 | 
						|
+# CONFIG_I2C_DEBUG_ALGO is not set
 | 
						|
+# CONFIG_I2C_DEBUG_BUS is not set
 | 
						|
+# CONFIG_SPI is not set
 | 
						|
+# CONFIG_SPMI is not set
 | 
						|
+# CONFIG_HSI is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PPS support
 | 
						|
+#
 | 
						|
+CONFIG_PPS=y
 | 
						|
+# CONFIG_PPS_DEBUG is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PPS clients support
 | 
						|
+#
 | 
						|
+# CONFIG_PPS_CLIENT_KTIMER is not set
 | 
						|
+# CONFIG_PPS_CLIENT_LDISC is not set
 | 
						|
+# CONFIG_PPS_CLIENT_GPIO is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PPS generators support
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PTP clock support
 | 
						|
+#
 | 
						|
+CONFIG_PTP_1588_CLOCK=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
 | 
						|
+#
 | 
						|
+CONFIG_GPIOLIB=y
 | 
						|
+CONFIG_GPIO_DEVRES=y
 | 
						|
+CONFIG_GPIO_ACPI=y
 | 
						|
+# CONFIG_DEBUG_GPIO is not set
 | 
						|
+# CONFIG_GPIO_SYSFS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Memory mapped GPIO drivers
 | 
						|
+#
 | 
						|
+# CONFIG_GPIO_AMDPT is not set
 | 
						|
+# CONFIG_GPIO_DWAPB is not set
 | 
						|
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
 | 
						|
+# CONFIG_GPIO_ICH is not set
 | 
						|
+# CONFIG_GPIO_LYNXPOINT is not set
 | 
						|
+# CONFIG_GPIO_VX855 is not set
 | 
						|
+# CONFIG_GPIO_ZX is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Port-mapped I/O GPIO drivers
 | 
						|
+#
 | 
						|
+# CONFIG_GPIO_F7188X is not set
 | 
						|
+# CONFIG_GPIO_IT87 is not set
 | 
						|
+# CONFIG_GPIO_SCH is not set
 | 
						|
+# CONFIG_GPIO_SCH311X is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# I2C GPIO expanders
 | 
						|
+#
 | 
						|
+# CONFIG_GPIO_ADP5588 is not set
 | 
						|
+# CONFIG_GPIO_MAX7300 is not set
 | 
						|
+# CONFIG_GPIO_MAX732X is not set
 | 
						|
+# CONFIG_GPIO_PCA953X is not set
 | 
						|
+# CONFIG_GPIO_PCF857X is not set
 | 
						|
+# CONFIG_GPIO_TPIC2810 is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# MFD GPIO expanders
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PCI GPIO expanders
 | 
						|
+#
 | 
						|
+# CONFIG_GPIO_AMD8111 is not set
 | 
						|
+# CONFIG_GPIO_BT8XX is not set
 | 
						|
+# CONFIG_GPIO_ML_IOH is not set
 | 
						|
+# CONFIG_GPIO_RDC321X is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# SPI or I2C GPIO expanders
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# USB GPIO expanders
 | 
						|
+#
 | 
						|
+CONFIG_W1=m
 | 
						|
+CONFIG_W1_CON=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# 1-wire Bus Masters
 | 
						|
+#
 | 
						|
+# CONFIG_W1_MASTER_MATROX is not set
 | 
						|
+# CONFIG_W1_MASTER_DS2490 is not set
 | 
						|
+CONFIG_W1_MASTER_DS2482=m
 | 
						|
+# CONFIG_W1_MASTER_DS1WM is not set
 | 
						|
+# CONFIG_W1_MASTER_GPIO is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# 1-wire Slaves
 | 
						|
+#
 | 
						|
+CONFIG_W1_SLAVE_THERM=m
 | 
						|
+# CONFIG_W1_SLAVE_SMEM is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS2408 is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS2413 is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS2406 is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS2423 is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS2431 is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS2433 is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS2760 is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS2780 is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS2781 is not set
 | 
						|
+# CONFIG_W1_SLAVE_DS28E04 is not set
 | 
						|
+# CONFIG_W1_SLAVE_BQ27000 is not set
 | 
						|
+CONFIG_POWER_SUPPLY=y
 | 
						|
+# CONFIG_POWER_SUPPLY_DEBUG is not set
 | 
						|
+# CONFIG_PDA_POWER is not set
 | 
						|
+# CONFIG_TEST_POWER is not set
 | 
						|
+# CONFIG_BATTERY_DS2780 is not set
 | 
						|
+# CONFIG_BATTERY_DS2781 is not set
 | 
						|
+# CONFIG_BATTERY_DS2782 is not set
 | 
						|
+# CONFIG_BATTERY_SBS is not set
 | 
						|
+# CONFIG_BATTERY_BQ27XXX is not set
 | 
						|
+# CONFIG_BATTERY_MAX17040 is not set
 | 
						|
+# CONFIG_BATTERY_MAX17042 is not set
 | 
						|
+# CONFIG_CHARGER_MAX8903 is not set
 | 
						|
+# CONFIG_CHARGER_LP8727 is not set
 | 
						|
+# CONFIG_CHARGER_GPIO is not set
 | 
						|
+# CONFIG_CHARGER_BQ2415X is not set
 | 
						|
+# CONFIG_CHARGER_BQ24190 is not set
 | 
						|
+# CONFIG_CHARGER_BQ24735 is not set
 | 
						|
+# CONFIG_CHARGER_BQ25890 is not set
 | 
						|
+# CONFIG_CHARGER_SMB347 is not set
 | 
						|
+# CONFIG_BATTERY_GAUGE_LTC2941 is not set
 | 
						|
+# CONFIG_CHARGER_RT9455 is not set
 | 
						|
+# CONFIG_POWER_RESET is not set
 | 
						|
+# CONFIG_POWER_AVS is not set
 | 
						|
+CONFIG_HWMON=y
 | 
						|
+CONFIG_HWMON_VID=m
 | 
						|
+# CONFIG_HWMON_DEBUG_CHIP is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Native drivers
 | 
						|
+#
 | 
						|
+# CONFIG_SENSORS_ABITUGURU is not set
 | 
						|
+# CONFIG_SENSORS_ABITUGURU3 is not set
 | 
						|
+# CONFIG_SENSORS_AD7414 is not set
 | 
						|
+# CONFIG_SENSORS_AD7418 is not set
 | 
						|
+# CONFIG_SENSORS_ADM1021 is not set
 | 
						|
+# CONFIG_SENSORS_ADM1025 is not set
 | 
						|
+# CONFIG_SENSORS_ADM1026 is not set
 | 
						|
+# CONFIG_SENSORS_ADM1029 is not set
 | 
						|
+# CONFIG_SENSORS_ADM1031 is not set
 | 
						|
+# CONFIG_SENSORS_ADM9240 is not set
 | 
						|
+# CONFIG_SENSORS_ADT7410 is not set
 | 
						|
+# CONFIG_SENSORS_ADT7411 is not set
 | 
						|
+# CONFIG_SENSORS_ADT7462 is not set
 | 
						|
+# CONFIG_SENSORS_ADT7470 is not set
 | 
						|
+# CONFIG_SENSORS_ADT7475 is not set
 | 
						|
+# CONFIG_SENSORS_ASC7621 is not set
 | 
						|
+# CONFIG_SENSORS_K8TEMP is not set
 | 
						|
+# CONFIG_SENSORS_K10TEMP is not set
 | 
						|
+# CONFIG_SENSORS_FAM15H_POWER is not set
 | 
						|
+# CONFIG_SENSORS_APPLESMC is not set
 | 
						|
+# CONFIG_SENSORS_ASB100 is not set
 | 
						|
+# CONFIG_SENSORS_ATXP1 is not set
 | 
						|
+# CONFIG_SENSORS_DS620 is not set
 | 
						|
+# CONFIG_SENSORS_DS1621 is not set
 | 
						|
+# CONFIG_SENSORS_DELL_SMM is not set
 | 
						|
+# CONFIG_SENSORS_I5K_AMB is not set
 | 
						|
+# CONFIG_SENSORS_F71805F is not set
 | 
						|
+# CONFIG_SENSORS_F71882FG is not set
 | 
						|
+# CONFIG_SENSORS_F75375S is not set
 | 
						|
+# CONFIG_SENSORS_FSCHMD is not set
 | 
						|
+# CONFIG_SENSORS_FTSTEUTATES is not set
 | 
						|
+# CONFIG_SENSORS_GL518SM is not set
 | 
						|
+# CONFIG_SENSORS_GL520SM is not set
 | 
						|
+# CONFIG_SENSORS_G760A is not set
 | 
						|
+# CONFIG_SENSORS_G762 is not set
 | 
						|
+# CONFIG_SENSORS_GPIO_FAN is not set
 | 
						|
+# CONFIG_SENSORS_HIH6130 is not set
 | 
						|
+# CONFIG_SENSORS_IBMAEM is not set
 | 
						|
+# CONFIG_SENSORS_IBMPEX is not set
 | 
						|
+# CONFIG_SENSORS_I5500 is not set
 | 
						|
+CONFIG_SENSORS_CORETEMP=m
 | 
						|
+CONFIG_SENSORS_IT87=m
 | 
						|
+# CONFIG_SENSORS_JC42 is not set
 | 
						|
+# CONFIG_SENSORS_POWR1220 is not set
 | 
						|
+# CONFIG_SENSORS_LINEAGE is not set
 | 
						|
+# CONFIG_SENSORS_LTC2945 is not set
 | 
						|
+# CONFIG_SENSORS_LTC2990 is not set
 | 
						|
+# CONFIG_SENSORS_LTC4151 is not set
 | 
						|
+# CONFIG_SENSORS_LTC4215 is not set
 | 
						|
+# CONFIG_SENSORS_LTC4222 is not set
 | 
						|
+# CONFIG_SENSORS_LTC4245 is not set
 | 
						|
+# CONFIG_SENSORS_LTC4260 is not set
 | 
						|
+# CONFIG_SENSORS_LTC4261 is not set
 | 
						|
+# CONFIG_SENSORS_MAX16065 is not set
 | 
						|
+# CONFIG_SENSORS_MAX1619 is not set
 | 
						|
+# CONFIG_SENSORS_MAX1668 is not set
 | 
						|
+# CONFIG_SENSORS_MAX197 is not set
 | 
						|
+# CONFIG_SENSORS_MAX6639 is not set
 | 
						|
+# CONFIG_SENSORS_MAX6642 is not set
 | 
						|
+# CONFIG_SENSORS_MAX6650 is not set
 | 
						|
+# CONFIG_SENSORS_MAX6697 is not set
 | 
						|
+# CONFIG_SENSORS_MAX31790 is not set
 | 
						|
+# CONFIG_SENSORS_MCP3021 is not set
 | 
						|
+# CONFIG_SENSORS_LM63 is not set
 | 
						|
+# CONFIG_SENSORS_LM73 is not set
 | 
						|
+# CONFIG_SENSORS_LM75 is not set
 | 
						|
+# CONFIG_SENSORS_LM77 is not set
 | 
						|
+# CONFIG_SENSORS_LM78 is not set
 | 
						|
+# CONFIG_SENSORS_LM80 is not set
 | 
						|
+# CONFIG_SENSORS_LM83 is not set
 | 
						|
+# CONFIG_SENSORS_LM85 is not set
 | 
						|
+# CONFIG_SENSORS_LM87 is not set
 | 
						|
+# CONFIG_SENSORS_LM90 is not set
 | 
						|
+# CONFIG_SENSORS_LM92 is not set
 | 
						|
+# CONFIG_SENSORS_LM93 is not set
 | 
						|
+# CONFIG_SENSORS_LM95234 is not set
 | 
						|
+# CONFIG_SENSORS_LM95241 is not set
 | 
						|
+# CONFIG_SENSORS_LM95245 is not set
 | 
						|
+# CONFIG_SENSORS_PC87360 is not set
 | 
						|
+# CONFIG_SENSORS_PC87427 is not set
 | 
						|
+# CONFIG_SENSORS_NTC_THERMISTOR is not set
 | 
						|
+# CONFIG_SENSORS_NCT6683 is not set
 | 
						|
+# CONFIG_SENSORS_NCT6775 is not set
 | 
						|
+# CONFIG_SENSORS_NCT7802 is not set
 | 
						|
+# CONFIG_SENSORS_NCT7904 is not set
 | 
						|
+# CONFIG_SENSORS_PCF8591 is not set
 | 
						|
+# CONFIG_PMBUS is not set
 | 
						|
+# CONFIG_SENSORS_SHT15 is not set
 | 
						|
+# CONFIG_SENSORS_SHT21 is not set
 | 
						|
+# CONFIG_SENSORS_SHT3x is not set
 | 
						|
+# CONFIG_SENSORS_SHTC1 is not set
 | 
						|
+# CONFIG_SENSORS_SIS5595 is not set
 | 
						|
+# CONFIG_SENSORS_DME1737 is not set
 | 
						|
+# CONFIG_SENSORS_EMC1403 is not set
 | 
						|
+# CONFIG_SENSORS_EMC2103 is not set
 | 
						|
+# CONFIG_SENSORS_EMC6W201 is not set
 | 
						|
+# CONFIG_SENSORS_SMSC47M1 is not set
 | 
						|
+# CONFIG_SENSORS_SMSC47M192 is not set
 | 
						|
+# CONFIG_SENSORS_SMSC47B397 is not set
 | 
						|
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
 | 
						|
+# CONFIG_SENSORS_SCH5627 is not set
 | 
						|
+# CONFIG_SENSORS_SCH5636 is not set
 | 
						|
+# CONFIG_SENSORS_SMM665 is not set
 | 
						|
+# CONFIG_SENSORS_ADC128D818 is not set
 | 
						|
+# CONFIG_SENSORS_ADS1015 is not set
 | 
						|
+# CONFIG_SENSORS_ADS7828 is not set
 | 
						|
+# CONFIG_SENSORS_AMC6821 is not set
 | 
						|
+# CONFIG_SENSORS_INA209 is not set
 | 
						|
+# CONFIG_SENSORS_INA2XX is not set
 | 
						|
+# CONFIG_SENSORS_INA3221 is not set
 | 
						|
+# CONFIG_SENSORS_TC74 is not set
 | 
						|
+# CONFIG_SENSORS_THMC50 is not set
 | 
						|
+# CONFIG_SENSORS_TMP102 is not set
 | 
						|
+# CONFIG_SENSORS_TMP103 is not set
 | 
						|
+# CONFIG_SENSORS_TMP401 is not set
 | 
						|
+# CONFIG_SENSORS_TMP421 is not set
 | 
						|
+# CONFIG_SENSORS_VIA_CPUTEMP is not set
 | 
						|
+# CONFIG_SENSORS_VIA686A is not set
 | 
						|
+# CONFIG_SENSORS_VT1211 is not set
 | 
						|
+# CONFIG_SENSORS_VT8231 is not set
 | 
						|
+# CONFIG_SENSORS_W83781D is not set
 | 
						|
+# CONFIG_SENSORS_W83791D is not set
 | 
						|
+# CONFIG_SENSORS_W83792D is not set
 | 
						|
+# CONFIG_SENSORS_W83793 is not set
 | 
						|
+# CONFIG_SENSORS_W83795 is not set
 | 
						|
+# CONFIG_SENSORS_W83L785TS is not set
 | 
						|
+# CONFIG_SENSORS_W83L786NG is not set
 | 
						|
+# CONFIG_SENSORS_W83627HF is not set
 | 
						|
+# CONFIG_SENSORS_W83627EHF is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# ACPI drivers
 | 
						|
+#
 | 
						|
+# CONFIG_SENSORS_ACPI_POWER is not set
 | 
						|
+# CONFIG_SENSORS_ATK0110 is not set
 | 
						|
+CONFIG_THERMAL=y
 | 
						|
+CONFIG_THERMAL_HWMON=y
 | 
						|
+CONFIG_THERMAL_WRITABLE_TRIPS=y
 | 
						|
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
 | 
						|
+# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
 | 
						|
+# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
 | 
						|
+# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set
 | 
						|
+# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
 | 
						|
+CONFIG_THERMAL_GOV_STEP_WISE=y
 | 
						|
+# CONFIG_THERMAL_GOV_BANG_BANG is not set
 | 
						|
+CONFIG_THERMAL_GOV_USER_SPACE=y
 | 
						|
+# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set
 | 
						|
+# CONFIG_THERMAL_EMULATION is not set
 | 
						|
+# CONFIG_INTEL_POWERCLAMP is not set
 | 
						|
+CONFIG_X86_PKG_TEMP_THERMAL=m
 | 
						|
+# CONFIG_INTEL_SOC_DTS_THERMAL is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# ACPI INT340X thermal drivers
 | 
						|
+#
 | 
						|
+# CONFIG_INT340X_THERMAL is not set
 | 
						|
+# CONFIG_INTEL_PCH_THERMAL is not set
 | 
						|
+CONFIG_WATCHDOG=y
 | 
						|
+CONFIG_WATCHDOG_CORE=y
 | 
						|
+# CONFIG_WATCHDOG_NOWAYOUT is not set
 | 
						|
+# CONFIG_WATCHDOG_SYSFS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Watchdog Device Drivers
 | 
						|
+#
 | 
						|
+# CONFIG_SOFT_WATCHDOG is not set
 | 
						|
+# CONFIG_XILINX_WATCHDOG is not set
 | 
						|
+# CONFIG_ZIIRAVE_WATCHDOG is not set
 | 
						|
+# CONFIG_CADENCE_WATCHDOG is not set
 | 
						|
+# CONFIG_DW_WATCHDOG is not set
 | 
						|
+# CONFIG_MAX63XX_WATCHDOG is not set
 | 
						|
+# CONFIG_ACQUIRE_WDT is not set
 | 
						|
+# CONFIG_ADVANTECH_WDT is not set
 | 
						|
+# CONFIG_ALIM1535_WDT is not set
 | 
						|
+# CONFIG_ALIM7101_WDT is not set
 | 
						|
+# CONFIG_F71808E_WDT is not set
 | 
						|
+CONFIG_SP5100_TCO=y
 | 
						|
+# CONFIG_SBC_FITPC2_WATCHDOG is not set
 | 
						|
+# CONFIG_EUROTECH_WDT is not set
 | 
						|
+# CONFIG_IB700_WDT is not set
 | 
						|
+# CONFIG_IBMASR is not set
 | 
						|
+# CONFIG_WAFER_WDT is not set
 | 
						|
+# CONFIG_I6300ESB_WDT is not set
 | 
						|
+# CONFIG_IE6XX_WDT is not set
 | 
						|
+CONFIG_ITCO_WDT=m
 | 
						|
+# CONFIG_ITCO_VENDOR_SUPPORT is not set
 | 
						|
+CONFIG_IT8712F_WDT=m
 | 
						|
+# CONFIG_IT87_WDT is not set
 | 
						|
+# CONFIG_HP_WATCHDOG is not set
 | 
						|
+# CONFIG_SC1200_WDT is not set
 | 
						|
+# CONFIG_PC87413_WDT is not set
 | 
						|
+CONFIG_NV_TCO=y
 | 
						|
+# CONFIG_60XX_WDT is not set
 | 
						|
+# CONFIG_CPU5_WDT is not set
 | 
						|
+# CONFIG_SMSC_SCH311X_WDT is not set
 | 
						|
+# CONFIG_SMSC37B787_WDT is not set
 | 
						|
+# CONFIG_VIA_WDT is not set
 | 
						|
+# CONFIG_W83627HF_WDT is not set
 | 
						|
+# CONFIG_W83877F_WDT is not set
 | 
						|
+# CONFIG_W83977F_WDT is not set
 | 
						|
+# CONFIG_MACHZ_WDT is not set
 | 
						|
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
 | 
						|
+# CONFIG_NI903X_WDT is not set
 | 
						|
+# CONFIG_MEN_A21_WDT is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PCI-based Watchdog Cards
 | 
						|
+#
 | 
						|
+# CONFIG_PCIPCWATCHDOG is not set
 | 
						|
+# CONFIG_WDTPCI is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# USB-based Watchdog Cards
 | 
						|
+#
 | 
						|
+# CONFIG_USBPCWATCHDOG is not set
 | 
						|
+CONFIG_SSB_POSSIBLE=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Sonics Silicon Backplane
 | 
						|
+#
 | 
						|
+# CONFIG_SSB is not set
 | 
						|
+CONFIG_BCMA_POSSIBLE=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Broadcom specific AMBA
 | 
						|
+#
 | 
						|
+# CONFIG_BCMA is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Multifunction device drivers
 | 
						|
+#
 | 
						|
+CONFIG_MFD_CORE=y
 | 
						|
+# CONFIG_MFD_BCM590XX is not set
 | 
						|
+# CONFIG_MFD_AXP20X_I2C is not set
 | 
						|
+# CONFIG_MFD_CROS_EC is not set
 | 
						|
+# CONFIG_MFD_DA9062 is not set
 | 
						|
+# CONFIG_MFD_DA9063 is not set
 | 
						|
+# CONFIG_MFD_DA9150 is not set
 | 
						|
+# CONFIG_MFD_DLN2 is not set
 | 
						|
+# CONFIG_MFD_MC13XXX_I2C is not set
 | 
						|
+# CONFIG_HTC_PASIC3 is not set
 | 
						|
+CONFIG_LPC_ICH=y
 | 
						|
+# CONFIG_LPC_SCH is not set
 | 
						|
+# CONFIG_MFD_INTEL_LPSS_ACPI is not set
 | 
						|
+# CONFIG_MFD_INTEL_LPSS_PCI is not set
 | 
						|
+# CONFIG_MFD_JANZ_CMODIO is not set
 | 
						|
+# CONFIG_MFD_KEMPLD is not set
 | 
						|
+# CONFIG_MFD_88PM800 is not set
 | 
						|
+# CONFIG_MFD_88PM805 is not set
 | 
						|
+# CONFIG_MFD_MAX14577 is not set
 | 
						|
+# CONFIG_MFD_MAX77693 is not set
 | 
						|
+# CONFIG_MFD_MAX8907 is not set
 | 
						|
+# CONFIG_MFD_MT6397 is not set
 | 
						|
+# CONFIG_MFD_MENF21BMC is not set
 | 
						|
+# CONFIG_MFD_VIPERBOARD is not set
 | 
						|
+# CONFIG_MFD_RETU is not set
 | 
						|
+# CONFIG_MFD_PCF50633 is not set
 | 
						|
+# CONFIG_MFD_RDC321X is not set
 | 
						|
+# CONFIG_MFD_RTSX_PCI is not set
 | 
						|
+# CONFIG_MFD_RT5033 is not set
 | 
						|
+# CONFIG_MFD_RTSX_USB is not set
 | 
						|
+# CONFIG_MFD_SI476X_CORE is not set
 | 
						|
+# CONFIG_MFD_SM501 is not set
 | 
						|
+# CONFIG_MFD_SKY81452 is not set
 | 
						|
+# CONFIG_ABX500_CORE is not set
 | 
						|
+# CONFIG_MFD_SYSCON is not set
 | 
						|
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
 | 
						|
+# CONFIG_MFD_LP3943 is not set
 | 
						|
+# CONFIG_TPS6105X is not set
 | 
						|
+# CONFIG_TPS65010 is not set
 | 
						|
+# CONFIG_TPS6507X is not set
 | 
						|
+# CONFIG_MFD_TPS65086 is not set
 | 
						|
+# CONFIG_MFD_TPS65217 is not set
 | 
						|
+# CONFIG_MFD_TPS65218 is not set
 | 
						|
+# CONFIG_MFD_TPS65912_I2C is not set
 | 
						|
+# CONFIG_MFD_WL1273_CORE is not set
 | 
						|
+# CONFIG_MFD_LM3533 is not set
 | 
						|
+# CONFIG_MFD_TMIO is not set
 | 
						|
+# CONFIG_MFD_VX855 is not set
 | 
						|
+# CONFIG_MFD_ARIZONA_I2C is not set
 | 
						|
+# CONFIG_MFD_WM8994 is not set
 | 
						|
+# CONFIG_REGULATOR is not set
 | 
						|
+# CONFIG_MEDIA_SUPPORT is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Graphics support
 | 
						|
+#
 | 
						|
+CONFIG_AGP=y
 | 
						|
+CONFIG_AGP_AMD64=y
 | 
						|
+# CONFIG_AGP_INTEL is not set
 | 
						|
+# CONFIG_AGP_SIS is not set
 | 
						|
+# CONFIG_AGP_VIA is not set
 | 
						|
+CONFIG_VGA_ARB=y
 | 
						|
+CONFIG_VGA_ARB_MAX_GPUS=16
 | 
						|
+# CONFIG_VGA_SWITCHEROO is not set
 | 
						|
+# CONFIG_DRM is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# ACP (Audio CoProcessor) Configuration
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Frame buffer Devices
 | 
						|
+#
 | 
						|
+# CONFIG_FB is not set
 | 
						|
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 | 
						|
+# CONFIG_VGASTATE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Console display driver support
 | 
						|
+#
 | 
						|
+CONFIG_VGA_CONSOLE=y
 | 
						|
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
 | 
						|
+CONFIG_DUMMY_CONSOLE=y
 | 
						|
+CONFIG_DUMMY_CONSOLE_COLUMNS=80
 | 
						|
+CONFIG_DUMMY_CONSOLE_ROWS=25
 | 
						|
+# CONFIG_SOUND is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# HID support
 | 
						|
+#
 | 
						|
+CONFIG_HID=y
 | 
						|
+# CONFIG_HID_BATTERY_STRENGTH is not set
 | 
						|
+CONFIG_HIDRAW=y
 | 
						|
+# CONFIG_UHID is not set
 | 
						|
+CONFIG_HID_GENERIC=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Special HID drivers
 | 
						|
+#
 | 
						|
+# CONFIG_HID_A4TECH is not set
 | 
						|
+# CONFIG_HID_ACRUX is not set
 | 
						|
+# CONFIG_HID_APPLE is not set
 | 
						|
+# CONFIG_HID_APPLEIR is not set
 | 
						|
+# CONFIG_HID_AUREAL is not set
 | 
						|
+# CONFIG_HID_BELKIN is not set
 | 
						|
+# CONFIG_HID_BETOP_FF is not set
 | 
						|
+# CONFIG_HID_CHERRY is not set
 | 
						|
+# CONFIG_HID_CHICONY is not set
 | 
						|
+# CONFIG_HID_CMEDIA is not set
 | 
						|
+# CONFIG_HID_CP2112 is not set
 | 
						|
+# CONFIG_HID_CYPRESS is not set
 | 
						|
+# CONFIG_HID_DRAGONRISE is not set
 | 
						|
+# CONFIG_HID_EMS_FF is not set
 | 
						|
+# CONFIG_HID_ELECOM is not set
 | 
						|
+# CONFIG_HID_ELO is not set
 | 
						|
+# CONFIG_HID_EZKEY is not set
 | 
						|
+# CONFIG_HID_GEMBIRD is not set
 | 
						|
+# CONFIG_HID_GFRM is not set
 | 
						|
+# CONFIG_HID_HOLTEK is not set
 | 
						|
+# CONFIG_HID_KEYTOUCH is not set
 | 
						|
+# CONFIG_HID_KYE is not set
 | 
						|
+# CONFIG_HID_UCLOGIC is not set
 | 
						|
+# CONFIG_HID_WALTOP is not set
 | 
						|
+# CONFIG_HID_GYRATION is not set
 | 
						|
+# CONFIG_HID_ICADE is not set
 | 
						|
+# CONFIG_HID_TWINHAN is not set
 | 
						|
+# CONFIG_HID_KENSINGTON is not set
 | 
						|
+# CONFIG_HID_LCPOWER is not set
 | 
						|
+# CONFIG_HID_LENOVO is not set
 | 
						|
+# CONFIG_HID_LOGITECH is not set
 | 
						|
+# CONFIG_HID_MAGICMOUSE is not set
 | 
						|
+# CONFIG_HID_MICROSOFT is not set
 | 
						|
+# CONFIG_HID_MONTEREY is not set
 | 
						|
+# CONFIG_HID_MULTITOUCH is not set
 | 
						|
+# CONFIG_HID_NTRIG is not set
 | 
						|
+# CONFIG_HID_ORTEK is not set
 | 
						|
+# CONFIG_HID_PANTHERLORD is not set
 | 
						|
+# CONFIG_HID_PENMOUNT is not set
 | 
						|
+# CONFIG_HID_PETALYNX is not set
 | 
						|
+# CONFIG_HID_PICOLCD is not set
 | 
						|
+# CONFIG_HID_PLANTRONICS is not set
 | 
						|
+# CONFIG_HID_PRIMAX is not set
 | 
						|
+# CONFIG_HID_ROCCAT is not set
 | 
						|
+# CONFIG_HID_SAITEK is not set
 | 
						|
+# CONFIG_HID_SAMSUNG is not set
 | 
						|
+# CONFIG_HID_SPEEDLINK is not set
 | 
						|
+# CONFIG_HID_STEELSERIES is not set
 | 
						|
+# CONFIG_HID_SUNPLUS is not set
 | 
						|
+# CONFIG_HID_RMI is not set
 | 
						|
+# CONFIG_HID_GREENASIA is not set
 | 
						|
+# CONFIG_HID_SMARTJOYPLUS is not set
 | 
						|
+# CONFIG_HID_TIVO is not set
 | 
						|
+# CONFIG_HID_TOPSEED is not set
 | 
						|
+# CONFIG_HID_THRUSTMASTER is not set
 | 
						|
+# CONFIG_HID_WACOM is not set
 | 
						|
+# CONFIG_HID_XINMO is not set
 | 
						|
+# CONFIG_HID_ZEROPLUS is not set
 | 
						|
+# CONFIG_HID_ZYDACRON is not set
 | 
						|
+# CONFIG_HID_SENSOR_HUB is not set
 | 
						|
+# CONFIG_HID_ALPS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# USB HID support
 | 
						|
+#
 | 
						|
+CONFIG_USB_HID=y
 | 
						|
+CONFIG_HID_PID=y
 | 
						|
+CONFIG_USB_HIDDEV=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# I2C HID support
 | 
						|
+#
 | 
						|
+# CONFIG_I2C_HID is not set
 | 
						|
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 | 
						|
+CONFIG_USB_SUPPORT=y
 | 
						|
+CONFIG_USB_COMMON=y
 | 
						|
+CONFIG_USB_ARCH_HAS_HCD=y
 | 
						|
+CONFIG_USB=y
 | 
						|
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Miscellaneous USB options
 | 
						|
+#
 | 
						|
+CONFIG_USB_DEFAULT_PERSIST=y
 | 
						|
+# CONFIG_USB_DYNAMIC_MINORS is not set
 | 
						|
+# CONFIG_USB_OTG is not set
 | 
						|
+# CONFIG_USB_OTG_WHITELIST is not set
 | 
						|
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
 | 
						|
+# CONFIG_USB_ULPI_BUS is not set
 | 
						|
+CONFIG_USB_MON=y
 | 
						|
+# CONFIG_USB_WUSB_CBAF is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# USB Host Controller Drivers
 | 
						|
+#
 | 
						|
+# CONFIG_USB_C67X00_HCD is not set
 | 
						|
+# CONFIG_USB_XHCI_HCD is not set
 | 
						|
+CONFIG_USB_EHCI_HCD=m
 | 
						|
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 | 
						|
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
 | 
						|
+CONFIG_USB_EHCI_PCI=m
 | 
						|
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
 | 
						|
+# CONFIG_USB_OXU210HP_HCD is not set
 | 
						|
+# CONFIG_USB_ISP116X_HCD is not set
 | 
						|
+# CONFIG_USB_ISP1362_HCD is not set
 | 
						|
+# CONFIG_USB_FOTG210_HCD is not set
 | 
						|
+CONFIG_USB_OHCI_HCD=m
 | 
						|
+CONFIG_USB_OHCI_HCD_PCI=m
 | 
						|
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
 | 
						|
+CONFIG_USB_UHCI_HCD=m
 | 
						|
+# CONFIG_USB_SL811_HCD is not set
 | 
						|
+# CONFIG_USB_R8A66597_HCD is not set
 | 
						|
+# CONFIG_USB_HCD_TEST_MODE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# USB Device Class drivers
 | 
						|
+#
 | 
						|
+CONFIG_USB_ACM=m
 | 
						|
+# CONFIG_USB_PRINTER is not set
 | 
						|
+# CONFIG_USB_WDM is not set
 | 
						|
+# CONFIG_USB_TMC is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# also be needed; see USB_STORAGE Help for more info
 | 
						|
+#
 | 
						|
+CONFIG_USB_STORAGE=m
 | 
						|
+# CONFIG_USB_STORAGE_DEBUG is not set
 | 
						|
+# CONFIG_USB_STORAGE_REALTEK is not set
 | 
						|
+# CONFIG_USB_STORAGE_DATAFAB is not set
 | 
						|
+# CONFIG_USB_STORAGE_FREECOM is not set
 | 
						|
+# CONFIG_USB_STORAGE_ISD200 is not set
 | 
						|
+# CONFIG_USB_STORAGE_USBAT is not set
 | 
						|
+# CONFIG_USB_STORAGE_SDDR09 is not set
 | 
						|
+# CONFIG_USB_STORAGE_SDDR55 is not set
 | 
						|
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
 | 
						|
+# CONFIG_USB_STORAGE_ALAUDA is not set
 | 
						|
+# CONFIG_USB_STORAGE_ONETOUCH is not set
 | 
						|
+# CONFIG_USB_STORAGE_KARMA is not set
 | 
						|
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 | 
						|
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
 | 
						|
+# CONFIG_USB_UAS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# USB Imaging devices
 | 
						|
+#
 | 
						|
+# CONFIG_USB_MDC800 is not set
 | 
						|
+# CONFIG_USB_MICROTEK is not set
 | 
						|
+# CONFIG_USBIP_CORE is not set
 | 
						|
+# CONFIG_USB_MUSB_HDRC is not set
 | 
						|
+# CONFIG_USB_DWC3 is not set
 | 
						|
+# CONFIG_USB_DWC2 is not set
 | 
						|
+# CONFIG_USB_CHIPIDEA is not set
 | 
						|
+# CONFIG_USB_ISP1760 is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# USB port drivers
 | 
						|
+#
 | 
						|
+CONFIG_USB_SERIAL=m
 | 
						|
+CONFIG_USB_SERIAL_GENERIC=y
 | 
						|
+# CONFIG_USB_SERIAL_SIMPLE is not set
 | 
						|
+# CONFIG_USB_SERIAL_AIRCABLE is not set
 | 
						|
+# CONFIG_USB_SERIAL_ARK3116 is not set
 | 
						|
+# CONFIG_USB_SERIAL_BELKIN is not set
 | 
						|
+# CONFIG_USB_SERIAL_CH341 is not set
 | 
						|
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
 | 
						|
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
 | 
						|
+# CONFIG_USB_SERIAL_CP210X is not set
 | 
						|
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 | 
						|
+# CONFIG_USB_SERIAL_EMPEG is not set
 | 
						|
+CONFIG_USB_SERIAL_FTDI_SIO=m
 | 
						|
+# CONFIG_USB_SERIAL_VISOR is not set
 | 
						|
+# CONFIG_USB_SERIAL_IPAQ is not set
 | 
						|
+# CONFIG_USB_SERIAL_IR is not set
 | 
						|
+# CONFIG_USB_SERIAL_EDGEPORT is not set
 | 
						|
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
 | 
						|
+# CONFIG_USB_SERIAL_F81232 is not set
 | 
						|
+# CONFIG_USB_SERIAL_GARMIN is not set
 | 
						|
+# CONFIG_USB_SERIAL_IPW is not set
 | 
						|
+# CONFIG_USB_SERIAL_IUU is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
 | 
						|
+CONFIG_USB_SERIAL_KEYSPAN=m
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
 | 
						|
+# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
 | 
						|
+# CONFIG_USB_SERIAL_KLSI is not set
 | 
						|
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
 | 
						|
+# CONFIG_USB_SERIAL_MCT_U232 is not set
 | 
						|
+# CONFIG_USB_SERIAL_METRO is not set
 | 
						|
+# CONFIG_USB_SERIAL_MOS7720 is not set
 | 
						|
+# CONFIG_USB_SERIAL_MOS7840 is not set
 | 
						|
+# CONFIG_USB_SERIAL_MXUPORT is not set
 | 
						|
+# CONFIG_USB_SERIAL_NAVMAN is not set
 | 
						|
+CONFIG_USB_SERIAL_PL2303=m
 | 
						|
+# CONFIG_USB_SERIAL_OTI6858 is not set
 | 
						|
+# CONFIG_USB_SERIAL_QCAUX is not set
 | 
						|
+# CONFIG_USB_SERIAL_QUALCOMM is not set
 | 
						|
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
 | 
						|
+# CONFIG_USB_SERIAL_SAFE is not set
 | 
						|
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 | 
						|
+# CONFIG_USB_SERIAL_SYMBOL is not set
 | 
						|
+# CONFIG_USB_SERIAL_TI is not set
 | 
						|
+# CONFIG_USB_SERIAL_CYBERJACK is not set
 | 
						|
+# CONFIG_USB_SERIAL_XIRCOM is not set
 | 
						|
+# CONFIG_USB_SERIAL_OPTION is not set
 | 
						|
+# CONFIG_USB_SERIAL_OMNINET is not set
 | 
						|
+# CONFIG_USB_SERIAL_OPTICON is not set
 | 
						|
+# CONFIG_USB_SERIAL_XSENS_MT is not set
 | 
						|
+# CONFIG_USB_SERIAL_WISHBONE is not set
 | 
						|
+# CONFIG_USB_SERIAL_SSU100 is not set
 | 
						|
+# CONFIG_USB_SERIAL_QT2 is not set
 | 
						|
+# CONFIG_USB_SERIAL_DEBUG is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# USB Miscellaneous drivers
 | 
						|
+#
 | 
						|
+# CONFIG_USB_EMI62 is not set
 | 
						|
+# CONFIG_USB_EMI26 is not set
 | 
						|
+# CONFIG_USB_ADUTUX is not set
 | 
						|
+# CONFIG_USB_SEVSEG is not set
 | 
						|
+# CONFIG_USB_RIO500 is not set
 | 
						|
+# CONFIG_USB_LEGOTOWER is not set
 | 
						|
+# CONFIG_USB_LCD is not set
 | 
						|
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 | 
						|
+# CONFIG_USB_CYTHERM is not set
 | 
						|
+# CONFIG_USB_IDMOUSE is not set
 | 
						|
+# CONFIG_USB_FTDI_ELAN is not set
 | 
						|
+# CONFIG_USB_APPLEDISPLAY is not set
 | 
						|
+# CONFIG_USB_SISUSBVGA is not set
 | 
						|
+# CONFIG_USB_LD is not set
 | 
						|
+# CONFIG_USB_TRANCEVIBRATOR is not set
 | 
						|
+# CONFIG_USB_IOWARRIOR is not set
 | 
						|
+CONFIG_USB_TEST=m
 | 
						|
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
 | 
						|
+# CONFIG_USB_ISIGHTFW is not set
 | 
						|
+# CONFIG_USB_YUREX is not set
 | 
						|
+CONFIG_USB_EZUSB_FX2=m
 | 
						|
+# CONFIG_USB_HSIC_USB3503 is not set
 | 
						|
+# CONFIG_USB_LINK_LAYER_TEST is not set
 | 
						|
+# CONFIG_UCSI is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# USB Physical Layer drivers
 | 
						|
+#
 | 
						|
+# CONFIG_USB_PHY is not set
 | 
						|
+# CONFIG_NOP_USB_XCEIV is not set
 | 
						|
+# CONFIG_USB_GPIO_VBUS is not set
 | 
						|
+# CONFIG_USB_ISP1301 is not set
 | 
						|
+# CONFIG_USB_GADGET is not set
 | 
						|
+# CONFIG_UWB is not set
 | 
						|
+# CONFIG_MMC is not set
 | 
						|
+# CONFIG_MEMSTICK is not set
 | 
						|
+# CONFIG_NEW_LEDS is not set
 | 
						|
+# CONFIG_ACCESSIBILITY is not set
 | 
						|
+CONFIG_INFINIBAND=m
 | 
						|
+CONFIG_INFINIBAND_USER_MAD=m
 | 
						|
+CONFIG_INFINIBAND_USER_ACCESS=m
 | 
						|
+CONFIG_INFINIBAND_USER_MEM=y
 | 
						|
+CONFIG_INFINIBAND_ON_DEMAND_PAGING=y
 | 
						|
+CONFIG_INFINIBAND_ADDR_TRANS=y
 | 
						|
+CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y
 | 
						|
+# CONFIG_INFINIBAND_MTHCA is not set
 | 
						|
+# CONFIG_INFINIBAND_QIB is not set
 | 
						|
+# CONFIG_INFINIBAND_CXGB3 is not set
 | 
						|
+CONFIG_MLX4_INFINIBAND=m
 | 
						|
+# CONFIG_INFINIBAND_NES is not set
 | 
						|
+# CONFIG_INFINIBAND_OCRDMA is not set
 | 
						|
+# CONFIG_INFINIBAND_USNIC is not set
 | 
						|
+# CONFIG_INFINIBAND_IPOIB is not set
 | 
						|
+# CONFIG_INFINIBAND_SRP is not set
 | 
						|
+# CONFIG_INFINIBAND_ISER is not set
 | 
						|
+CONFIG_INFINIBAND_RDMAVT=m
 | 
						|
+CONFIG_INFINIBAND_HFI1=m
 | 
						|
+# CONFIG_HFI1_DEBUG_SDMA_ORDER is not set
 | 
						|
+CONFIG_HFI1_VERBS_31BIT_PSN=y
 | 
						|
+# CONFIG_SDMA_VERBOSITY is not set
 | 
						|
+CONFIG_EDAC_ATOMIC_SCRUB=y
 | 
						|
+CONFIG_EDAC_SUPPORT=y
 | 
						|
+# CONFIG_EDAC is not set
 | 
						|
+CONFIG_RTC_LIB=y
 | 
						|
+CONFIG_RTC_MC146818_LIB=y
 | 
						|
+# CONFIG_RTC_CLASS is not set
 | 
						|
+CONFIG_DMADEVICES=y
 | 
						|
+# CONFIG_DMADEVICES_DEBUG is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# DMA Devices
 | 
						|
+#
 | 
						|
+CONFIG_DMA_ACPI=y
 | 
						|
+# CONFIG_INTEL_IDMA64 is not set
 | 
						|
+# CONFIG_INTEL_IOATDMA is not set
 | 
						|
+# CONFIG_QCOM_HIDMA_MGMT is not set
 | 
						|
+# CONFIG_QCOM_HIDMA is not set
 | 
						|
+# CONFIG_DW_DMAC is not set
 | 
						|
+# CONFIG_DW_DMAC_PCI is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# DMABUF options
 | 
						|
+#
 | 
						|
+# CONFIG_SYNC_FILE is not set
 | 
						|
+# CONFIG_AUXDISPLAY is not set
 | 
						|
+# CONFIG_UIO is not set
 | 
						|
+# CONFIG_VFIO is not set
 | 
						|
+CONFIG_IRQ_BYPASS_MANAGER=y
 | 
						|
+# CONFIG_VIRT_DRIVERS is not set
 | 
						|
+CONFIG_VIRTIO=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Virtio drivers
 | 
						|
+#
 | 
						|
+CONFIG_VIRTIO_PCI=y
 | 
						|
+CONFIG_VIRTIO_PCI_LEGACY=y
 | 
						|
+# CONFIG_VIRTIO_BALLOON is not set
 | 
						|
+# CONFIG_VIRTIO_INPUT is not set
 | 
						|
+# CONFIG_VIRTIO_MMIO is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Microsoft Hyper-V guest support
 | 
						|
+#
 | 
						|
+# CONFIG_HYPERV is not set
 | 
						|
+# CONFIG_STAGING is not set
 | 
						|
+CONFIG_X86_PLATFORM_DEVICES=y
 | 
						|
+# CONFIG_ACERHDF is not set
 | 
						|
+# CONFIG_DELL_SMBIOS is not set
 | 
						|
+# CONFIG_DELL_SMO8800 is not set
 | 
						|
+# CONFIG_FUJITSU_TABLET is not set
 | 
						|
+# CONFIG_HP_ACCEL is not set
 | 
						|
+# CONFIG_HP_WIRELESS is not set
 | 
						|
+# CONFIG_SENSORS_HDAPS is not set
 | 
						|
+# CONFIG_INTEL_MENLOW is not set
 | 
						|
+# CONFIG_ASUS_WIRELESS is not set
 | 
						|
+# CONFIG_ACPI_WMI is not set
 | 
						|
+# CONFIG_TOPSTAR_LAPTOP is not set
 | 
						|
+# CONFIG_TOSHIBA_BT_RFKILL is not set
 | 
						|
+# CONFIG_TOSHIBA_HAPS is not set
 | 
						|
+# CONFIG_ACPI_CMPC is not set
 | 
						|
+CONFIG_INTEL_HID_EVENT=m
 | 
						|
+# CONFIG_INTEL_VBTN is not set
 | 
						|
+# CONFIG_INTEL_IPS is not set
 | 
						|
+# CONFIG_INTEL_PMC_CORE is not set
 | 
						|
+# CONFIG_IBM_RTL is not set
 | 
						|
+# CONFIG_SAMSUNG_Q10 is not set
 | 
						|
+# CONFIG_INTEL_RST is not set
 | 
						|
+# CONFIG_INTEL_SMARTCONNECT is not set
 | 
						|
+# CONFIG_PVPANIC is not set
 | 
						|
+# CONFIG_INTEL_PMC_IPC is not set
 | 
						|
+# CONFIG_SURFACE_PRO3_BUTTON is not set
 | 
						|
+CONFIG_INTEL_PUNIT_IPC=m
 | 
						|
+# CONFIG_CHROME_PLATFORMS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Hardware Spinlock drivers
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Clock Source drivers
 | 
						|
+#
 | 
						|
+CONFIG_CLKEVT_I8253=y
 | 
						|
+CONFIG_I8253_LOCK=y
 | 
						|
+CONFIG_CLKBLD_I8253=y
 | 
						|
+# CONFIG_ATMEL_PIT is not set
 | 
						|
+# CONFIG_SH_TIMER_CMT is not set
 | 
						|
+# CONFIG_SH_TIMER_MTU2 is not set
 | 
						|
+# CONFIG_SH_TIMER_TMU is not set
 | 
						|
+# CONFIG_EM_TIMER_STI is not set
 | 
						|
+# CONFIG_MAILBOX is not set
 | 
						|
+CONFIG_IOMMU_API=y
 | 
						|
+CONFIG_IOMMU_SUPPORT=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Generic IOMMU Pagetable Support
 | 
						|
+#
 | 
						|
+CONFIG_IOMMU_IOVA=y
 | 
						|
+CONFIG_AMD_IOMMU=y
 | 
						|
+# CONFIG_AMD_IOMMU_V2 is not set
 | 
						|
+CONFIG_DMAR_TABLE=y
 | 
						|
+CONFIG_INTEL_IOMMU=y
 | 
						|
+# CONFIG_INTEL_IOMMU_SVM is not set
 | 
						|
+# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set
 | 
						|
+CONFIG_INTEL_IOMMU_FLOPPY_WA=y
 | 
						|
+CONFIG_IRQ_REMAP=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Remoteproc drivers
 | 
						|
+#
 | 
						|
+# CONFIG_STE_MODEM_RPROC is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Rpmsg drivers
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# SOC (System On Chip) specific Drivers
 | 
						|
+#
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Broadcom SoC drivers
 | 
						|
+#
 | 
						|
+# CONFIG_SUNXI_SRAM is not set
 | 
						|
+# CONFIG_SOC_TI is not set
 | 
						|
+# CONFIG_PM_DEVFREQ is not set
 | 
						|
+# CONFIG_EXTCON is not set
 | 
						|
+# CONFIG_MEMORY is not set
 | 
						|
+# CONFIG_IIO is not set
 | 
						|
+# CONFIG_NTB is not set
 | 
						|
+# CONFIG_VME_BUS is not set
 | 
						|
+# CONFIG_PWM is not set
 | 
						|
+CONFIG_ARM_GIC_MAX_NR=1
 | 
						|
+# CONFIG_IPACK_BUS is not set
 | 
						|
+# CONFIG_RESET_CONTROLLER is not set
 | 
						|
+# CONFIG_FMC is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# PHY Subsystem
 | 
						|
+#
 | 
						|
+CONFIG_GENERIC_PHY=y
 | 
						|
+# CONFIG_PHY_PXA_28NM_HSIC is not set
 | 
						|
+# CONFIG_PHY_PXA_28NM_USB2 is not set
 | 
						|
+# CONFIG_BCM_KONA_USB2_PHY is not set
 | 
						|
+# CONFIG_POWERCAP is not set
 | 
						|
+# CONFIG_MCB is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Performance monitor support
 | 
						|
+#
 | 
						|
+# CONFIG_RAS is not set
 | 
						|
+# CONFIG_THUNDERBOLT is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Android
 | 
						|
+#
 | 
						|
+# CONFIG_ANDROID is not set
 | 
						|
+# CONFIG_LIBNVDIMM is not set
 | 
						|
+# CONFIG_DEV_DAX is not set
 | 
						|
+# CONFIG_NVMEM is not set
 | 
						|
+# CONFIG_STM is not set
 | 
						|
+# CONFIG_INTEL_TH is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# FPGA Configuration Support
 | 
						|
+#
 | 
						|
+# CONFIG_FPGA is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Firmware Drivers
 | 
						|
+#
 | 
						|
+# CONFIG_EDD is not set
 | 
						|
+CONFIG_FIRMWARE_MEMMAP=y
 | 
						|
+CONFIG_DELL_RBU=m
 | 
						|
+CONFIG_DCDBAS=m
 | 
						|
+CONFIG_DMIID=y
 | 
						|
+# CONFIG_DMI_SYSFS is not set
 | 
						|
+CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
 | 
						|
+CONFIG_ISCSI_IBFT_FIND=y
 | 
						|
+# CONFIG_ISCSI_IBFT is not set
 | 
						|
+# CONFIG_FW_CFG_SYSFS is not set
 | 
						|
+CONFIG_GOOGLE_FIRMWARE=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Google Firmware Drivers
 | 
						|
+#
 | 
						|
+CONFIG_GOOGLE_SMI=y
 | 
						|
+CONFIG_GOOGLE_MEMCONSOLE=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# EFI (Extensible Firmware Interface) Support
 | 
						|
+#
 | 
						|
+CONFIG_EFI_VARS=y
 | 
						|
+CONFIG_EFI_ESRT=y
 | 
						|
+CONFIG_EFI_RUNTIME_MAP=y
 | 
						|
+# CONFIG_EFI_FAKE_MEMMAP is not set
 | 
						|
+CONFIG_EFI_RUNTIME_WRAPPERS=y
 | 
						|
+# CONFIG_EFI_BOOTLOADER_CONTROL is not set
 | 
						|
+# CONFIG_EFI_CAPSULE_LOADER is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# File systems
 | 
						|
+#
 | 
						|
+CONFIG_DCACHE_WORD_ACCESS=y
 | 
						|
+# CONFIG_EXT2_FS is not set
 | 
						|
+# CONFIG_EXT3_FS is not set
 | 
						|
+CONFIG_EXT4_FS=y
 | 
						|
+CONFIG_EXT4_USE_FOR_EXT2=y
 | 
						|
+# CONFIG_EXT4_FS_POSIX_ACL is not set
 | 
						|
+CONFIG_EXT4_FS_SECURITY=y
 | 
						|
+# CONFIG_EXT4_ENCRYPTION is not set
 | 
						|
+# CONFIG_EXT4_DEBUG is not set
 | 
						|
+CONFIG_JBD2=y
 | 
						|
+CONFIG_JBD2_DEBUG=y
 | 
						|
+CONFIG_FS_MBCACHE=y
 | 
						|
+# CONFIG_REISERFS_FS is not set
 | 
						|
+# CONFIG_JFS_FS is not set
 | 
						|
+# CONFIG_XFS_FS is not set
 | 
						|
+# CONFIG_GFS2_FS is not set
 | 
						|
+# CONFIG_OCFS2_FS is not set
 | 
						|
+# CONFIG_BTRFS_FS is not set
 | 
						|
+# CONFIG_NILFS2_FS is not set
 | 
						|
+# CONFIG_F2FS_FS is not set
 | 
						|
+# CONFIG_FS_DAX is not set
 | 
						|
+CONFIG_FS_POSIX_ACL=y
 | 
						|
+CONFIG_EXPORTFS=y
 | 
						|
+# CONFIG_EXPORTFS_BLOCK_OPS is not set
 | 
						|
+CONFIG_FILE_LOCKING=y
 | 
						|
+CONFIG_MANDATORY_FILE_LOCKING=y
 | 
						|
+# CONFIG_FS_ENCRYPTION is not set
 | 
						|
+CONFIG_FSNOTIFY=y
 | 
						|
+CONFIG_DNOTIFY=y
 | 
						|
+CONFIG_INOTIFY_USER=y
 | 
						|
+CONFIG_FANOTIFY=y
 | 
						|
+# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set
 | 
						|
+CONFIG_QUOTA=y
 | 
						|
+CONFIG_QUOTA_NETLINK_INTERFACE=y
 | 
						|
+# CONFIG_PRINT_QUOTA_WARNING is not set
 | 
						|
+# CONFIG_QUOTA_DEBUG is not set
 | 
						|
+CONFIG_QUOTA_TREE=y
 | 
						|
+# CONFIG_QFMT_V1 is not set
 | 
						|
+CONFIG_QFMT_V2=y
 | 
						|
+CONFIG_QUOTACTL=y
 | 
						|
+CONFIG_QUOTACTL_COMPAT=y
 | 
						|
+CONFIG_AUTOFS4_FS=m
 | 
						|
+CONFIG_FUSE_FS=y
 | 
						|
+# CONFIG_CUSE is not set
 | 
						|
+# CONFIG_OVERLAY_FS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Caches
 | 
						|
+#
 | 
						|
+# CONFIG_FSCACHE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# CD-ROM/DVD Filesystems
 | 
						|
+#
 | 
						|
+CONFIG_ISO9660_FS=m
 | 
						|
+CONFIG_JOLIET=y
 | 
						|
+CONFIG_ZISOFS=y
 | 
						|
+# CONFIG_UDF_FS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# DOS/FAT/NT Filesystems
 | 
						|
+#
 | 
						|
+CONFIG_FAT_FS=m
 | 
						|
+CONFIG_MSDOS_FS=m
 | 
						|
+CONFIG_VFAT_FS=m
 | 
						|
+CONFIG_FAT_DEFAULT_CODEPAGE=437
 | 
						|
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 | 
						|
+# CONFIG_FAT_DEFAULT_UTF8 is not set
 | 
						|
+# CONFIG_NTFS_FS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Pseudo filesystems
 | 
						|
+#
 | 
						|
+CONFIG_PROC_FS=y
 | 
						|
+CONFIG_PROC_KCORE=y
 | 
						|
+CONFIG_PROC_VMCORE=y
 | 
						|
+CONFIG_PROC_SYSCTL=y
 | 
						|
+CONFIG_PROC_PAGE_MONITOR=y
 | 
						|
+CONFIG_PROC_CHILDREN=y
 | 
						|
+CONFIG_KERNFS=y
 | 
						|
+CONFIG_SYSFS=y
 | 
						|
+CONFIG_TMPFS=y
 | 
						|
+CONFIG_TMPFS_POSIX_ACL=y
 | 
						|
+CONFIG_TMPFS_XATTR=y
 | 
						|
+CONFIG_HUGETLBFS=y
 | 
						|
+CONFIG_HUGETLB_PAGE=y
 | 
						|
+CONFIG_CONFIGFS_FS=y
 | 
						|
+CONFIG_EFIVAR_FS=m
 | 
						|
+CONFIG_MISC_FILESYSTEMS=y
 | 
						|
+# CONFIG_ORANGEFS_FS is not set
 | 
						|
+# CONFIG_ADFS_FS is not set
 | 
						|
+# CONFIG_AFFS_FS is not set
 | 
						|
+# CONFIG_ECRYPT_FS is not set
 | 
						|
+# CONFIG_HFS_FS is not set
 | 
						|
+# CONFIG_HFSPLUS_FS is not set
 | 
						|
+# CONFIG_BEFS_FS is not set
 | 
						|
+# CONFIG_BFS_FS is not set
 | 
						|
+# CONFIG_EFS_FS is not set
 | 
						|
+# CONFIG_LOGFS is not set
 | 
						|
+# CONFIG_CRAMFS is not set
 | 
						|
+# CONFIG_SQUASHFS is not set
 | 
						|
+# CONFIG_VXFS_FS is not set
 | 
						|
+# CONFIG_MINIX_FS is not set
 | 
						|
+# CONFIG_OMFS_FS is not set
 | 
						|
+# CONFIG_HPFS_FS is not set
 | 
						|
+# CONFIG_QNX4FS_FS is not set
 | 
						|
+# CONFIG_QNX6FS_FS is not set
 | 
						|
+CONFIG_ROMFS_FS=m
 | 
						|
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
 | 
						|
+CONFIG_ROMFS_ON_BLOCK=y
 | 
						|
+# CONFIG_PSTORE is not set
 | 
						|
+# CONFIG_SYSV_FS is not set
 | 
						|
+# CONFIG_UFS_FS is not set
 | 
						|
+CONFIG_NETWORK_FILESYSTEMS=y
 | 
						|
+CONFIG_NFS_FS=m
 | 
						|
+CONFIG_NFS_V2=m
 | 
						|
+CONFIG_NFS_V3=m
 | 
						|
+CONFIG_NFS_V3_ACL=y
 | 
						|
+CONFIG_NFS_V4=m
 | 
						|
+# CONFIG_NFS_SWAP is not set
 | 
						|
+# CONFIG_NFS_V4_1 is not set
 | 
						|
+# CONFIG_NFS_USE_LEGACY_DNS is not set
 | 
						|
+CONFIG_NFS_USE_KERNEL_DNS=y
 | 
						|
+CONFIG_NFSD=m
 | 
						|
+CONFIG_NFSD_V3=y
 | 
						|
+# CONFIG_NFSD_V3_ACL is not set
 | 
						|
+# CONFIG_NFSD_V4 is not set
 | 
						|
+CONFIG_GRACE_PERIOD=m
 | 
						|
+CONFIG_LOCKD=m
 | 
						|
+CONFIG_LOCKD_V4=y
 | 
						|
+CONFIG_NFS_ACL_SUPPORT=m
 | 
						|
+CONFIG_NFS_COMMON=y
 | 
						|
+CONFIG_SUNRPC=m
 | 
						|
+CONFIG_SUNRPC_GSS=m
 | 
						|
+# CONFIG_SUNRPC_DEBUG is not set
 | 
						|
+CONFIG_SUNRPC_XPRT_RDMA=m
 | 
						|
+# CONFIG_CEPH_FS is not set
 | 
						|
+# CONFIG_CIFS is not set
 | 
						|
+# CONFIG_NCP_FS is not set
 | 
						|
+# CONFIG_CODA_FS is not set
 | 
						|
+# CONFIG_AFS_FS is not set
 | 
						|
+CONFIG_NLS=y
 | 
						|
+CONFIG_NLS_DEFAULT="iso8859-1"
 | 
						|
+CONFIG_NLS_CODEPAGE_437=y
 | 
						|
+# CONFIG_NLS_CODEPAGE_737 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_775 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_850 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_852 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_855 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_857 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_860 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_861 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_862 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_863 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_864 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_865 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_866 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_869 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_936 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_950 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_932 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_949 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_874 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_8 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_1250 is not set
 | 
						|
+# CONFIG_NLS_CODEPAGE_1251 is not set
 | 
						|
+CONFIG_NLS_ASCII=y
 | 
						|
+CONFIG_NLS_ISO8859_1=y
 | 
						|
+# CONFIG_NLS_ISO8859_2 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_3 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_4 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_5 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_6 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_7 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_9 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_13 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_14 is not set
 | 
						|
+# CONFIG_NLS_ISO8859_15 is not set
 | 
						|
+# CONFIG_NLS_KOI8_R is not set
 | 
						|
+# CONFIG_NLS_KOI8_U is not set
 | 
						|
+# CONFIG_NLS_MAC_ROMAN is not set
 | 
						|
+# CONFIG_NLS_MAC_CELTIC is not set
 | 
						|
+# CONFIG_NLS_MAC_CENTEURO is not set
 | 
						|
+# CONFIG_NLS_MAC_CROATIAN is not set
 | 
						|
+# CONFIG_NLS_MAC_CYRILLIC is not set
 | 
						|
+# CONFIG_NLS_MAC_GAELIC is not set
 | 
						|
+# CONFIG_NLS_MAC_GREEK is not set
 | 
						|
+# CONFIG_NLS_MAC_ICELAND is not set
 | 
						|
+# CONFIG_NLS_MAC_INUIT is not set
 | 
						|
+# CONFIG_NLS_MAC_ROMANIAN is not set
 | 
						|
+# CONFIG_NLS_MAC_TURKISH is not set
 | 
						|
+CONFIG_NLS_UTF8=y
 | 
						|
+# CONFIG_DLM is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Kernel hacking
 | 
						|
+#
 | 
						|
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# printk and dmesg options
 | 
						|
+#
 | 
						|
+CONFIG_PRINTK_TIME=y
 | 
						|
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
 | 
						|
+# CONFIG_BOOT_PRINTK_DELAY is not set
 | 
						|
+# CONFIG_DYNAMIC_DEBUG is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Compile-time checks and compiler options
 | 
						|
+#
 | 
						|
+CONFIG_DEBUG_INFO=y
 | 
						|
+# CONFIG_DEBUG_INFO_REDUCED is not set
 | 
						|
+# CONFIG_DEBUG_INFO_SPLIT is not set
 | 
						|
+# CONFIG_DEBUG_INFO_DWARF4 is not set
 | 
						|
+# CONFIG_GDB_SCRIPTS is not set
 | 
						|
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
 | 
						|
+CONFIG_ENABLE_MUST_CHECK=y
 | 
						|
+CONFIG_FRAME_WARN=2048
 | 
						|
+# CONFIG_STRIP_ASM_SYMS is not set
 | 
						|
+# CONFIG_READABLE_ASM is not set
 | 
						|
+# CONFIG_UNUSED_SYMBOLS is not set
 | 
						|
+# CONFIG_PAGE_OWNER is not set
 | 
						|
+CONFIG_DEBUG_FS=y
 | 
						|
+# CONFIG_HEADERS_CHECK is not set
 | 
						|
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
 | 
						|
+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
 | 
						|
+CONFIG_ARCH_WANT_FRAME_POINTERS=y
 | 
						|
+CONFIG_FRAME_POINTER=y
 | 
						|
+# CONFIG_STACK_VALIDATION is not set
 | 
						|
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 | 
						|
+CONFIG_MAGIC_SYSRQ=y
 | 
						|
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
 | 
						|
+CONFIG_DEBUG_KERNEL=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Memory Debugging
 | 
						|
+#
 | 
						|
+# CONFIG_PAGE_EXTENSION is not set
 | 
						|
+# CONFIG_DEBUG_PAGEALLOC is not set
 | 
						|
+# CONFIG_PAGE_POISONING is not set
 | 
						|
+# CONFIG_DEBUG_PAGE_REF is not set
 | 
						|
+# CONFIG_DEBUG_OBJECTS is not set
 | 
						|
+# CONFIG_DEBUG_SLAB is not set
 | 
						|
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
 | 
						|
+# CONFIG_DEBUG_KMEMLEAK is not set
 | 
						|
+# CONFIG_DEBUG_STACK_USAGE is not set
 | 
						|
+# CONFIG_DEBUG_VM is not set
 | 
						|
+# CONFIG_DEBUG_VIRTUAL is not set
 | 
						|
+CONFIG_DEBUG_MEMORY_INIT=y
 | 
						|
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
 | 
						|
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
 | 
						|
+# CONFIG_DEBUG_STACKOVERFLOW is not set
 | 
						|
+CONFIG_HAVE_ARCH_KMEMCHECK=y
 | 
						|
+CONFIG_HAVE_ARCH_KASAN=y
 | 
						|
+# CONFIG_KASAN is not set
 | 
						|
+CONFIG_ARCH_HAS_KCOV=y
 | 
						|
+# CONFIG_KCOV is not set
 | 
						|
+# CONFIG_DEBUG_SHIRQ is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Debug Lockups and Hangs
 | 
						|
+#
 | 
						|
+CONFIG_LOCKUP_DETECTOR=y
 | 
						|
+CONFIG_HARDLOCKUP_DETECTOR=y
 | 
						|
+# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
 | 
						|
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
 | 
						|
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 | 
						|
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
 | 
						|
+# CONFIG_DETECT_HUNG_TASK is not set
 | 
						|
+# CONFIG_WQ_WATCHDOG is not set
 | 
						|
+# CONFIG_PANIC_ON_OOPS is not set
 | 
						|
+CONFIG_PANIC_ON_OOPS_VALUE=0
 | 
						|
+CONFIG_PANIC_TIMEOUT=0
 | 
						|
+CONFIG_SCHED_DEBUG=y
 | 
						|
+CONFIG_SCHED_INFO=y
 | 
						|
+CONFIG_SCHEDSTATS=y
 | 
						|
+# CONFIG_SCHED_STACK_END_CHECK is not set
 | 
						|
+# CONFIG_DEBUG_TIMEKEEPING is not set
 | 
						|
+CONFIG_TIMER_STATS=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Lock Debugging (spinlocks, mutexes, etc...)
 | 
						|
+#
 | 
						|
+# CONFIG_DEBUG_RT_MUTEXES is not set
 | 
						|
+# CONFIG_DEBUG_SPINLOCK is not set
 | 
						|
+# CONFIG_DEBUG_MUTEXES is not set
 | 
						|
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
 | 
						|
+# CONFIG_DEBUG_LOCK_ALLOC is not set
 | 
						|
+# CONFIG_PROVE_LOCKING is not set
 | 
						|
+# CONFIG_LOCK_STAT is not set
 | 
						|
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
 | 
						|
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 | 
						|
+# CONFIG_LOCK_TORTURE_TEST is not set
 | 
						|
+CONFIG_STACKTRACE=y
 | 
						|
+# CONFIG_DEBUG_KOBJECT is not set
 | 
						|
+CONFIG_DEBUG_BUGVERBOSE=y
 | 
						|
+# CONFIG_DEBUG_LIST is not set
 | 
						|
+# CONFIG_DEBUG_PI_LIST is not set
 | 
						|
+# CONFIG_DEBUG_SG is not set
 | 
						|
+# CONFIG_DEBUG_NOTIFIERS is not set
 | 
						|
+# CONFIG_DEBUG_CREDENTIALS is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# RCU Debugging
 | 
						|
+#
 | 
						|
+# CONFIG_PROVE_RCU is not set
 | 
						|
+# CONFIG_SPARSE_RCU_POINTER is not set
 | 
						|
+# CONFIG_TORTURE_TEST is not set
 | 
						|
+# CONFIG_RCU_PERF_TEST is not set
 | 
						|
+# CONFIG_RCU_TORTURE_TEST is not set
 | 
						|
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
 | 
						|
+# CONFIG_RCU_TRACE is not set
 | 
						|
+# CONFIG_RCU_EQS_DEBUG is not set
 | 
						|
+CONFIG_DEBUG_WQ_FORCE_RR_CPU=y
 | 
						|
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 | 
						|
+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
 | 
						|
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
 | 
						|
+# CONFIG_FAULT_INJECTION is not set
 | 
						|
+# CONFIG_LATENCYTOP is not set
 | 
						|
+CONFIG_USER_STACKTRACE_SUPPORT=y
 | 
						|
+CONFIG_NOP_TRACER=y
 | 
						|
+CONFIG_HAVE_FUNCTION_TRACER=y
 | 
						|
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 | 
						|
+CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
 | 
						|
+CONFIG_HAVE_DYNAMIC_FTRACE=y
 | 
						|
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
 | 
						|
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 | 
						|
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 | 
						|
+CONFIG_HAVE_FENTRY=y
 | 
						|
+CONFIG_HAVE_C_RECORDMCOUNT=y
 | 
						|
+CONFIG_TRACE_CLOCK=y
 | 
						|
+CONFIG_RING_BUFFER=y
 | 
						|
+CONFIG_EVENT_TRACING=y
 | 
						|
+CONFIG_CONTEXT_SWITCH_TRACER=y
 | 
						|
+CONFIG_TRACING=y
 | 
						|
+CONFIG_GENERIC_TRACER=y
 | 
						|
+CONFIG_TRACING_SUPPORT=y
 | 
						|
+CONFIG_FTRACE=y
 | 
						|
+CONFIG_FUNCTION_TRACER=y
 | 
						|
+CONFIG_FUNCTION_GRAPH_TRACER=y
 | 
						|
+# CONFIG_IRQSOFF_TRACER is not set
 | 
						|
+# CONFIG_SCHED_TRACER is not set
 | 
						|
+CONFIG_FTRACE_SYSCALLS=y
 | 
						|
+# CONFIG_TRACER_SNAPSHOT is not set
 | 
						|
+CONFIG_BRANCH_PROFILE_NONE=y
 | 
						|
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 | 
						|
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 | 
						|
+# CONFIG_STACK_TRACER is not set
 | 
						|
+CONFIG_BLK_DEV_IO_TRACE=y
 | 
						|
+CONFIG_KPROBE_EVENT=y
 | 
						|
+# CONFIG_UPROBE_EVENT is not set
 | 
						|
+CONFIG_PROBE_EVENTS=y
 | 
						|
+CONFIG_DYNAMIC_FTRACE=y
 | 
						|
+CONFIG_DYNAMIC_FTRACE_WITH_REGS=y
 | 
						|
+# CONFIG_FUNCTION_PROFILER is not set
 | 
						|
+CONFIG_FTRACE_MCOUNT_RECORD=y
 | 
						|
+# CONFIG_FTRACE_STARTUP_TEST is not set
 | 
						|
+# CONFIG_MMIOTRACE is not set
 | 
						|
+# CONFIG_HIST_TRIGGERS is not set
 | 
						|
+# CONFIG_TRACEPOINT_BENCHMARK is not set
 | 
						|
+# CONFIG_RING_BUFFER_BENCHMARK is not set
 | 
						|
+# CONFIG_RING_BUFFER_STARTUP_TEST is not set
 | 
						|
+# CONFIG_TRACE_ENUM_MAP_FILE is not set
 | 
						|
+CONFIG_TRACING_EVENTS_GPIO=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Runtime Testing
 | 
						|
+#
 | 
						|
+CONFIG_LKDTM=y
 | 
						|
+# CONFIG_TEST_LIST_SORT is not set
 | 
						|
+# CONFIG_KPROBES_SANITY_TEST is not set
 | 
						|
+# CONFIG_BACKTRACE_SELF_TEST is not set
 | 
						|
+# CONFIG_RBTREE_TEST is not set
 | 
						|
+# CONFIG_INTERVAL_TREE_TEST is not set
 | 
						|
+# CONFIG_PERCPU_TEST is not set
 | 
						|
+# CONFIG_ATOMIC64_SELFTEST is not set
 | 
						|
+# CONFIG_TEST_HEXDUMP is not set
 | 
						|
+# CONFIG_TEST_STRING_HELPERS is not set
 | 
						|
+# CONFIG_TEST_KSTRTOX is not set
 | 
						|
+# CONFIG_TEST_PRINTF is not set
 | 
						|
+CONFIG_TEST_BITMAP=y
 | 
						|
+# CONFIG_TEST_UUID is not set
 | 
						|
+# CONFIG_TEST_RHASHTABLE is not set
 | 
						|
+# CONFIG_TEST_HASH is not set
 | 
						|
+CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
 | 
						|
+# CONFIG_DMA_API_DEBUG is not set
 | 
						|
+# CONFIG_TEST_LKM is not set
 | 
						|
+# CONFIG_TEST_USER_COPY is not set
 | 
						|
+# CONFIG_TEST_BPF is not set
 | 
						|
+# CONFIG_TEST_FIRMWARE is not set
 | 
						|
+# CONFIG_TEST_UDELAY is not set
 | 
						|
+# CONFIG_MEMTEST is not set
 | 
						|
+# CONFIG_TEST_STATIC_KEYS is not set
 | 
						|
+# CONFIG_SAMPLES is not set
 | 
						|
+CONFIG_HAVE_ARCH_KGDB=y
 | 
						|
+# CONFIG_KGDB is not set
 | 
						|
+CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y
 | 
						|
+# CONFIG_UBSAN is not set
 | 
						|
+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
 | 
						|
+# CONFIG_STRICT_DEVMEM is not set
 | 
						|
+CONFIG_X86_VERBOSE_BOOTUP=y
 | 
						|
+CONFIG_EARLY_PRINTK=y
 | 
						|
+CONFIG_EARLY_PRINTK_DBGP=y
 | 
						|
+# CONFIG_EARLY_PRINTK_EFI is not set
 | 
						|
+# CONFIG_X86_PTDUMP_CORE is not set
 | 
						|
+# CONFIG_X86_PTDUMP is not set
 | 
						|
+# CONFIG_EFI_PGT_DUMP is not set
 | 
						|
+# CONFIG_DEBUG_RODATA_TEST is not set
 | 
						|
+# CONFIG_DEBUG_WX is not set
 | 
						|
+# CONFIG_DEBUG_SET_MODULE_RONX is not set
 | 
						|
+CONFIG_DEBUG_NX_TEST=m
 | 
						|
+CONFIG_DOUBLEFAULT=y
 | 
						|
+# CONFIG_DEBUG_TLBFLUSH is not set
 | 
						|
+# CONFIG_IOMMU_STRESS is not set
 | 
						|
+CONFIG_HAVE_MMIOTRACE_SUPPORT=y
 | 
						|
+# CONFIG_X86_DECODER_SELFTEST is not set
 | 
						|
+CONFIG_IO_DELAY_TYPE_0X80=0
 | 
						|
+CONFIG_IO_DELAY_TYPE_0XED=1
 | 
						|
+CONFIG_IO_DELAY_TYPE_UDELAY=2
 | 
						|
+CONFIG_IO_DELAY_TYPE_NONE=3
 | 
						|
+CONFIG_IO_DELAY_0X80=y
 | 
						|
+# CONFIG_IO_DELAY_0XED is not set
 | 
						|
+# CONFIG_IO_DELAY_UDELAY is not set
 | 
						|
+# CONFIG_IO_DELAY_NONE is not set
 | 
						|
+CONFIG_DEFAULT_IO_DELAY_TYPE=0
 | 
						|
+CONFIG_DEBUG_BOOT_PARAMS=y
 | 
						|
+# CONFIG_CPA_DEBUG is not set
 | 
						|
+CONFIG_OPTIMIZE_INLINING=y
 | 
						|
+# CONFIG_DEBUG_ENTRY is not set
 | 
						|
+# CONFIG_DEBUG_NMI_SELFTEST is not set
 | 
						|
+CONFIG_X86_DEBUG_FPU=y
 | 
						|
+# CONFIG_PUNIT_ATOM_DEBUG is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Security options
 | 
						|
+#
 | 
						|
+CONFIG_KEYS=y
 | 
						|
+# CONFIG_PERSISTENT_KEYRINGS is not set
 | 
						|
+# CONFIG_BIG_KEYS is not set
 | 
						|
+# CONFIG_ENCRYPTED_KEYS is not set
 | 
						|
+# CONFIG_KEY_DH_OPERATIONS is not set
 | 
						|
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
 | 
						|
+CONFIG_SECURITY=y
 | 
						|
+# CONFIG_SECURITYFS is not set
 | 
						|
+CONFIG_SECURITY_NETWORK=y
 | 
						|
+# CONFIG_SECURITY_PATH is not set
 | 
						|
+# CONFIG_INTEL_TXT is not set
 | 
						|
+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
 | 
						|
+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y
 | 
						|
+# CONFIG_HARDENED_USERCOPY is not set
 | 
						|
+# CONFIG_SECURITY_SELINUX is not set
 | 
						|
+# CONFIG_SECURITY_SMACK is not set
 | 
						|
+# CONFIG_SECURITY_TOMOYO is not set
 | 
						|
+# CONFIG_SECURITY_APPARMOR is not set
 | 
						|
+# CONFIG_SECURITY_LOADPIN is not set
 | 
						|
+# CONFIG_SECURITY_YAMA is not set
 | 
						|
+CONFIG_INTEGRITY=y
 | 
						|
+# CONFIG_INTEGRITY_SIGNATURE is not set
 | 
						|
+CONFIG_INTEGRITY_AUDIT=y
 | 
						|
+# CONFIG_IMA is not set
 | 
						|
+# CONFIG_EVM is not set
 | 
						|
+CONFIG_DEFAULT_SECURITY_DAC=y
 | 
						|
+CONFIG_DEFAULT_SECURITY=""
 | 
						|
+CONFIG_CRYPTO=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Crypto core or helper
 | 
						|
+#
 | 
						|
+CONFIG_CRYPTO_ALGAPI=y
 | 
						|
+CONFIG_CRYPTO_ALGAPI2=y
 | 
						|
+CONFIG_CRYPTO_AEAD=y
 | 
						|
+CONFIG_CRYPTO_AEAD2=y
 | 
						|
+CONFIG_CRYPTO_BLKCIPHER=y
 | 
						|
+CONFIG_CRYPTO_BLKCIPHER2=y
 | 
						|
+CONFIG_CRYPTO_HASH=y
 | 
						|
+CONFIG_CRYPTO_HASH2=y
 | 
						|
+CONFIG_CRYPTO_RNG=m
 | 
						|
+CONFIG_CRYPTO_RNG2=y
 | 
						|
+CONFIG_CRYPTO_RNG_DEFAULT=m
 | 
						|
+CONFIG_CRYPTO_AKCIPHER2=y
 | 
						|
+CONFIG_CRYPTO_KPP2=y
 | 
						|
+# CONFIG_CRYPTO_RSA is not set
 | 
						|
+# CONFIG_CRYPTO_DH is not set
 | 
						|
+# CONFIG_CRYPTO_ECDH is not set
 | 
						|
+CONFIG_CRYPTO_MANAGER=y
 | 
						|
+CONFIG_CRYPTO_MANAGER2=y
 | 
						|
+# CONFIG_CRYPTO_USER is not set
 | 
						|
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
 | 
						|
+# CONFIG_CRYPTO_GF128MUL is not set
 | 
						|
+CONFIG_CRYPTO_NULL=y
 | 
						|
+CONFIG_CRYPTO_NULL2=y
 | 
						|
+# CONFIG_CRYPTO_PCRYPT is not set
 | 
						|
+CONFIG_CRYPTO_WORKQUEUE=y
 | 
						|
+# CONFIG_CRYPTO_CRYPTD is not set
 | 
						|
+# CONFIG_CRYPTO_MCRYPTD is not set
 | 
						|
+CONFIG_CRYPTO_AUTHENC=y
 | 
						|
+# CONFIG_CRYPTO_TEST is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Authenticated Encryption with Associated Data
 | 
						|
+#
 | 
						|
+# CONFIG_CRYPTO_CCM is not set
 | 
						|
+# CONFIG_CRYPTO_GCM is not set
 | 
						|
+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
 | 
						|
+# CONFIG_CRYPTO_SEQIV is not set
 | 
						|
+CONFIG_CRYPTO_ECHAINIV=m
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Block modes
 | 
						|
+#
 | 
						|
+CONFIG_CRYPTO_CBC=y
 | 
						|
+# CONFIG_CRYPTO_CTR is not set
 | 
						|
+# CONFIG_CRYPTO_CTS is not set
 | 
						|
+# CONFIG_CRYPTO_ECB is not set
 | 
						|
+# CONFIG_CRYPTO_LRW is not set
 | 
						|
+# CONFIG_CRYPTO_PCBC is not set
 | 
						|
+# CONFIG_CRYPTO_XTS is not set
 | 
						|
+# CONFIG_CRYPTO_KEYWRAP is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Hash modes
 | 
						|
+#
 | 
						|
+# CONFIG_CRYPTO_CMAC is not set
 | 
						|
+CONFIG_CRYPTO_HMAC=y
 | 
						|
+# CONFIG_CRYPTO_XCBC is not set
 | 
						|
+CONFIG_CRYPTO_VMAC=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Digest
 | 
						|
+#
 | 
						|
+CONFIG_CRYPTO_CRC32C=y
 | 
						|
+# CONFIG_CRYPTO_CRC32C_INTEL is not set
 | 
						|
+# CONFIG_CRYPTO_CRC32 is not set
 | 
						|
+# CONFIG_CRYPTO_CRC32_PCLMUL is not set
 | 
						|
+# CONFIG_CRYPTO_CRCT10DIF is not set
 | 
						|
+# CONFIG_CRYPTO_GHASH is not set
 | 
						|
+# CONFIG_CRYPTO_POLY1305 is not set
 | 
						|
+# CONFIG_CRYPTO_POLY1305_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_MD4 is not set
 | 
						|
+CONFIG_CRYPTO_MD5=y
 | 
						|
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
 | 
						|
+# CONFIG_CRYPTO_RMD128 is not set
 | 
						|
+# CONFIG_CRYPTO_RMD160 is not set
 | 
						|
+# CONFIG_CRYPTO_RMD256 is not set
 | 
						|
+# CONFIG_CRYPTO_RMD320 is not set
 | 
						|
+CONFIG_CRYPTO_SHA1=y
 | 
						|
+# CONFIG_CRYPTO_SHA1_SSSE3 is not set
 | 
						|
+# CONFIG_CRYPTO_SHA256_SSSE3 is not set
 | 
						|
+# CONFIG_CRYPTO_SHA512_SSSE3 is not set
 | 
						|
+# CONFIG_CRYPTO_SHA1_MB is not set
 | 
						|
+# CONFIG_CRYPTO_SHA256_MB is not set
 | 
						|
+# CONFIG_CRYPTO_SHA512_MB is not set
 | 
						|
+CONFIG_CRYPTO_SHA256=y
 | 
						|
+CONFIG_CRYPTO_SHA512=y
 | 
						|
+# CONFIG_CRYPTO_SHA3 is not set
 | 
						|
+# CONFIG_CRYPTO_TGR192 is not set
 | 
						|
+# CONFIG_CRYPTO_WP512 is not set
 | 
						|
+# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Ciphers
 | 
						|
+#
 | 
						|
+CONFIG_CRYPTO_AES=y
 | 
						|
+# CONFIG_CRYPTO_AES_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_AES_NI_INTEL is not set
 | 
						|
+# CONFIG_CRYPTO_ANUBIS is not set
 | 
						|
+CONFIG_CRYPTO_ARC4=y
 | 
						|
+# CONFIG_CRYPTO_BLOWFISH is not set
 | 
						|
+# CONFIG_CRYPTO_BLOWFISH_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_CAMELLIA is not set
 | 
						|
+# CONFIG_CRYPTO_CAMELLIA_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_CAST5 is not set
 | 
						|
+# CONFIG_CRYPTO_CAST5_AVX_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_CAST6 is not set
 | 
						|
+# CONFIG_CRYPTO_CAST6_AVX_X86_64 is not set
 | 
						|
+CONFIG_CRYPTO_DES=y
 | 
						|
+# CONFIG_CRYPTO_DES3_EDE_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_FCRYPT is not set
 | 
						|
+# CONFIG_CRYPTO_KHAZAD is not set
 | 
						|
+# CONFIG_CRYPTO_SALSA20 is not set
 | 
						|
+# CONFIG_CRYPTO_SALSA20_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_CHACHA20 is not set
 | 
						|
+# CONFIG_CRYPTO_CHACHA20_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_SEED is not set
 | 
						|
+# CONFIG_CRYPTO_SERPENT is not set
 | 
						|
+# CONFIG_CRYPTO_SERPENT_SSE2_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_SERPENT_AVX_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_SERPENT_AVX2_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_TEA is not set
 | 
						|
+# CONFIG_CRYPTO_TWOFISH is not set
 | 
						|
+# CONFIG_CRYPTO_TWOFISH_X86_64 is not set
 | 
						|
+# CONFIG_CRYPTO_TWOFISH_X86_64_3WAY is not set
 | 
						|
+# CONFIG_CRYPTO_TWOFISH_AVX_X86_64 is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Compression
 | 
						|
+#
 | 
						|
+# CONFIG_CRYPTO_DEFLATE is not set
 | 
						|
+CONFIG_CRYPTO_LZO=y
 | 
						|
+# CONFIG_CRYPTO_842 is not set
 | 
						|
+# CONFIG_CRYPTO_LZ4 is not set
 | 
						|
+# CONFIG_CRYPTO_LZ4HC is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Random Number Generation
 | 
						|
+#
 | 
						|
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 | 
						|
+CONFIG_CRYPTO_DRBG_MENU=m
 | 
						|
+CONFIG_CRYPTO_DRBG_HMAC=y
 | 
						|
+# CONFIG_CRYPTO_DRBG_HASH is not set
 | 
						|
+CONFIG_CRYPTO_DRBG=m
 | 
						|
+CONFIG_CRYPTO_JITTERENTROPY=m
 | 
						|
+# CONFIG_CRYPTO_USER_API_HASH is not set
 | 
						|
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
 | 
						|
+# CONFIG_CRYPTO_USER_API_RNG is not set
 | 
						|
+# CONFIG_CRYPTO_USER_API_AEAD is not set
 | 
						|
+CONFIG_CRYPTO_HW=y
 | 
						|
+# CONFIG_CRYPTO_DEV_PADLOCK is not set
 | 
						|
+# CONFIG_CRYPTO_DEV_CCP is not set
 | 
						|
+# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set
 | 
						|
+# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set
 | 
						|
+# CONFIG_CRYPTO_DEV_QAT_C62X is not set
 | 
						|
+# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set
 | 
						|
+# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set
 | 
						|
+# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set
 | 
						|
+# CONFIG_ASYMMETRIC_KEY_TYPE is not set
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Certificates for signature checking
 | 
						|
+#
 | 
						|
+CONFIG_HAVE_KVM=y
 | 
						|
+CONFIG_HAVE_KVM_IRQCHIP=y
 | 
						|
+CONFIG_HAVE_KVM_IRQFD=y
 | 
						|
+CONFIG_HAVE_KVM_IRQ_ROUTING=y
 | 
						|
+CONFIG_HAVE_KVM_EVENTFD=y
 | 
						|
+CONFIG_KVM_MMIO=y
 | 
						|
+CONFIG_KVM_ASYNC_PF=y
 | 
						|
+CONFIG_HAVE_KVM_MSI=y
 | 
						|
+CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
 | 
						|
+CONFIG_KVM_VFIO=y
 | 
						|
+CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
 | 
						|
+CONFIG_KVM_COMPAT=y
 | 
						|
+CONFIG_HAVE_KVM_IRQ_BYPASS=y
 | 
						|
+CONFIG_VIRTUALIZATION=y
 | 
						|
+CONFIG_KVM=y
 | 
						|
+CONFIG_KVM_INTEL=y
 | 
						|
+CONFIG_KVM_AMD=y
 | 
						|
+# CONFIG_KVM_MMU_AUDIT is not set
 | 
						|
+# CONFIG_KVM_DEVICE_ASSIGNMENT is not set
 | 
						|
+# CONFIG_VHOST_NET is not set
 | 
						|
+# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set
 | 
						|
+CONFIG_BINARY_PRINTF=y
 | 
						|
+
 | 
						|
+#
 | 
						|
+# Library routines
 | 
						|
+#
 | 
						|
+CONFIG_BITREVERSE=y
 | 
						|
+# CONFIG_HAVE_ARCH_BITREVERSE is not set
 | 
						|
+CONFIG_RATIONAL=y
 | 
						|
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
 | 
						|
+CONFIG_GENERIC_STRNLEN_USER=y
 | 
						|
+CONFIG_GENERIC_NET_UTILS=y
 | 
						|
+CONFIG_GENERIC_FIND_FIRST_BIT=y
 | 
						|
+CONFIG_GENERIC_PCI_IOMAP=y
 | 
						|
+CONFIG_GENERIC_IOMAP=y
 | 
						|
+CONFIG_GENERIC_IO=y
 | 
						|
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
 | 
						|
+CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
 | 
						|
+# CONFIG_CRC_CCITT is not set
 | 
						|
+CONFIG_CRC16=y
 | 
						|
+# CONFIG_CRC_T10DIF is not set
 | 
						|
+CONFIG_CRC_ITU_T=m
 | 
						|
+CONFIG_CRC32=y
 | 
						|
+# CONFIG_CRC32_SELFTEST is not set
 | 
						|
+CONFIG_CRC32_SLICEBY8=y
 | 
						|
+# CONFIG_CRC32_SLICEBY4 is not set
 | 
						|
+# CONFIG_CRC32_SARWATE is not set
 | 
						|
+# CONFIG_CRC32_BIT is not set
 | 
						|
+# CONFIG_CRC7 is not set
 | 
						|
+CONFIG_LIBCRC32C=y
 | 
						|
+# CONFIG_CRC8 is not set
 | 
						|
+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set
 | 
						|
+# CONFIG_RANDOM32_SELFTEST is not set
 | 
						|
+CONFIG_ZLIB_INFLATE=y
 | 
						|
+CONFIG_LZO_COMPRESS=y
 | 
						|
+CONFIG_LZO_DECOMPRESS=y
 | 
						|
+CONFIG_LZ4_DECOMPRESS=y
 | 
						|
+CONFIG_XZ_DEC=y
 | 
						|
+CONFIG_XZ_DEC_X86=y
 | 
						|
+CONFIG_XZ_DEC_POWERPC=y
 | 
						|
+CONFIG_XZ_DEC_IA64=y
 | 
						|
+CONFIG_XZ_DEC_ARM=y
 | 
						|
+CONFIG_XZ_DEC_ARMTHUMB=y
 | 
						|
+CONFIG_XZ_DEC_SPARC=y
 | 
						|
+CONFIG_XZ_DEC_BCJ=y
 | 
						|
+# CONFIG_XZ_DEC_TEST is not set
 | 
						|
+CONFIG_DECOMPRESS_GZIP=y
 | 
						|
+CONFIG_DECOMPRESS_BZIP2=y
 | 
						|
+CONFIG_DECOMPRESS_LZMA=y
 | 
						|
+CONFIG_DECOMPRESS_XZ=y
 | 
						|
+CONFIG_DECOMPRESS_LZO=y
 | 
						|
+CONFIG_DECOMPRESS_LZ4=y
 | 
						|
+CONFIG_GENERIC_ALLOCATOR=y
 | 
						|
+CONFIG_TEXTSEARCH=y
 | 
						|
+CONFIG_TEXTSEARCH_KMP=m
 | 
						|
+CONFIG_TEXTSEARCH_BM=m
 | 
						|
+CONFIG_TEXTSEARCH_FSM=m
 | 
						|
+CONFIG_RADIX_TREE_MULTIORDER=y
 | 
						|
+CONFIG_ASSOCIATIVE_ARRAY=y
 | 
						|
+CONFIG_HAS_IOMEM=y
 | 
						|
+CONFIG_HAS_IOPORT_MAP=y
 | 
						|
+CONFIG_HAS_DMA=y
 | 
						|
+CONFIG_CHECK_SIGNATURE=y
 | 
						|
+CONFIG_CPU_RMAP=y
 | 
						|
+CONFIG_DQL=y
 | 
						|
+CONFIG_GLOB=y
 | 
						|
+# CONFIG_GLOB_SELFTEST is not set
 | 
						|
+CONFIG_NLATTR=y
 | 
						|
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
 | 
						|
+# CONFIG_CORDIC is not set
 | 
						|
+# CONFIG_DDR is not set
 | 
						|
+CONFIG_IRQ_POLL=y
 | 
						|
+CONFIG_OID_REGISTRY=m
 | 
						|
+CONFIG_UCS2_STRING=y
 | 
						|
+# CONFIG_SG_SPLIT is not set
 | 
						|
+CONFIG_SG_POOL=y
 | 
						|
+CONFIG_ARCH_HAS_SG_CHAIN=y
 | 
						|
+CONFIG_ARCH_HAS_PMEM_API=y
 | 
						|
+CONFIG_ARCH_HAS_MMIO_FLUSH=y
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 2867ba805abf8e11292f5287188684e2679bdf80 Mon Sep 17 00:00:00 2001
 | 
						|
From: Soheil Hassas Yeganeh <soheil@google.com>
 | 
						|
Date: Sat, 23 Jan 2016 20:54:46 -0500
 | 
						|
Subject: [PATCH 16/27] net-test: adds a gce-install.sh script to build and
 | 
						|
 install kernel on GCE machine
 | 
						|
 | 
						|
This commit adds a script to build an upstream Linux kernel and
 | 
						|
install it and boot it on a Google Cloud (GCE) virtual machine.
 | 
						|
 | 
						|
Usage:
 | 
						|
  ./gce-install.sh -m <MACHINE_IP>
 | 
						|
 | 
						|
e.g.:
 | 
						|
  ./gce-install.sh  -m 1.2.3.4
 | 
						|
  ssh 1.2.3.4
 | 
						|
 | 
						|
Tested: On GCE.
 | 
						|
Effort: net-test
 | 
						|
Change-Id: I149233b802202335af93183728050aadb52cca2c
 | 
						|
---
 | 
						|
 .gitignore     |  3 ++
 | 
						|
 gce-install.sh | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++
 | 
						|
 2 files changed, 92 insertions(+)
 | 
						|
 create mode 100755 gce-install.sh
 | 
						|
 | 
						|
diff --git a/.gitignore b/.gitignore
 | 
						|
index 5da004814678..f09d026f4820 100644
 | 
						|
--- a/.gitignore
 | 
						|
+++ b/.gitignore
 | 
						|
@@ -154,6 +154,9 @@ x509.genkey
 | 
						|
 /allrandom.config
 | 
						|
 /allyes.config
 | 
						|
 
 | 
						|
+# tmp build/install directory for /gce-install.sh:
 | 
						|
+/gce/
 | 
						|
+
 | 
						|
 # Kconfig savedefconfig output
 | 
						|
 /defconfig
 | 
						|
 
 | 
						|
diff --git a/gce-install.sh b/gce-install.sh
 | 
						|
new file mode 100755
 | 
						|
index 000000000000..1d84fe1d313e
 | 
						|
--- /dev/null
 | 
						|
+++ b/gce-install.sh
 | 
						|
@@ -0,0 +1,89 @@
 | 
						|
+#!/bin/bash
 | 
						|
+# Build a Linux kernel, install it on a remote machine, and reboot the machine.
 | 
						|
+# This script is only known to work for Debian/Ubuntu-based GCE VMs.
 | 
						|
+
 | 
						|
+set -e
 | 
						|
+
 | 
						|
+usage() {
 | 
						|
+	echo "gce-install.sh -m <MACHINE_IP>"
 | 
						|
+}
 | 
						|
+
 | 
						|
+MACHINE=""
 | 
						|
+VERBOSE=""
 | 
						|
+
 | 
						|
+while getopts "h?vm:p:z:" opt; do
 | 
						|
+	case "${opt}" in
 | 
						|
+		h|\?)
 | 
						|
+			usage
 | 
						|
+			exit 0
 | 
						|
+			;;
 | 
						|
+		v)
 | 
						|
+			VERBOSE="set -x"
 | 
						|
+			;;
 | 
						|
+		m)
 | 
						|
+			MACHINE=${OPTARG}
 | 
						|
+			;;
 | 
						|
+	esac
 | 
						|
+done
 | 
						|
+
 | 
						|
+if [ -z ${MACHINE} ]; then
 | 
						|
+	usage
 | 
						|
+	exit -1
 | 
						|
+fi
 | 
						|
+
 | 
						|
+umask 022
 | 
						|
+
 | 
						|
+${VERBOSE}
 | 
						|
+
 | 
						|
+BRANCH=`git rev-parse --abbrev-ref HEAD | sed s/-/+/g`
 | 
						|
+SHA1=`git rev-parse --short HEAD`
 | 
						|
+LOCALVERSION=+${BRANCH}+${SHA1}+GCE
 | 
						|
+GCE_PKG_DIR=${PWD}/gce/${LOCALVERSION}/pkg
 | 
						|
+GCE_INSTALL_DIR=${PWD}/gce/${LOCALVERSION}/install
 | 
						|
+GCE_BUILD_DIR=${PWD}/gce/${LOCALVERSION}/build
 | 
						|
+KERNEL_PKG=kernel-${LOCALVERSION}.tar.gz2
 | 
						|
+MAKE_OPTS="-j`nproc` \
 | 
						|
+           LOCALVERSION=${LOCALVERSION} \
 | 
						|
+           EXTRAVERSION="" \
 | 
						|
+           INSTALL_PATH=${GCE_INSTALL_DIR}/boot \
 | 
						|
+           INSTALL_MOD_PATH=${GCE_INSTALL_DIR}"
 | 
						|
+
 | 
						|
+echo "cleaning..."
 | 
						|
+mkdir -p ${GCE_BUILD_DIR}
 | 
						|
+mkdir -p ${GCE_INSTALL_DIR}/boot
 | 
						|
+mkdir -p ${GCE_PKG_DIR}
 | 
						|
+
 | 
						|
+set +e
 | 
						|
+echo "copying config.gce to .config ..."
 | 
						|
+cp config.gce .config
 | 
						|
+echo "running make olddefconfig ..."
 | 
						|
+make olddefconfig               > /tmp/make.olddefconfig
 | 
						|
+make ${MAKE_OPTS} prepare         > /tmp/make.prepare
 | 
						|
+echo "making..."
 | 
						|
+make ${MAKE_OPTS}                 > /tmp/make.default
 | 
						|
+echo "making modules ..."
 | 
						|
+make ${MAKE_OPTS} modules         > /tmp/make.modules
 | 
						|
+echo "making install ..."
 | 
						|
+make ${MAKE_OPTS} install         > /tmp/make.install
 | 
						|
+echo "making modules_install ..."
 | 
						|
+make ${MAKE_OPTS} modules_install > /tmp/make.modules_install
 | 
						|
+set -e
 | 
						|
+
 | 
						|
+echo "making tarball ..."
 | 
						|
+(cd ${GCE_INSTALL_DIR}; tar -cvzf ${GCE_PKG_DIR}/${KERNEL_PKG}  boot/* lib/modules/* --owner=0 --group=0  > /tmp/make.tarball)
 | 
						|
+
 | 
						|
+echo "running: scp $GCE_PKG_DIR/$KERNEL_PKG ${MACHINE}:~/"
 | 
						|
+scp ${GCE_PKG_DIR}/${KERNEL_PKG} ${MACHINE}:~/
 | 
						|
+
 | 
						|
+ssh ${MACHINE} "
 | 
						|
+$VERBOSE
 | 
						|
+sudo rm -rf /boot/*GCE /lib/modules/*GCE
 | 
						|
+sudo tar --no-same-owner -xzvf ${KERNEL_PKG} -C / > /tmp/tar.out.txt
 | 
						|
+cd /boot
 | 
						|
+for v in \$(ls vmlinuz-* | sed s/vmlinuz-//g); do
 | 
						|
+	sudo mkinitramfs -k -o initrd.img-\${v} \${v}
 | 
						|
+done
 | 
						|
+sudo update-grub
 | 
						|
+sudo reboot
 | 
						|
+"
 | 
						|
+umask 027
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 59c67beb45a1d4d4684d06400b90109bbdb6320e Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Wed, 29 Aug 2018 10:27:59 -0400
 | 
						|
Subject: [PATCH 17/27] net-test: scripts for testing bbr2 with upstream Linux
 | 
						|
 kernels
 | 
						|
 | 
						|
- runs a small set of simple tests
 | 
						|
  - sets up netem to emulate a configured network scenario
 | 
						|
  - runs /usr/bin/netperf and /usr/bin/netserver to generate traffic
 | 
						|
  - writes pcaps and ss logs
 | 
						|
- analyzes test results
 | 
						|
- generates graphs
 | 
						|
 | 
						|
Usage:
 | 
						|
  ./run_tests.sh
 | 
						|
  ./graph_tests.sh
 | 
						|
 | 
						|
Effort: net-test
 | 
						|
Change-Id: I38662f554b3c905aa79947a2c52a2ecfe3943f8c
 | 
						|
---
 | 
						|
 gtests/net/tcp/bbr/nsperf/graph_tests.sh   | 306 ++++++++++++
 | 
						|
 gtests/net/tcp/bbr/nsperf/median.py        |  43 ++
 | 
						|
 gtests/net/tcp/bbr/nsperf/nsperf.py        | 540 +++++++++++++++++++++
 | 
						|
 gtests/net/tcp/bbr/nsperf/run_tests.sh     | 201 ++++++++
 | 
						|
 gtests/net/tcp/bbr/nsperf/ss_log_parser.py | 193 ++++++++
 | 
						|
 5 files changed, 1283 insertions(+)
 | 
						|
 create mode 100755 gtests/net/tcp/bbr/nsperf/graph_tests.sh
 | 
						|
 create mode 100755 gtests/net/tcp/bbr/nsperf/median.py
 | 
						|
 create mode 100755 gtests/net/tcp/bbr/nsperf/nsperf.py
 | 
						|
 create mode 100755 gtests/net/tcp/bbr/nsperf/run_tests.sh
 | 
						|
 create mode 100755 gtests/net/tcp/bbr/nsperf/ss_log_parser.py
 | 
						|
 | 
						|
diff --git a/gtests/net/tcp/bbr/nsperf/graph_tests.sh b/gtests/net/tcp/bbr/nsperf/graph_tests.sh
 | 
						|
new file mode 100755
 | 
						|
index 000000000000..6277c4ffa1cc
 | 
						|
--- /dev/null
 | 
						|
+++ b/gtests/net/tcp/bbr/nsperf/graph_tests.sh
 | 
						|
@@ -0,0 +1,306 @@
 | 
						|
+#!/bin/bash
 | 
						|
+# For all test results, generate png graphs and an HTML page linking to them.
 | 
						|
+#
 | 
						|
+# By default, graphs all tests:
 | 
						|
+#   ./graph_tests.sh
 | 
						|
+# But you can also graph a subset of tests by setting the "tests"
 | 
						|
+# environment variable:
 | 
						|
+#   tests="coexist shallow" ./graph_tests.sh
 | 
						|
+#
 | 
						|
+# fancier usage:
 | 
						|
+#          indir=out.180.sec/ outdir=graphs/ ./graph_tests.sh
 | 
						|
+
 | 
						|
+if [ "$indir" = "" ]; then
 | 
						|
+    indir="out/"
 | 
						|
+fi
 | 
						|
+
 | 
						|
+if [ "$outdir" = "" ]; then
 | 
						|
+    outdir="graphs/"
 | 
						|
+fi
 | 
						|
+
 | 
						|
+# By default graph all tests.
 | 
						|
+# To graph a subset of tests, set the environment variable: tests="foo bar".
 | 
						|
+if [ "$tests" = "" ]; then
 | 
						|
+    tests="coexist random_loss shallow bufferbloat ecn_bulk"
 | 
						|
+fi
 | 
						|
+
 | 
						|
+format=png
 | 
						|
+if [ "$format" = "png" ]; then
 | 
						|
+  PNG_SIZE="1024,768"
 | 
						|
+  TERMINAL="set terminal pngcairo noenhanced size $PNG_SIZE"
 | 
						|
+else
 | 
						|
+  TERMINAL="set terminal wxt noenhanced size 1024,768"
 | 
						|
+fi
 | 
						|
+
 | 
						|
+mkdir -p $outdir
 | 
						|
+
 | 
						|
+# Start HTML for a web page showing all png graphs we generate.
 | 
						|
+TITLE="bbr v2 alpha upstream core tests"
 | 
						|
+HTML_PATH="${outdir}/index.html"
 | 
						|
+echo > $HTML_PATH
 | 
						|
+echo "<html><title>$TITLE</title><body> <b> $TITLE </b> <br>\n" >> $HTML_PATH
 | 
						|
+
 | 
						|
+if [[ $tests == *"coexist"* ]]; then
 | 
						|
+    #######
 | 
						|
+    # show acceptable coexistence w/ cubic:
 | 
						|
+    # graph tput of 1 cubic, 1 BBR at a range of buffer depths:
 | 
						|
+    # (bw=50M, rtt=30ms, buf={...}xBDP)
 | 
						|
+    rm -f $outdir/coexist.*
 | 
						|
+    for cc_combo in cubic:1,bbr:1 cubic:1,bbr2:1; do
 | 
						|
+	for bdp_of_buf in  0.1  1 2 4 8 16; do
 | 
						|
+	    echo -n "$bdp_of_buf " >> $outdir/coexist.${cc_combo}
 | 
						|
+	    grep THROUGHPUT $indir/coexist/${cc_combo}/${bdp_of_buf}/netperf.out.1.txt | \
 | 
						|
+		cut -d= -f2 >> $outdir/coexist.${cc_combo}
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+
 | 
						|
+    OUTPNG="$outdir/coexist_1xcubic_1xbbr2_50M_30ms_varybuf.png"
 | 
						|
+    OUTPUT="\n\
 | 
						|
+set output '$OUTPNG'"
 | 
						|
+
 | 
						|
+    echo -e "set y2tics\n\
 | 
						|
+	$TERMINAL $OUTPUT\n\
 | 
						|
+	set key top left\n\
 | 
						|
+	set ytics nomirror\n\
 | 
						|
+	set grid\n\
 | 
						|
+	set title  'cubic vs BBR throughput'\n\
 | 
						|
+        set xlabel 'buffer size (as a multiple of BDP)'\n\
 | 
						|
+        set ylabel 'throughput in Mbit/sec'\n\
 | 
						|
+	set yrange [0:50]\n\
 | 
						|
+	plot '$outdir/coexist.cubic:1,bbr:1'  u 1:2 t 'bbr'  w lp lw 2 pt 7 lt rgb \"#abd9e9\",\
 | 
						|
+	     '$outdir/coexist.cubic:1,bbr2:1' u 1:2 t 'bbr2' w lp lw 2 pt 7 lt rgb \"#2c7bb6\"\
 | 
						|
+             \n" > $outdir/coexist.gnuplot
 | 
						|
+
 | 
						|
+    gnuplot -persist $outdir/coexist.gnuplot
 | 
						|
+    echo -e "<img src='$OUTPNG'>\n" >> $HTML_PATH
 | 
						|
+fi
 | 
						|
+
 | 
						|
+
 | 
						|
+if [[ $tests == *"random_loss"* ]]; then
 | 
						|
+    #######
 | 
						|
+    # show high throughput with random loss up to design parameter:
 | 
						|
+    # graph tput of cubic, bbr2 at a range of random loss rates
 | 
						|
+    # (bw=1G, rtt=100ms, loss={...}
 | 
						|
+    rm -f $outdir/random_loss.*
 | 
						|
+    loss_rates="0.00001 0.0001 0.001 0.01 0.1 0.2 0.5 1 2 3 10 15 20"
 | 
						|
+    for loss_rate in $loss_rates; do
 | 
						|
+	for cc_name in cubic bbr bbr2; do
 | 
						|
+	    cc="${cc_name}:1"
 | 
						|
+	    sumd="$indir/random_loss/${cc}/${loss_rate}/summary/"
 | 
						|
+	    mkdir -p $sumd
 | 
						|
+	    rm -f "${sumd}/*txt"
 | 
						|
+	    for rep in `seq 1 10`; do
 | 
						|
+		d="$indir/random_loss/${cc}/${loss_rate}/rep-${rep}"
 | 
						|
+		grep THROUGHPUT ${d}/netperf.out.0.txt | cut -d= -f2 >> ${sumd}/THROUGHPUT.samples.txt
 | 
						|
+	    done
 | 
						|
+	    infile="${sumd}/THROUGHPUT.samples.txt" ./median.py > \
 | 
						|
+		  ${sumd}/THROUGHPUT.median.txt
 | 
						|
+	    echo -n "$loss_rate " >> $outdir/random_loss.${cc}
 | 
						|
+	    cat ${sumd}/THROUGHPUT.median.txt >> $outdir/random_loss.${cc}
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+
 | 
						|
+    OUTPNG="$outdir/random_loss_1G_100ms_varyloss.png"
 | 
						|
+    OUTPUT="\n\
 | 
						|
+set output '$OUTPNG'"
 | 
						|
+
 | 
						|
+    echo -e "set y2tics\n\
 | 
						|
+	$TERMINAL $OUTPUT\n\
 | 
						|
+	set key top right\n\
 | 
						|
+	set ytics nomirror\n\
 | 
						|
+	set grid\n\
 | 
						|
+        set logscale x\n\
 | 
						|
+	set title  'cubic, bbr, and bbr2 throughput with random loss'\n\
 | 
						|
+        set xlabel 'random loss rate, in percent'\n\
 | 
						|
+        set ylabel 'throughput in Mbit/sec'\n\
 | 
						|
+	set yrange [0:1000]\n\
 | 
						|
+        set xrange [:20]\n\
 | 
						|
+	plot '$outdir/random_loss.cubic:1' u 1:2 t 'cubic' w lp lw 2 pt 7 lt rgb \"#d7191c\",\
 | 
						|
+	     '$outdir/random_loss.bbr:1'   u 1:2 t 'bbr' w lp lw 2 pt 7 lt rgb \"#abd9e9\",\
 | 
						|
+	     '$outdir/random_loss.bbr2:1'  u 1:2 t 'bbr2'  w lp lw 2 pt 7 lt rgb \"#2c7bb6\"\
 | 
						|
+             \n" > $outdir/random_loss.gnuplot
 | 
						|
+
 | 
						|
+    gnuplot -persist $outdir/random_loss.gnuplot
 | 
						|
+    echo -e "<img src='$OUTPNG'>\n" >> $HTML_PATH
 | 
						|
+fi
 | 
						|
+
 | 
						|
+
 | 
						|
+if [[ $tests == *"shallow"* ]]; then
 | 
						|
+    #######
 | 
						|
+    # show reasonably low loss rates in shallow buffers:
 | 
						|
+    # graph retransmit rate for range of flow counts
 | 
						|
+    # (bw=1G, rtt=100ms, buf=1ms, num_flows={...})
 | 
						|
+    # BDP is 1G*100ms = 8256 packets
 | 
						|
+    rm -f $outdir/shallow_buf.*
 | 
						|
+    for num_flows in 1 10 30 60 100; do
 | 
						|
+	for cc_name in cubic bbr bbr2; do
 | 
						|
+	    echo -n "$num_flows " >> $outdir/shallow_buf.${cc_name}
 | 
						|
+	    d="$indir/shallow/${cc_name}:${num_flows}/${num_flows}"
 | 
						|
+	    infile=${d}/ss.log outdir=${d}/ ./ss_log_parser.py
 | 
						|
+	    cat ${d}/retrans.out.total.txt >> $outdir/shallow_buf.${cc_name}
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+
 | 
						|
+    OUTPNG="$outdir/shallow_buf_1G_100ms_varynumflows.png"
 | 
						|
+    OUTPUT="\n\
 | 
						|
+set output '$OUTPNG'"
 | 
						|
+
 | 
						|
+    echo -e "set y2tics\n\
 | 
						|
+	$TERMINAL $OUTPUT\n\
 | 
						|
+	set key top left\n\
 | 
						|
+	set ytics nomirror\n\
 | 
						|
+	set grid\n\
 | 
						|
+        set logscale x\n\
 | 
						|
+	set title  'cubic, bbr, and bbr2 retransmit rate in shallow buffers'\n\
 | 
						|
+        set xlabel 'number of flows'\n\
 | 
						|
+        set ylabel 'retransmit rate (percent)'\n\
 | 
						|
+	set yrange [0:15]\n\
 | 
						|
+        set xrange [:]\n\
 | 
						|
+	plot '$outdir/shallow_buf.cubic' u 1:2 t 'cubic' w lp lw 2 pt 7 lt rgb \"#d7191c\",\
 | 
						|
+	     '$outdir/shallow_buf.bbr'   u 1:2 t 'bbr' w lp lw 2 pt 7 lt rgb \"#abd9e9\",\
 | 
						|
+	     '$outdir/shallow_buf.bbr2'  u 1:2 t 'bbr2'  w lp lw 2 pt 7 lt rgb \"#2c7bb6\"\
 | 
						|
+             \n" > $outdir/shallow_buf.gnuplot
 | 
						|
+
 | 
						|
+    gnuplot -persist $outdir/shallow_buf.gnuplot
 | 
						|
+    echo -e "<img src='$OUTPNG'>\n" >> $HTML_PATH
 | 
						|
+fi
 | 
						|
+
 | 
						|
+
 | 
						|
+if [[ $tests == *"bufferbloat"* ]]; then
 | 
						|
+    #######
 | 
						|
+    # show low delay in deep buffers, even without ECN signal:
 | 
						|
+    # graph p50 RTT for two flows using either cubic or bbr2,
 | 
						|
+    # at a range of buffer depths.
 | 
						|
+    # (bw=50M, rtt=30ms, buf={...}xBDP)
 | 
						|
+    rm -f $outdir/bufferbloat.*
 | 
						|
+    for bdp_of_buf in 1 10 50 100; do
 | 
						|
+	for cc_name in cubic bbr bbr2; do
 | 
						|
+	    echo -n "$bdp_of_buf " >> $outdir/bufferbloat.${cc_name}
 | 
						|
+	    num_flows=2
 | 
						|
+	    d="$indir/bufferbloat/${cc_name}:${num_flows}/${bdp_of_buf}"
 | 
						|
+	    infile=${d}/ss.log outdir=${d}/ ./ss_log_parser.py
 | 
						|
+	    cat ${d}/rtt_p50.out.total.txt >> $outdir/bufferbloat.${cc_name}
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+
 | 
						|
+    OUTPNG="$outdir/bufferbloat_50M_30ms_varybuf.png"
 | 
						|
+    OUTPUT="\n\
 | 
						|
+set output '$OUTPNG'"
 | 
						|
+
 | 
						|
+    echo -e "set y2tics\n\
 | 
						|
+	$TERMINAL $OUTPUT\n\
 | 
						|
+	set key top left\n\
 | 
						|
+	set ytics nomirror\n\
 | 
						|
+	set grid\n\
 | 
						|
+	set title  'cubic, bbr, and bbr2 median RTT'\n\
 | 
						|
+        set xlabel 'buffer size (as a multiple of BDP)'\n\
 | 
						|
+        set ylabel 'median srtt sample (ms)'\n\
 | 
						|
+	set yrange [0:]\n\
 | 
						|
+        set xrange [1:100]\n\
 | 
						|
+	plot '$outdir/bufferbloat.cubic' u 1:2 t 'cubic' w lp lw 2 pt 7 lt rgb \"#d7191c\",\
 | 
						|
+	     '$outdir/bufferbloat.bbr'   u 1:2 t 'bbr' w lp lw 2 pt 7 lt rgb \"#abd9e9\",\
 | 
						|
+	     '$outdir/bufferbloat.bbr2'  u 1:2 t 'bbr2'  w lp lw 2 pt 7 lt rgb \"#2c7bb6\"\
 | 
						|
+             \n" > $outdir/bufferbloat.gnuplot
 | 
						|
+
 | 
						|
+    gnuplot -persist $outdir/bufferbloat.gnuplot
 | 
						|
+    echo -e "<img src='$OUTPNG'>\n" >> $HTML_PATH
 | 
						|
+fi
 | 
						|
+
 | 
						|
+if [[ $tests == *"ecn_bulk"* ]]; then
 | 
						|
+    rm -f $outdir/ecn_bulk.*
 | 
						|
+
 | 
						|
+    #######
 | 
						|
+    # show ECN support can keep queues very low:
 | 
						|
+    # graph p50 for range of flow counts.
 | 
						|
+    # (bw=1G, rtt=1ms, num_flows={...})
 | 
						|
+    # For each CC and flow count, show the median of the p50 RTT from N trials.
 | 
						|
+    for cc_name in dctcp bbr2 bbr; do
 | 
						|
+	for num_flows in 1 4 10 40 100; do
 | 
						|
+	    sumd="$indir/ecn_bulk/${cc_name}/${num_flows}/summary/"
 | 
						|
+	    mkdir -p $sumd
 | 
						|
+	    rm -f "${sumd}/*txt"
 | 
						|
+	    for rep in `seq 1 10`; do
 | 
						|
+		# Find median srtt for this rep, and add it to list
 | 
						|
+		# of all samples.
 | 
						|
+		d="$indir/ecn_bulk/${cc_name}/${num_flows}/rep-${rep}"
 | 
						|
+		infile=${d}/ss.log outdir=${d}/ ./ss_log_parser.py
 | 
						|
+		cat ${d}/rtt_p50.out.total.txt >> ${sumd}/rtt_p50.out.samples.txt
 | 
						|
+	    done
 | 
						|
+	    infile="${sumd}/rtt_p50.out.samples.txt" ./median.py > \
 | 
						|
+		  ${sumd}/rtt_p50.out.median.txt
 | 
						|
+	    echo -n "$num_flows " >> $outdir/ecn_bulk.${cc_name}
 | 
						|
+	    cat ${sumd}/rtt_p50.out.median.txt >> $outdir/ecn_bulk.${cc_name}
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+
 | 
						|
+    OUTPNG="$outdir/ecn_bulk_1G_1ms_rtt_varynumflows.png"
 | 
						|
+    OUTPUT="\n\
 | 
						|
+set output '$OUTPNG'"
 | 
						|
+
 | 
						|
+    echo -e "set y2tics\n\
 | 
						|
+	$TERMINAL $OUTPUT\n\
 | 
						|
+	set key top left\n\
 | 
						|
+	set ytics nomirror\n\
 | 
						|
+	set grid\n\
 | 
						|
+        set logscale x\n\
 | 
						|
+	set title  'dctcp, bbr, and bbr2 median RTT'\n\
 | 
						|
+        set xlabel 'number of flows'\n\
 | 
						|
+        set ylabel 'median srtt sample (ms)'\n\
 | 
						|
+	set yrange [0:]\n\
 | 
						|
+        set xrange [1:100]\n\
 | 
						|
+	plot '$outdir/ecn_bulk.dctcp'       u 1:2 t 'dctcp'           w lp lw 2 pt 7 lt rgb \"#d7191c\",\
 | 
						|
+	     '$outdir/ecn_bulk.bbr'         u 1:2 t 'bbr'             w lp lw 2 pt 7 lt rgb \"#abd9e9\",\
 | 
						|
+	     '$outdir/ecn_bulk.bbr2'  u 1:2 t 'bbr2' w lp lw 2 pt 7 lt rgb \"#2c7bb6\"\
 | 
						|
+             \n" > $outdir/ecn_bulk_rtt.gnuplot
 | 
						|
+
 | 
						|
+    gnuplot -persist $outdir/ecn_bulk_rtt.gnuplot
 | 
						|
+    echo -e "<img src='$OUTPNG'>\n" >> $HTML_PATH
 | 
						|
+
 | 
						|
+
 | 
						|
+    #######
 | 
						|
+    # show ECN support can keep queues very low:
 | 
						|
+    # graph median of retrans rates across N trials:
 | 
						|
+    for cc_name in dctcp bbr2 bbr; do
 | 
						|
+	for num_flows in 1 4 10 40 100; do
 | 
						|
+	    sumd="$indir/ecn_bulk/${cc_name}/${num_flows}/summary/"
 | 
						|
+	    mkdir -p $sumd
 | 
						|
+	    rm -f "${sumd}/*txt"
 | 
						|
+	    for rep in `seq 1 10`; do
 | 
						|
+		# Find overall retrans rate for this rep, and add it to list
 | 
						|
+		# of all samples.
 | 
						|
+		d="$indir/ecn_bulk/${cc_name}/${num_flows}/rep-${rep}"
 | 
						|
+		cat ${d}/retrans.out.total.txt >> ${sumd}/retrans.out.samples.txt
 | 
						|
+	    done
 | 
						|
+	    infile="${sumd}/retrans.out.samples.txt" ./median.py > \
 | 
						|
+		  ${sumd}/retrans.out.median.txt
 | 
						|
+	    echo -n "$num_flows " >> $outdir/ecn_bulk.retrans.${cc_name}
 | 
						|
+	    cat ${sumd}/retrans.out.median.txt >> $outdir/ecn_bulk.retrans.${cc_name}
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+
 | 
						|
+    OUTPNG="$outdir/ecn_bulk_1G_1ms_retrans_varynumflows.png"
 | 
						|
+    OUTPUT="\n\
 | 
						|
+set output '$OUTPNG'"
 | 
						|
+
 | 
						|
+    echo -e "set y2tics\n\
 | 
						|
+	$TERMINAL $OUTPUT\n\
 | 
						|
+	set key top left\n\
 | 
						|
+	set grid\n\
 | 
						|
+        set logscale x\n\
 | 
						|
+        set logscale y\n\
 | 
						|
+	set title  'dctcp, bbr, and bbr2 retransmit rate'\n\
 | 
						|
+        set xlabel 'number of flows'\n\
 | 
						|
+        set ylabel 'retransmit rate (percent)'\n\
 | 
						|
+	set yrange [:]\n\
 | 
						|
+        set xrange [1:100]\n\
 | 
						|
+	plot '$outdir/ecn_bulk.retrans.dctcp'       u 1:2 t 'dctcp' axis x1y1 w lp lw 2 pt 7 lt rgb \"#d7191c\",\
 | 
						|
+	     '$outdir/ecn_bulk.retrans.bbr'         u 1:2 t 'bbr'   axis x1y1 w lp lw 2 pt 7 lt rgb \"#abd9e9\",\
 | 
						|
+	     '$outdir/ecn_bulk.retrans.bbr2'  u 1:2 t 'bbr2'  axis x1y1 w lp lw 2 pt 7 lt rgb \"#2c7bb6\"\
 | 
						|
+             \n" > $outdir/ecn_bulk_retrans.gnuplot
 | 
						|
+
 | 
						|
+    gnuplot -persist $outdir/ecn_bulk_retrans.gnuplot
 | 
						|
+    echo -e "<img src='$OUTPNG'>\n" >> $HTML_PATH
 | 
						|
+
 | 
						|
+fi
 | 
						|
+
 | 
						|
+echo "done graphing all tests: $tests"
 | 
						|
diff --git a/gtests/net/tcp/bbr/nsperf/median.py b/gtests/net/tcp/bbr/nsperf/median.py
 | 
						|
new file mode 100755
 | 
						|
index 000000000000..f09ae072e0fd
 | 
						|
--- /dev/null
 | 
						|
+++ b/gtests/net/tcp/bbr/nsperf/median.py
 | 
						|
@@ -0,0 +1,43 @@
 | 
						|
+#!/usr/bin/python
 | 
						|
+#
 | 
						|
+# Read a file with one float per line, and print the median of all numbers.
 | 
						|
+# Usage:
 | 
						|
+#    infile=numbers.txt ./median.py
 | 
						|
+
 | 
						|
+import os
 | 
						|
+import sys
 | 
						|
+
 | 
						|
+def read_file():
 | 
						|
+    """Read a file with one float per line, and return as a list of floats."""
 | 
						|
+
 | 
						|
+    nums = []
 | 
						|
+
 | 
						|
+    path = os.environ['infile']
 | 
						|
+    f = open(path)
 | 
						|
+
 | 
						|
+    # Read a line, or EOF.
 | 
						|
+    line = f.readline()
 | 
						|
+    while True:
 | 
						|
+        if not line:
 | 
						|
+            return nums
 | 
						|
+        num_str = line.strip()
 | 
						|
+        num = float(num_str)
 | 
						|
+        nums.append(num)
 | 
						|
+        line = f.readline()
 | 
						|
+
 | 
						|
+def median(nums):
 | 
						|
+    """Return median of all numbers."""
 | 
						|
+
 | 
						|
+    sorted_nums = sorted(nums)
 | 
						|
+    n = len(sorted_nums)
 | 
						|
+    m = n - 1
 | 
						|
+    return (sorted_nums[n/2] + sorted_nums[m/2]) / 2.0
 | 
						|
+
 | 
						|
+def main():
 | 
						|
+    """Main function to run everything."""
 | 
						|
+    nums = read_file()
 | 
						|
+    print('%s' % median(nums))
 | 
						|
+    return 0
 | 
						|
+
 | 
						|
+if __name__ == '__main__':
 | 
						|
+    sys.exit(main())
 | 
						|
diff --git a/gtests/net/tcp/bbr/nsperf/nsperf.py b/gtests/net/tcp/bbr/nsperf/nsperf.py
 | 
						|
new file mode 100755
 | 
						|
index 000000000000..c8b5f697f0a8
 | 
						|
--- /dev/null
 | 
						|
+++ b/gtests/net/tcp/bbr/nsperf/nsperf.py
 | 
						|
@@ -0,0 +1,540 @@
 | 
						|
+#!/usr/bin/python
 | 
						|
+#
 | 
						|
+# Use netem, network namespaces, and veth virtual NICs
 | 
						|
+# to run a multi-flow TCP test on a single Linux machine.
 | 
						|
+#
 | 
						|
+# There is one network namespace for each emulated host.
 | 
						|
+# The emulated hosts are as follows:
 | 
						|
+#
 | 
						|
+#   srv: server (sender)
 | 
						|
+#   srt: server router
 | 
						|
+#   mid: middle host to emulate delays and bandwidth constraints
 | 
						|
+#   crt: client router
 | 
						|
+#   cli: client (receiver)
 | 
						|
+#
 | 
						|
+# Most hosts have both a left ("l") and right ("r") virtual NIC.
 | 
						|
+# The server has only an "r" NIC and the client has only an "l" NIC.
 | 
						|
+#
 | 
						|
+# The topology is as follows:
 | 
						|
+#
 | 
						|
+#   +-------+ +-------+ +-------+ +-------+ +-------+
 | 
						|
+#   |  srv  | |  srt  | |  mid  | |  crt  | |  cli  |
 | 
						|
+#   |     r +-+ l   r +-+ l   r +-+ l   r +-+ l     |
 | 
						|
+#   +-------+ +-------+ +-------+ +-------+ +-------+
 | 
						|
+#
 | 
						|
+# Authors:
 | 
						|
+#  Neal Cardwell
 | 
						|
+#  Soheil Hassas Yeganeh
 | 
						|
+#  Kevin (Yudong) Yang
 | 
						|
+#  Arjun Roy
 | 
						|
+
 | 
						|
+import os
 | 
						|
+import os.path
 | 
						|
+import socket
 | 
						|
+import sys
 | 
						|
+import threading
 | 
						|
+import time
 | 
						|
+
 | 
						|
+HOSTS = ['cli', 'crt', 'mid', 'srt', 'srv']
 | 
						|
+IP_MODE = socket.AF_INET6
 | 
						|
+SS_INTERVAL_SECONDS = 0.1  # gather 'ss' stats each X seconds
 | 
						|
+FIRST_PORT = 10000         # first TCP port to use
 | 
						|
+
 | 
						|
+# On Ubuntu 18.04.2 LTS, there are issues with the iproute2 binaries:
 | 
						|
+#  (1) the 'tc' binary  has a bug and cannot parse netem random loss rates
 | 
						|
+#  (2) the 'ss' tool is missing recent socket stats
 | 
						|
+# So to use this testing tool you may need to build your own iproute2 tools
 | 
						|
+# from the latest iproute2 sources:
 | 
						|
+#   sudo su -
 | 
						|
+#   apt install pkg-config bison flex
 | 
						|
+#   mkdir -p /root/iproute2/
 | 
						|
+#   cd /root/iproute2
 | 
						|
+#   git clone git://git.kernel.org/pub/scm/network/iproute2/iproute2.git
 | 
						|
+#   cd iproute2/
 | 
						|
+#   ./configure
 | 
						|
+#   make
 | 
						|
+SS_PATH = '/root/iproute2/iproute2/misc/ss'
 | 
						|
+TC_PATH = '/root/iproute2/iproute2/tc/tc'
 | 
						|
+
 | 
						|
+def netperf():
 | 
						|
+    if os.path.isfile('./netperf'):
 | 
						|
+        return './netperf'
 | 
						|
+    else:
 | 
						|
+        return '/usr/bin/netperf'
 | 
						|
+
 | 
						|
+def netserver():
 | 
						|
+    if os.path.isfile('./netserver'):
 | 
						|
+        return './netserver'
 | 
						|
+    else:
 | 
						|
+        return '/usr/bin/netserver'
 | 
						|
+
 | 
						|
+def log_dir():
 | 
						|
+    return '/tmp/'
 | 
						|
+
 | 
						|
+def run(cmd, verbose=True):
 | 
						|
+    if verbose:
 | 
						|
+        print('running: |%s|' % (cmd))
 | 
						|
+    status = os.system(cmd)
 | 
						|
+    if status != 0:
 | 
						|
+        sys.stderr.write('error %d executing: %s' % (status, cmd))
 | 
						|
+
 | 
						|
+def cleanup():
 | 
						|
+    """Delete all veth pairs and all network namespaces."""
 | 
						|
+    for host in HOSTS:
 | 
						|
+        run('( ip netns exec %(host)s ip link del dev %(host)s.l; '
 | 
						|
+            '  ip netns exec %(host)s ip link del dev %(host)s.r; '
 | 
						|
+            '  ip netns del %(host)s ) 2> /dev/null'  % {'host' : host})
 | 
						|
+
 | 
						|
+def setup_logging():
 | 
						|
+    """Set up all logging."""
 | 
						|
+    # Zero out /var/log/kern-debug.log so that we only get our test logs.
 | 
						|
+    run('logrotate -f /etc/logrotate.conf')
 | 
						|
+    # Set up BBR to log with printk to /var/log/kern-debug.log.
 | 
						|
+    run('echo Y > /sys/module/tcp_bbr2/parameters/debug_with_printk')
 | 
						|
+    run('echo 3 > /sys/module/tcp_bbr2/parameters/flags')
 | 
						|
+
 | 
						|
+def setup_namespaces():
 | 
						|
+    """Set up all network namespaces."""
 | 
						|
+    for host in HOSTS:
 | 
						|
+        run('ip netns add %(host)s'  % {'host' : host})
 | 
						|
+
 | 
						|
+def setup_loopback():
 | 
						|
+    """Set up loopback devices for all namespaces."""
 | 
						|
+    for host in HOSTS:
 | 
						|
+        run('ip netns exec %(host)s ifconfig lo up' % {'host' : host})
 | 
						|
+
 | 
						|
+def setup_veth():
 | 
						|
+    """Set up all veth interfaces."""
 | 
						|
+    c = ''
 | 
						|
+    c += 'ip link add srv.r type veth peer name srt.l\n'
 | 
						|
+    c += 'ip link add srt.r type veth peer name mid.l\n'
 | 
						|
+    c += 'ip link add mid.r type veth peer name crt.l\n'
 | 
						|
+    c += 'ip link add crt.r type veth peer name cli.l\n'
 | 
						|
+
 | 
						|
+    c += 'ip link set dev srv.r netns srv\n'
 | 
						|
+    c += 'ip link set dev srt.r netns srt\n'
 | 
						|
+    c += 'ip link set dev srt.l netns srt\n'
 | 
						|
+    c += 'ip link set dev mid.r netns mid\n'
 | 
						|
+    c += 'ip link set dev mid.l netns mid\n'
 | 
						|
+    c += 'ip link set dev crt.l netns crt\n'
 | 
						|
+    c += 'ip link set dev crt.r netns crt\n'
 | 
						|
+    c += 'ip link set dev cli.l netns cli\n'
 | 
						|
+
 | 
						|
+    c += 'ip netns exec srv ip link set srv.r up\n'
 | 
						|
+    c += 'ip netns exec srt ip link set srt.r up\n'
 | 
						|
+    c += 'ip netns exec srt ip link set srt.l up\n'
 | 
						|
+    c += 'ip netns exec mid ip link set mid.r up\n'
 | 
						|
+    c += 'ip netns exec mid ip link set mid.l up\n'
 | 
						|
+    c += 'ip netns exec crt ip link set crt.r up\n'
 | 
						|
+    c += 'ip netns exec crt ip link set crt.l up\n'
 | 
						|
+    c += 'ip netns exec cli ip link set cli.l up\n'
 | 
						|
+
 | 
						|
+    # Disable TSO, GSO, GRO, or else netem limit is interpreted per
 | 
						|
+    # multi-MSS skb, not per packet on the emulated wire.
 | 
						|
+    c += 'ip netns exec srt ethtool -K srt.r tso off gso off gro off\n'
 | 
						|
+    c += 'ip netns exec mid ethtool -K mid.l tso off gso off gro off\n'
 | 
						|
+    c += 'ip netns exec mid ethtool -K mid.r tso off gso off gro off\n'
 | 
						|
+    c += 'ip netns exec srt ethtool -K crt.l tso off gso off gro off\n'
 | 
						|
+
 | 
						|
+    # server
 | 
						|
+    c += 'ip netns exec srv ip addr add 192.168.0.1/24 dev srv.r\n'
 | 
						|
+
 | 
						|
+    # server router
 | 
						|
+    c += 'ip netns exec srt ip addr add 192.168.0.100/24 dev srt.l\n'
 | 
						|
+    c += 'ip netns exec srt ip addr add 192.168.1.1/24   dev srt.r\n'
 | 
						|
+
 | 
						|
+    # mid
 | 
						|
+    c += 'ip netns exec mid ip addr add 192.168.1.100/24 dev mid.l\n'
 | 
						|
+    c += 'ip netns exec mid ip addr add 192.168.2.1/24   dev mid.r\n'
 | 
						|
+
 | 
						|
+    # client router
 | 
						|
+    c += 'ip netns exec crt ip addr add 192.168.2.100/24 dev crt.l\n'
 | 
						|
+    c += 'ip netns exec crt ip addr add 192.168.3.1/24   dev crt.r\n'
 | 
						|
+
 | 
						|
+    # client
 | 
						|
+    c += 'ip netns exec cli ip addr add 192.168.3.100/24 dev cli.l\n'
 | 
						|
+
 | 
						|
+    run(c)
 | 
						|
+
 | 
						|
+def setup_routes():
 | 
						|
+    """Set up all routes."""
 | 
						|
+    c = ''
 | 
						|
+
 | 
						|
+    # server
 | 
						|
+    c += 'h=srv\n'
 | 
						|
+    c += 'ip netns exec $h tc qdisc add dev $h.r root fq\n'
 | 
						|
+    c += 'ip netns exec $h ip route add default via 192.168.0.100 dev $h.r\n'
 | 
						|
+
 | 
						|
+    # server router
 | 
						|
+    c += 'h=srt\n'
 | 
						|
+    c += 'ip netns exec $h ip route add default via 192.168.1.100 dev $h.r\n'
 | 
						|
+
 | 
						|
+    # mid
 | 
						|
+    c += 'h=mid\n'
 | 
						|
+    c += 'ip netns exec $h ip route add 192.168.3.0/24 via 192.168.2.100\n'
 | 
						|
+    c += 'ip netns exec $h ip route add default via 192.168.1.1 dev $h.l\n'
 | 
						|
+
 | 
						|
+    # client router
 | 
						|
+    c += 'h=crt\n'
 | 
						|
+    c += 'ip netns exec $h ip route add default via 192.168.2.1 dev $h.l\n'
 | 
						|
+
 | 
						|
+    # cli
 | 
						|
+    c += 'h=cli\n'
 | 
						|
+    c += 'ip netns exec $h ip route add default via 192.168.3.1 dev $h.l\n'
 | 
						|
+
 | 
						|
+    run(c)
 | 
						|
+
 | 
						|
+def setup_forwarding():
 | 
						|
+    """Enable forwarding in each namespace."""
 | 
						|
+    for host in HOSTS:
 | 
						|
+        run('ip netns exec %(host)s sysctl -q -w '
 | 
						|
+            'net.ipv4.ip_forward=1 '
 | 
						|
+            'net.ipv6.conf.all.forwarding=1'  % {'host' : host})
 | 
						|
+
 | 
						|
+def netem_limit(rate, delay, buf):
 | 
						|
+    """Get netem limit in packets.
 | 
						|
+
 | 
						|
+    Needs to hold the packets in emulated pipe and emulated buffer.
 | 
						|
+    """
 | 
						|
+    bdp_bits = (rate * 1000000.0) * (delay / 1000.0)
 | 
						|
+    bdp_bytes = bdp_bits / 8.0
 | 
						|
+    bdp = int(bdp_bytes / 1500.0)
 | 
						|
+    limit = bdp + buf
 | 
						|
+    return limit
 | 
						|
+
 | 
						|
+# Parse string like 'cubic:1,bbr:2' and return an array like:
 | 
						|
+# ['cubic', 'bbr', 'bbr']
 | 
						|
+def parse_cc_param(param_string):
 | 
						|
+    cc_list = []
 | 
						|
+    groups = param_string.split(',')
 | 
						|
+    for group in groups:
 | 
						|
+        (cc_name, count) = group.split(':')
 | 
						|
+        count = int(count)
 | 
						|
+        for i in range(0, count):
 | 
						|
+            cc_list.append(cc_name)
 | 
						|
+    return cc_list
 | 
						|
+
 | 
						|
+def get_params():
 | 
						|
+    # Invocations of this tool should set the following parameters as
 | 
						|
+    # environment variables.
 | 
						|
+    params = {
 | 
						|
+        'bw':          -1, # input bottleneck bw in Mbit/sec; required
 | 
						|
+        'rtt':         -1, # RTT in ms; required
 | 
						|
+        'buf':         -1, # input bottleneck buffer in packets; required
 | 
						|
+        'loss':         0, # input bottleneck loss rate in percent; optional
 | 
						|
+        'policer':      0, # input bottleneck policer rate, Mbit/sec; optional
 | 
						|
+        'cc':          '', # congestion control algorithm: required
 | 
						|
+        'interval':     0, # interval between flow starts, in secs; optional
 | 
						|
+        'dur':         -1, # length of test in secs: required
 | 
						|
+        'outdir':      '', # output directory for results
 | 
						|
+        'qdisc':       '', # qdisc at downstream bottleneck (empty for FIFO)
 | 
						|
+        'cmd':         '', # command to run (e.g. set sysctl values)
 | 
						|
+        'pcap':         0, # bytes per packet to capture; 0 for no tracing
 | 
						|
+    }
 | 
						|
+
 | 
						|
+    for key in params.keys():
 | 
						|
+        print('parsing key %s' % key)
 | 
						|
+        if key in os.environ:
 | 
						|
+           print('looking at env var with key %s, val %s' % (key, os.environ[key]))
 | 
						|
+        else:
 | 
						|
+           print('no env var with key %s' % (key))
 | 
						|
+        if key not in os.environ:
 | 
						|
+            if params[key] != 0:
 | 
						|
+              sys.stderr.write('missing %s in environment variables\n' % key)
 | 
						|
+              sys.exit(1)
 | 
						|
+        elif key == 'cc':
 | 
						|
+            params[key] = parse_cc_param(os.environ[key])
 | 
						|
+        elif type(params[key]) == str:
 | 
						|
+            params[key] = os.environ[key]
 | 
						|
+        else:
 | 
						|
+            params[key] = float(os.environ[key])
 | 
						|
+
 | 
						|
+    print(params)
 | 
						|
+    params['netperf'] = netperf()
 | 
						|
+    params['receiver_ip'] = '192.168.3.100'
 | 
						|
+    # 10Gbit/sec * 100ms is 125MBytes, so to tolerate
 | 
						|
+    # high loss rates and lots of SACKed data, we use
 | 
						|
+    # 512MByte socket send and receive buffers:
 | 
						|
+    params['mem'] = 536870912
 | 
						|
+    return params
 | 
						|
+
 | 
						|
+# Put bandwidth rate limiting using HTB, tied to user-specified
 | 
						|
+# queuing discipline at that bottleneck, on traffic coming in the cli.l device.
 | 
						|
+def setup_htb_and_qdisc(d):
 | 
						|
+    """Set up HTB for rate limiting, and user-specified qdisc for the queue."""
 | 
						|
+
 | 
						|
+    c = ''
 | 
						|
+
 | 
						|
+    # First load the necessary modules.
 | 
						|
+    c += ('rmmod ifb\n'
 | 
						|
+          'modprobe ifb numifbs=10\n'
 | 
						|
+          'modprobe act_mirred\n')
 | 
						|
+
 | 
						|
+    # Clear old queuing disciplines (qdisc) on the interfaces
 | 
						|
+    d['ext']         = 'cli.l'
 | 
						|
+    d['ext_ingress'] = 'cli.ifb0'
 | 
						|
+    d['host'] = 'cli'
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s qdisc del dev %(ext)s root\n') % d
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s qdisc del dev %(ext)s ingress\n') % d
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s qdisc del dev %(ext_ingress)s root\n') % d
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s qdisc del dev %(ext_ingress)s ingress\n') % d
 | 
						|
+
 | 
						|
+    # Create ingress ifb0 on client interface.
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s qdisc add dev %(ext)s handle ffff: ingress\n') % d
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          'ip link add %(ext_ingress)s type ifb\n') % d
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          'ip link set dev %(ext_ingress)s up\n') % d
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          'ifconfig %(ext_ingress)s txqueuelen 128000\n') % d
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          'ifconfig %(ext_ingress)s\n') % d
 | 
						|
+
 | 
						|
+    # Forward all ingress traffic to the IFB device.
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s filter add dev %(ext)s parent ffff: protocol all u32 '
 | 
						|
+          'match u32 0 0 action mirred egress redirect '
 | 
						|
+          'dev %(ext_ingress)s\n') % d
 | 
						|
+
 | 
						|
+    # Create an egress filter on the IFB device.
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s qdisc add dev %(ext_ingress)s root handle 1: '
 | 
						|
+          'htb default 11\n') % d
 | 
						|
+
 | 
						|
+    # Add root class HTB with rate limiting.
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s class add dev %(ext_ingress)s parent 1: classid 1:11 '
 | 
						|
+          '  htb rate %(IRATE)sMbit ceil %(IRATE)sMbit\n') % d
 | 
						|
+
 | 
						|
+    # Add qdisc for downstream bottleneck.
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s qdisc add dev %(ext_ingress)s parent 1:11 handle 20: '
 | 
						|
+          '%(QDISC)s\n') % d
 | 
						|
+
 | 
						|
+    c += ('ip netns exec %(host)s %(tc)s -stat qdisc show\n') % d
 | 
						|
+
 | 
						|
+    return c
 | 
						|
+
 | 
						|
+def setup_netem(params):
 | 
						|
+    """Set up netem on the crt (client router) host."""
 | 
						|
+
 | 
						|
+    d = {}
 | 
						|
+
 | 
						|
+    # Parameters for data direction.
 | 
						|
+    d['IRATE']   = params['bw']      # Mbit/sec
 | 
						|
+    d['IDELAY']  = params['rtt'] / 2 # ms
 | 
						|
+    d['IBUF']    = params['buf']     # packets
 | 
						|
+    d['ILOSS']   = params['loss']
 | 
						|
+    d['IREO']    = 0  # TODO: not implemented yet
 | 
						|
+    d['ILIMIT'] = netem_limit(rate=d['IRATE'], delay=d['IDELAY'], buf=d['IBUF'])
 | 
						|
+    d['POLICER'] = params['policer'] # Mbit/sec
 | 
						|
+    d['QDISC']   = params['qdisc']
 | 
						|
+
 | 
						|
+    # Parameters for ACK direction.
 | 
						|
+    d['ORATE']  = 1000 # Mbit/sec; TODO: not implemented yet
 | 
						|
+    d['ODELAY'] = params['rtt'] / 2 # ms
 | 
						|
+    d['OBUF']   = 1000 # packets; TODO: not implemented yet
 | 
						|
+    d['OLOSS']  = 0  # TODO: not implemented yet
 | 
						|
+    d['OREO']   = 0  # TODO: not implemented yet
 | 
						|
+    d['OLIMIT'] = netem_limit(rate=d['ORATE'], delay=d['ODELAY'], buf=d['OBUF'])
 | 
						|
+
 | 
						|
+    d['tc'] = TC_PATH
 | 
						|
+
 | 
						|
+    c = ''
 | 
						|
+
 | 
						|
+    # TODO: fix the policer mechanism to actually work...
 | 
						|
+    if params['policer'] > 0:
 | 
						|
+        d['host'] = 'mid'
 | 
						|
+        c = ('ip netns exec %(host)s '
 | 
						|
+             '%(tc)s filter list dev  %(host)s.r\n'%
 | 
						|
+             d)
 | 
						|
+        run(c)
 | 
						|
+
 | 
						|
+        c = ('ip netns exec %(host)s '
 | 
						|
+             '%(tc)s qdisc add dev %(host)s.l ingress\n' %
 | 
						|
+             d)
 | 
						|
+        run(c)
 | 
						|
+
 | 
						|
+        c = ('ip netns exec %(host)s '
 | 
						|
+             '%(tc)s filter add dev %(host)s.l '
 | 
						|
+             'parent 1: protocol ip prio 10 u32 '
 | 
						|
+             'match ip src 192.168.0.1/32 flowid 1:2 '
 | 
						|
+             'action police rate %(POLICER)sMbit burst 100k drop\n' %
 | 
						|
+             d)
 | 
						|
+        run(c)
 | 
						|
+        c = ''
 | 
						|
+
 | 
						|
+    if d['QDISC'] == '':
 | 
						|
+        # If the user doesn't need a fancy qdisc, and FIFO will do,
 | 
						|
+        # then use netem for rate limiting and buffering,
 | 
						|
+        # since netem seems more accurate than HTB.
 | 
						|
+        d['INETEM_RATE'] = 'rate %(IRATE)sMbit' % d
 | 
						|
+    else:
 | 
						|
+        d['INETEM_RATE'] = ''
 | 
						|
+        d['ILIMIT'] = '%d' % (2*1000*1000*1000) # buffer is in user's qdisc
 | 
						|
+
 | 
						|
+    # Inbound from sender -> receiver. Downstream rate limiting is on cli.l.
 | 
						|
+    d['host'] = 'crt'
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s qdisc add dev %(host)s.r root netem '
 | 
						|
+          'limit %(ILIMIT)s delay %(IDELAY)sms %(IREO)sms '
 | 
						|
+          'loss random %(ILOSS)s%% %(INETEM_RATE)s\n') % d
 | 
						|
+
 | 
						|
+    # Outbound from receiver -> sender.
 | 
						|
+    d['host'] = 'crt'
 | 
						|
+    c += ('ip netns exec %(host)s '
 | 
						|
+          '%(tc)s qdisc add dev %(host)s.l root netem '
 | 
						|
+          'limit %(OLIMIT)s delay %(ODELAY)sms %(OREO)sms '
 | 
						|
+          'loss random %(OLOSS)s%% '
 | 
						|
+          'rate %(ORATE)sMbit\n') % d
 | 
						|
+
 | 
						|
+    c += ('ip netns exec %(host)s %(tc)s -stat qdisc show\n') % d
 | 
						|
+
 | 
						|
+    if (d['QDISC'] != ''):
 | 
						|
+        c += setup_htb_and_qdisc(d)
 | 
						|
+
 | 
						|
+    run(c)
 | 
						|
+
 | 
						|
+def ss_log_thread(params):
 | 
						|
+    """Repeatedly run ss command and append log to file."""
 | 
						|
+    dur = params['dur']
 | 
						|
+    outdir = params['outdir']
 | 
						|
+    ss_log_path = os.path.join(outdir, 'ss.log')
 | 
						|
+    receiver_ip = params['receiver_ip']
 | 
						|
+    num_conns = len(params['cc'])
 | 
						|
+
 | 
						|
+    t0 = time.time()
 | 
						|
+    t = t0
 | 
						|
+    port_cnt = num_conns
 | 
						|
+    f = open(ss_log_path, 'w')
 | 
						|
+    f.truncate()
 | 
						|
+    f.close()
 | 
						|
+    if IP_MODE == socket.AF_INET6:
 | 
						|
+        ss_ip = '[%s]'
 | 
						|
+    else:
 | 
						|
+        ss_ip = '%s'
 | 
						|
+    ss_ip %= receiver_ip
 | 
						|
+    ss_cmd = ('ip netns exec srv '
 | 
						|
+              '%s -tinm "dport >= :%d and dport < :%d and dst %s" >> %s' % (
 | 
						|
+                  SS_PATH,
 | 
						|
+                  FIRST_PORT, FIRST_PORT + port_cnt, ss_ip, ss_log_path))
 | 
						|
+
 | 
						|
+    while t < t0 + dur:
 | 
						|
+        f = open(ss_log_path, 'a')
 | 
						|
+        f.write('# %f\n' % (time.time(),))
 | 
						|
+        f.close()
 | 
						|
+        run(ss_cmd, verbose=False)
 | 
						|
+        t += SS_INTERVAL_SECONDS
 | 
						|
+        to_sleep = t - time.time()
 | 
						|
+        if to_sleep > 0:
 | 
						|
+            time.sleep(to_sleep)
 | 
						|
+
 | 
						|
+def launch_ss(params):
 | 
						|
+    t = threading.Thread(target=ss_log_thread, args=(params,))
 | 
						|
+    t.start()
 | 
						|
+    return t
 | 
						|
+
 | 
						|
+def run_test(params):
 | 
						|
+    """Run one test case."""
 | 
						|
+    print('command: %s' % (sys.argv))
 | 
						|
+    run('uname -a; date; uptime')
 | 
						|
+    run('grep . /sys/module/tcp_bbr2/parameters/*')
 | 
						|
+    run('sysctl net.ipv4.tcp_ecn')
 | 
						|
+
 | 
						|
+    # Configure sender namespaces.
 | 
						|
+    run('ip netns exec srv bash -c "%s"' % params['cmd'])
 | 
						|
+
 | 
						|
+    # Configure receiver namespace.
 | 
						|
+    run('ip netns exec cli bash -c "%s"' % params['cmd'])
 | 
						|
+
 | 
						|
+    # Set up receiver process.
 | 
						|
+    run('pkill -f netserver')
 | 
						|
+    run('ip netns exec cli %s -N' % (netserver()))
 | 
						|
+
 | 
						|
+    # Set up output directory.
 | 
						|
+    outdir = params['outdir']
 | 
						|
+    run('mkdir -p %s' % outdir)
 | 
						|
+
 | 
						|
+    # Set up sender-side packet capture.
 | 
						|
+    if params['pcap'] > 0:
 | 
						|
+        snaplen = params['pcap']
 | 
						|
+        path = os.path.join(outdir, 'out.pcap')
 | 
						|
+        run('ip netns exec srv tcpdump -i srv.r -s %(snaplen)d -w %(path)s &' %
 | 
						|
+            {'path': path, 'snaplen': snaplen})
 | 
						|
+
 | 
						|
+    # Set up periodic sender-side 'ss' stat capture.
 | 
						|
+    ss_thread = launch_ss(params)
 | 
						|
+
 | 
						|
+    if sys.argv[1] == 'stream':
 | 
						|
+        num_conns = len(params['cc'])
 | 
						|
+        print('num_conns = %d' % (num_conns))
 | 
						|
+        t0 = time.time()
 | 
						|
+        t = t0
 | 
						|
+        for i in range(0, num_conns):
 | 
						|
+            conn_params = params.copy()
 | 
						|
+            if i != num_conns - 1:
 | 
						|
+                conn_params['bg'] = '&'  # all but the last in the background
 | 
						|
+            else:
 | 
						|
+                conn_params['bg'] = ''
 | 
						|
+            conn_params['cc'] = params['cc'][i]
 | 
						|
+            conn_params['port'] = FIRST_PORT + i
 | 
						|
+            conn_params['outfile'] = '%s/netperf.out.%d.txt' % (outdir, i)
 | 
						|
+            run('ip netns exec srv %(netperf)s '
 | 
						|
+                '-l %(dur)d -H %(receiver_ip)s -- -k THROUGHPUT '
 | 
						|
+                '-s %(mem)s,%(mem)s -S %(mem)s,%(mem)s '
 | 
						|
+                '-K %(cc)s -P %(port)s '
 | 
						|
+                '> %(outfile)s '
 | 
						|
+                '%(bg)s' % conn_params)
 | 
						|
+            t += params['interval']
 | 
						|
+            to_sleep = t - time.time()
 | 
						|
+            if to_sleep > 0:
 | 
						|
+                time.sleep(to_sleep)
 | 
						|
+    elif sys.argv[1] == 'rr':
 | 
						|
+        params['request_size'] = (10 + 20 + 40 + 80 + 160) * 1448
 | 
						|
+        params['test'] = sys.argv[2]
 | 
						|
+        conn_params['port'] = FIRST_PORT
 | 
						|
+        run('ip netns exec srv %(netperf)s '
 | 
						|
+            ' -P 0 -t %(test)s -H %(receiver_ip)s -- '
 | 
						|
+            '-K %(cc)s -P %(port)s '
 | 
						|
+            '-r %(request_size)d,1 '
 | 
						|
+            '-o P50_LATENCY,P90_LATENCY,P99_LATENCY,MAX_LATENCY,'
 | 
						|
+            'TRANSACTION_RATE,'
 | 
						|
+            'LOCAL_TRANSPORT_RETRANS,REMOTE_TRANSPORT_RETRANS' % params)
 | 
						|
+    else:
 | 
						|
+        sys.stderr.write('unknown test type argument: %s\n' % sys.argv[1])
 | 
						|
+        sys.exit(1)
 | 
						|
+
 | 
						|
+    ss_thread.join()
 | 
						|
+    run('killall tcpdump')
 | 
						|
+
 | 
						|
+    run('ls -l /tmp/*.gz')
 | 
						|
+    run('cp -af /var/log/kern-debug.log ' + outdir)
 | 
						|
+    run('rm -f ' + outdir + '/*.gz')
 | 
						|
+    run('ls -l /tmp/*.gz')
 | 
						|
+    run('gzip '  + outdir + '/kern-debug.log')
 | 
						|
+    run('gzip  ' + outdir + '/out.pcap')
 | 
						|
+    run('ls -l /tmp/*gz')
 | 
						|
+
 | 
						|
+def main():
 | 
						|
+    """Main function to run everything."""
 | 
						|
+    params = get_params()
 | 
						|
+    cleanup()
 | 
						|
+    setup_logging()
 | 
						|
+    setup_namespaces()
 | 
						|
+    setup_loopback()
 | 
						|
+    setup_veth()
 | 
						|
+    setup_routes()
 | 
						|
+    setup_forwarding()
 | 
						|
+    setup_netem(params)
 | 
						|
+    run_test(params)
 | 
						|
+    cleanup()
 | 
						|
+    return 0
 | 
						|
+
 | 
						|
+
 | 
						|
+if __name__ == '__main__':
 | 
						|
+    sys.exit(main())
 | 
						|
diff --git a/gtests/net/tcp/bbr/nsperf/run_tests.sh b/gtests/net/tcp/bbr/nsperf/run_tests.sh
 | 
						|
new file mode 100755
 | 
						|
index 000000000000..31fd028d1319
 | 
						|
--- /dev/null
 | 
						|
+++ b/gtests/net/tcp/bbr/nsperf/run_tests.sh
 | 
						|
@@ -0,0 +1,201 @@
 | 
						|
+#!/bin/bash
 | 
						|
+#
 | 
						|
+# Run a set of tests with bbr2, bbr, cubic, dctcp.
 | 
						|
+# By default, runs all tests:
 | 
						|
+#   ./run_tests.sh
 | 
						|
+# But you can also run a subset of tests by setting the "tests"
 | 
						|
+# environment variable:
 | 
						|
+#   tests="coexist shallow" ./run_tests.sh
 | 
						|
+#
 | 
						|
+
 | 
						|
+# By default run all tests.
 | 
						|
+# To run a subset of tests, set the environment variable: tests="foo bar".
 | 
						|
+if [ "$tests" = "" ]; then
 | 
						|
+    tests="coexist random_loss shallow bufferbloat ecn_bulk"
 | 
						|
+fi
 | 
						|
+
 | 
						|
+# Module parameters for the alpha research release of bbr2 are here:
 | 
						|
+MOD_PARAM_DIR=/sys/module/tcp_bbr2/parameters/
 | 
						|
+
 | 
						|
+# Disable ECN support:
 | 
						|
+function disable_bbr_ecn() {
 | 
						|
+    echo 0 > $MOD_PARAM_DIR/ecn_enable
 | 
						|
+    egrep . $MOD_PARAM_DIR/* | grep ecn_enable
 | 
						|
+    echo 5000 > $MOD_PARAM_DIR/ecn_max_rtt_us
 | 
						|
+    egrep . $MOD_PARAM_DIR/* | grep ecn_max_rtt_us
 | 
						|
+}
 | 
						|
+
 | 
						|
+# Enable ECN support, with the understanding that all ECN signals we get
 | 
						|
+# here will be DCTCP/L4S ECN signals:
 | 
						|
+function enable_bbr_ecn() {
 | 
						|
+    echo 1 > $MOD_PARAM_DIR/ecn_enable
 | 
						|
+    egrep . $MOD_PARAM_DIR/* | grep ecn_enable
 | 
						|
+    echo 0 > $MOD_PARAM_DIR/ecn_max_rtt_us
 | 
						|
+    egrep . $MOD_PARAM_DIR/* | grep ecn_max_rtt_us
 | 
						|
+}
 | 
						|
+
 | 
						|
+# Make sure send and receive buffers can grow quite large, e.g. for
 | 
						|
+# bw=1G, rtt=100ms or larger.
 | 
						|
+sysctl -w net.core.rmem_max=250000000 net.ipv4.tcp_rmem='4096 131072 250000000'
 | 
						|
+sysctl -w net.core.wmem_max=250000000 net.ipv4.tcp_wmem='4096  16384 250000000'
 | 
						|
+disable_bbr_ecn
 | 
						|
+
 | 
						|
+function get_buf_pkts() {
 | 
						|
+    buf_pkts=`echo | awk -v bw=$bw -v rtt=$rtt -v bdp_of_buf=$bdp_of_buf '{bdp_pkts = int(bw*1000*1000*rtt/1000.0 / (1514 * 8) * bdp_of_buf); print bdp_pkts;}'`
 | 
						|
+}
 | 
						|
+
 | 
						|
+if [[ $tests == *"coexist"* ]]; then
 | 
						|
+    # show acceptable coexistence w/ cubic:
 | 
						|
+    # graph tput of 1 cubic, 1 bbr2 at a range of buffer depths:
 | 
						|
+    # (bw=50M, rtt=30ms, buf={...}xBDP)
 | 
						|
+    # [run for a very long time, 10minutes, to find convergence...]
 | 
						|
+    for cc_combo in cubic:1,bbr:1 cubic:1,bbr2:1; do
 | 
						|
+	for bdp_of_buf in  0.1  1 2 4 8 16; do
 | 
						|
+	    cmd=""
 | 
						|
+	    cc=$cc_combo     # mix of CCs in this experiment
 | 
						|
+	    interval=2       # interval between flow starts, in secs
 | 
						|
+	    bw=50            # Mbit/sec
 | 
						|
+	    rtt=30           # ms
 | 
						|
+	    qdisc=''         # use netem FIFO
 | 
						|
+	    loss=0           # loss in percent
 | 
						|
+	    dur=180          # test duration in secs
 | 
						|
+	    outdir="out/coexist/${cc}/$bdp_of_buf/"
 | 
						|
+	    # Create output directory:
 | 
						|
+	    mkdir -p $outdir
 | 
						|
+	    get_buf_pkts
 | 
						|
+	    set +e
 | 
						|
+	    cc=$cc bw=$bw rtt=$rtt buf=$buf_pkts qdisc=$qdisc loss=$loss \
 | 
						|
+	      dur=$dur cmd=$cmd outdir=$outdir interval=$interval \
 | 
						|
+	      ./nsperf.py stream | tee ${outdir}/nsperf.out.txt
 | 
						|
+	    set -e
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+fi
 | 
						|
+
 | 
						|
+if [[ $tests == *"random_loss"* ]]; then
 | 
						|
+    # show high throughput with random loss up to design parameter:
 | 
						|
+    # graph tput of cubic, bbr2 at a range of random loss rates
 | 
						|
+    # (bw=1G, rtt=100ms, loss={....}
 | 
						|
+    for rep in `seq 1 10`; do
 | 
						|
+	for cc_name in cubic bbr2 bbr; do
 | 
						|
+	    loss_rates="0.00001 0.0001 0.001 0.01 0.1 0.2 0.5 1 2 3 10 15 20"
 | 
						|
+	    for loss_rate in $loss_rates; do
 | 
						|
+		cmd=""
 | 
						|
+		cc=${cc_name}:1  # 1 flow
 | 
						|
+		interval=0       # interval between flow starts, in secs
 | 
						|
+		bw=1000          # Mbit/sec
 | 
						|
+		rtt=100          # ms
 | 
						|
+		bdp_of_buf=1     # buffer = 100% of BDP, or 100ms
 | 
						|
+		qdisc=''         # use netem FIFO
 | 
						|
+		loss=$loss_rate  # loss in percent
 | 
						|
+		dur=60           # test duration in secs
 | 
						|
+		outdir="out/random_loss/${cc}/${loss}/rep-${rep}/"
 | 
						|
+		# Create output directory:
 | 
						|
+		mkdir -p $outdir
 | 
						|
+		get_buf_pkts
 | 
						|
+		set +e
 | 
						|
+		cc=$cc bw=$bw rtt=$rtt buf=$buf_pkts qdisc=$qdisc loss=$loss \
 | 
						|
+		  dur=$dur cmd=$cmd outdir=$outdir interval=$interval \
 | 
						|
+		  ./nsperf.py stream | tee ${outdir}/nsperf.out.txt
 | 
						|
+		set -e
 | 
						|
+	    done
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+fi
 | 
						|
+
 | 
						|
+if [[ $tests == *"shallow"* ]]; then
 | 
						|
+    # show reasonably low loss rates in shallow buffers:
 | 
						|
+    # graph retransmit rate for range of flow counts
 | 
						|
+    # (bw=1G, rtt=100ms, buf=1ms, num_flows={...})
 | 
						|
+    # BDP is 1G*100ms = 8256 packets
 | 
						|
+    for cc_name in cubic bbr2 bbr; do
 | 
						|
+	for num_flows in 1 10 30 60 100; do
 | 
						|
+	    cmd=""
 | 
						|
+	    cc=${cc_name}:${num_flows}  # all flows bbr2
 | 
						|
+	    interval=.139    # interval between flow starts, in secs
 | 
						|
+	    bw=1000          # Mbit/sec
 | 
						|
+	    rtt=100          # ms
 | 
						|
+	    bdp_of_buf=0.02  # buffer = 2% of BDP, or 2ms
 | 
						|
+	    qdisc=''         # use netem FIFO
 | 
						|
+	    loss=0           # loss in percent
 | 
						|
+	    dur=300          # test duration in secs
 | 
						|
+	    outdir="out/shallow/${cc}/${num_flows}/"
 | 
						|
+	    # Create output directory:
 | 
						|
+	    mkdir -p $outdir
 | 
						|
+	    get_buf_pkts
 | 
						|
+	    set +e
 | 
						|
+	    cc=$cc bw=$bw rtt=$rtt buf=$buf_pkts qdisc=$qdisc loss=$loss \
 | 
						|
+	      dur=$dur cmd=$cmd outdir=$outdir interval=$interval \
 | 
						|
+	      ./nsperf.py stream | tee ${outdir}/nsperf.out.txt
 | 
						|
+	    set -e
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+fi
 | 
						|
+
 | 
						|
+if [[ $tests == *"bufferbloat"* ]]; then
 | 
						|
+    # show low delay in deep buffers, even without ECN signal:
 | 
						|
+    # graph p50 RTT for two flows using either cubic or bbr2,
 | 
						|
+    # at a range of buffer depths.
 | 
						|
+    # (bw=50M, rtt=30ms, buf={...}xBDP)
 | 
						|
+    for cc_name in cubic bbr2 bbr; do
 | 
						|
+	for bdp_of_buf in 1 10 50 100; do
 | 
						|
+	    cmd=""
 | 
						|
+	    cc=${cc_name}:2  # 2 flows
 | 
						|
+	    interval=2       # interval between flow starts, in secs
 | 
						|
+	    bw=50            # Mbit/sec
 | 
						|
+	    rtt=30           # ms
 | 
						|
+	    qdisc=''         # use netem FIFO
 | 
						|
+	    loss=0           # loss in percent
 | 
						|
+	    dur=120          # test duration in secs
 | 
						|
+	    outdir="out/bufferbloat/${cc}/${bdp_of_buf}/"
 | 
						|
+	    # Create output directory:
 | 
						|
+	    mkdir -p $outdir
 | 
						|
+	    get_buf_pkts
 | 
						|
+	    set +e
 | 
						|
+	    cc=$cc bw=$bw rtt=$rtt buf=$buf_pkts qdisc=$qdisc loss=$loss \
 | 
						|
+	      dur=$dur cmd=$cmd outdir=$outdir interval=$interval \
 | 
						|
+	      ./nsperf.py stream | tee ${outdir}/nsperf.out.txt
 | 
						|
+	    set -e
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+fi
 | 
						|
+
 | 
						|
+
 | 
						|
+if [[ $tests == *"ecn_bulk"* ]]; then
 | 
						|
+    # show ECN support can keep queues very low:
 | 
						|
+    # graph p50 and p95 RTT (and retx, tput, fairness) for range of flow counts
 | 
						|
+    # (bw=1G, rtt=1ms, num_flows={...})
 | 
						|
+    enable_bbr_ecn
 | 
						|
+    for rep in `seq 1 10`; do
 | 
						|
+	for cc_name in dctcp bbr2 bbr; do
 | 
						|
+	    for num_flows in 1 4 10 40 100; do
 | 
						|
+		# Inside the child/test namespaces, enable ECN for
 | 
						|
+		# both active and passive connections:
 | 
						|
+		cmd='sysctl net.ipv4.tcp_ecn=1'
 | 
						|
+		cc=${cc_name}:${num_flows}  # all flows bbr2
 | 
						|
+		interval=.005    # interval between flow starts, in secs
 | 
						|
+		bw=1000          # Mbit/sec
 | 
						|
+		rtt=1            # ms
 | 
						|
+		buf_pkts=0       # not using netem buffer
 | 
						|
+		# We set the limit to 1000 packets, or 12ms at 1Gbit/sec.
 | 
						|
+		# We configure the target to be far higher, to disable
 | 
						|
+		# Codel-based drops.
 | 
						|
+		qdisc='codel ce_threshold 242us limit 1000 target 100ms'
 | 
						|
+		loss=0           # loss in percent
 | 
						|
+		dur=10           # test duration in secs
 | 
						|
+		outdir="out/ecn_bulk/${cc_name}/${num_flows}/rep-${rep}/"
 | 
						|
+		# Create output directory:
 | 
						|
+		mkdir -p $outdir
 | 
						|
+		get_buf_pkts
 | 
						|
+		set +e
 | 
						|
+		cc=$cc bw=$bw rtt=$rtt buf=$buf_pkts qdisc=$qdisc loss=$loss \
 | 
						|
+		  dur=$dur cmd=$cmd outdir=$outdir interval=$interval \
 | 
						|
+		  ./nsperf.py stream | tee ${outdir}/nsperf.out.txt
 | 
						|
+		set -e
 | 
						|
+	    done
 | 
						|
+	done
 | 
						|
+    done
 | 
						|
+    disable_bbr_ecn
 | 
						|
+fi
 | 
						|
+
 | 
						|
+echo "done running all tests: $tests"
 | 
						|
diff --git a/gtests/net/tcp/bbr/nsperf/ss_log_parser.py b/gtests/net/tcp/bbr/nsperf/ss_log_parser.py
 | 
						|
new file mode 100755
 | 
						|
index 000000000000..3717a9fc7c23
 | 
						|
--- /dev/null
 | 
						|
+++ b/gtests/net/tcp/bbr/nsperf/ss_log_parser.py
 | 
						|
@@ -0,0 +1,193 @@
 | 
						|
+#!/usr/bin/python
 | 
						|
+#
 | 
						|
+# Parse ss.log textual output written by ss_log_thread() in nsperf.py.
 | 
						|
+# Usage:
 | 
						|
+#    infile=foo/ss.log outdir=out/ ss_log_parser.py
 | 
						|
+#
 | 
						|
+# Author:
 | 
						|
+#  Neal Cardwell
 | 
						|
+# Based on code by:
 | 
						|
+#  Kevin (Yudong) Yang
 | 
						|
+#  Soheil Hassas Yeganeh
 | 
						|
+
 | 
						|
+import os
 | 
						|
+import socket
 | 
						|
+import sys
 | 
						|
+import time
 | 
						|
+
 | 
						|
+DEBUG = False   # enable debugging output?
 | 
						|
+
 | 
						|
+def debug(s):
 | 
						|
+    if DEBUG:
 | 
						|
+        print('DEBUG: %s' % s)
 | 
						|
+
 | 
						|
+def median(nums):
 | 
						|
+    """Return median of all numbers."""
 | 
						|
+
 | 
						|
+    if len(nums) == 0:
 | 
						|
+        return 0
 | 
						|
+    sorted_nums = sorted(nums)
 | 
						|
+    n = len(sorted_nums)
 | 
						|
+    m = n - 1
 | 
						|
+    return (sorted_nums[n/2] + sorted_nums[m/2]) / 2.0
 | 
						|
+
 | 
						|
+def read_file():
 | 
						|
+    """Read the ss.log file and parse into a dictionary."""
 | 
						|
+    all_data = {}   # data for all time:            <time>: time_data
 | 
						|
+    time_data = {}  # data for the current timestamp: <port>: { field: value }
 | 
						|
+    time_secs = -1
 | 
						|
+    ss_log_path = os.environ['infile']
 | 
						|
+    debug('reading path: %s' % (ss_log_path))
 | 
						|
+    f = open(ss_log_path)
 | 
						|
+
 | 
						|
+    # Read a timestamp line, or per-flow tuple line, or EOF.
 | 
						|
+    line = f.readline()
 | 
						|
+    debug('readline 1 => %s' % (line))
 | 
						|
+    while True:
 | 
						|
+        debug('line => %s' % (line))
 | 
						|
+
 | 
						|
+        # If the file is done or data for current time is done, save time data.
 | 
						|
+        if not line or line.startswith('# ') and len(time_data):
 | 
						|
+            debug('all_data time %d => time_data %s' %
 | 
						|
+                  (time_secs,  time_data))
 | 
						|
+            all_data[time_secs] = time_data
 | 
						|
+            time_data = {}
 | 
						|
+
 | 
						|
+        if not line:
 | 
						|
+            return all_data
 | 
						|
+
 | 
						|
+        # Check to see if we have data for a new point in time
 | 
						|
+        if line.startswith('# '):
 | 
						|
+            time_secs = float(line[2:])
 | 
						|
+            assert time_secs > 0, time_secs
 | 
						|
+            debug('time_secs = %s' % (time_secs))
 | 
						|
+            # Read ss column headers ("State...")
 | 
						|
+            line = f.readline()
 | 
						|
+            debug('readline column headers => %s' % (line))
 | 
						|
+            # Read next line
 | 
						|
+            line = f.readline()
 | 
						|
+            continue
 | 
						|
+
 | 
						|
+        # Parse line with 4-tuple
 | 
						|
+        debug('readline for 4-tuple => %s' % (line))
 | 
						|
+        if not line or line.startswith('# '):
 | 
						|
+            continue   # No live sockets with ports maching the ss query...
 | 
						|
+        if len(line.split()) != 5:
 | 
						|
+            sys.stderr.write('unable to find 4-tuple in: %s' % (line))
 | 
						|
+            #print('unable to find 4-tuple in: %s' % (line))
 | 
						|
+            sys.exit()
 | 
						|
+        flow_data = {}
 | 
						|
+        port = line.strip()
 | 
						|
+        port = int(port[port.rfind(':') + 1:])
 | 
						|
+        flow_data['port'] = port
 | 
						|
+
 | 
						|
+        # Read line with flow stats
 | 
						|
+        line = f.readline()
 | 
						|
+        debug('readline flow stats => %s' % (line))
 | 
						|
+        assert line, 'expected flow stats for port %d' % (port)
 | 
						|
+        stats = line.strip().split()
 | 
						|
+        debug('stats: %s' % (stats))
 | 
						|
+        for item in stats:
 | 
						|
+            if item.startswith('cwnd:'):
 | 
						|
+                flow_data['cwnd'] = int(item[item.rfind(':') + 1:])
 | 
						|
+            elif item.startswith('bytes_acked:'):
 | 
						|
+                flow_data['bytes_acked'] = int(item[item.rfind(':') + 1:])
 | 
						|
+            elif item.startswith('retrans:'):
 | 
						|
+                flow_data['retrans'] = int(item[item.rfind('/') + 1:])
 | 
						|
+            elif item.startswith('data_segs_out:'):
 | 
						|
+                flow_data['data_segs_out'] = int(item[item.rfind(':') + 1:])
 | 
						|
+            elif item.startswith('rtt:'):
 | 
						|
+                flow_data['rtt'] = (
 | 
						|
+                    float(item[item.find(':') + 1:item.rfind('/')]) / 1000
 | 
						|
+                )
 | 
						|
+            elif item.startswith('unacked:'):
 | 
						|
+                flow_data['unacked'] = int(item[item.find(':') + 1:])
 | 
						|
+        debug('time_data for time %s port %d: %s' %
 | 
						|
+              (time_secs, port, flow_data))
 | 
						|
+        if not 'cwnd' in flow_data:
 | 
						|
+            sys.stderr.write('unable to find cwnd in: %s' % (line))
 | 
						|
+            #print('unable to find cwnd in: %s' % (line))
 | 
						|
+            sys.exit()
 | 
						|
+        time_data[port] = flow_data
 | 
						|
+        # Move on to the next line:
 | 
						|
+        line = f.readline()
 | 
						|
+
 | 
						|
+def log_retrans_rate(all_data):
 | 
						|
+    """Log average retransmit rate for each flow and globally."""
 | 
						|
+    outdir = os.environ['outdir']
 | 
						|
+
 | 
						|
+    last_data_segs_out = {}  # last data_segs_out per port
 | 
						|
+    last_retrans =       {}  # last retransmitted packet count per port
 | 
						|
+    retrans_rates = {}      # maps port number to retrans rate
 | 
						|
+    for t in sorted(all_data.keys()):
 | 
						|
+        time_data = all_data[t]
 | 
						|
+        for port, flow_data in time_data.items():
 | 
						|
+            debug('port %d flow_data %s' % (port, flow_data))
 | 
						|
+            last_data_segs_out[port] = flow_data.get('data_segs_out', 0)
 | 
						|
+            debug('port %d last_data_segs_out=%s' %
 | 
						|
+                  (port, last_data_segs_out[port]))
 | 
						|
+            last_retrans[port] = flow_data.get('retrans', 0)
 | 
						|
+            debug('port %d last_retrans=' % last_retrans[port])
 | 
						|
+
 | 
						|
+    total_retrans = 0
 | 
						|
+    total_data_segs_out = 0
 | 
						|
+    for port in sorted(last_data_segs_out):
 | 
						|
+        if last_data_segs_out[port] == 0:
 | 
						|
+            sys.stderr.write('outdir=%s port %d: last_data_segs_out==0\n' %
 | 
						|
+                             (outdir, port))
 | 
						|
+            retrans = 0
 | 
						|
+        else:
 | 
						|
+            retrans = float(last_retrans[port]) / float(last_data_segs_out[port])
 | 
						|
+        retrans_rates[port] = retrans
 | 
						|
+        total_retrans += last_retrans[port]
 | 
						|
+        total_data_segs_out += last_data_segs_out[port]
 | 
						|
+    if total_data_segs_out == 0:
 | 
						|
+        sys.stderr.write('outdir=%s total_data_segs_out==0\n' % (outdir))
 | 
						|
+        total_retrans_rate = 0
 | 
						|
+    else:
 | 
						|
+        total_retrans_rate = float(total_retrans) / float(total_data_segs_out)
 | 
						|
+
 | 
						|
+    # Write average retx rate for each flow, in percent.
 | 
						|
+    i = 0
 | 
						|
+    for port, retrans_rate in retrans_rates.items():
 | 
						|
+        filename = 'retrans.out.%d.txt' % (i)
 | 
						|
+        f = open(os.path.join(outdir, filename), 'w')
 | 
						|
+        f.write('%.5f\n' % (retrans_rate * 100.0))
 | 
						|
+        f.close()
 | 
						|
+        i += 1
 | 
						|
+
 | 
						|
+    # Write average retx rate across all flows, in percent.
 | 
						|
+    filename = 'retrans.out.total.txt'
 | 
						|
+    f = open(os.path.join(outdir, filename), 'w')
 | 
						|
+    f.write('%.5f\n' % (total_retrans_rate * 100.0))
 | 
						|
+    f.close()
 | 
						|
+
 | 
						|
+def log_rtt(all_data):
 | 
						|
+    """Log median srtt for all srtt samples we took from periodic ss dumps."""
 | 
						|
+    rtts = []
 | 
						|
+    for t in sorted(all_data.keys()):
 | 
						|
+        time_data = all_data[t]
 | 
						|
+        for port, flow_data in time_data.items():
 | 
						|
+            debug('port %d flow_data %s' % (port, flow_data))
 | 
						|
+            if 'rtt' in flow_data:
 | 
						|
+                rtt = flow_data['rtt']
 | 
						|
+                rtts.append(rtt)
 | 
						|
+
 | 
						|
+    p50_rtt = median(rtts)
 | 
						|
+    p50_rtt = p50_rtt * 1000.0   # convert to ms
 | 
						|
+    # Write p50 srtt sample (in secs) we took across all flows.
 | 
						|
+    outdir = os.environ['outdir']
 | 
						|
+    filename = 'rtt_p50.out.total.txt'
 | 
						|
+    f = open(os.path.join(outdir, filename), 'w')
 | 
						|
+    f.write('%s\n' % p50_rtt)   # RTT in ms
 | 
						|
+    f.close()
 | 
						|
+
 | 
						|
+def main():
 | 
						|
+    """Main function to run everything."""
 | 
						|
+    all_data = read_file()
 | 
						|
+    log_retrans_rate(all_data)
 | 
						|
+    log_rtt(all_data)
 | 
						|
+    return 0
 | 
						|
+
 | 
						|
+if __name__ == '__main__':
 | 
						|
+    sys.exit(main())
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 04fe6a14db3068391b7b8599e6edf3a47a0b2294 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Mon, 22 Jul 2019 23:18:56 -0400
 | 
						|
Subject: [PATCH 18/27] net-tcp_bbr: v2: add a README.md for TCP BBR v2 alpha
 | 
						|
 release
 | 
						|
 | 
						|
Change-Id: I35a8c984e299d2af6e78c3d4b3aade5627678306
 | 
						|
---
 | 
						|
 README.md | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 | 
						|
 1 file changed, 169 insertions(+)
 | 
						|
 create mode 100644 README.md
 | 
						|
 | 
						|
diff --git a/README.md b/README.md
 | 
						|
new file mode 100644
 | 
						|
index 000000000000..340d7c472bca
 | 
						|
--- /dev/null
 | 
						|
+++ b/README.md
 | 
						|
@@ -0,0 +1,169 @@
 | 
						|
+# TCP BBR v2 Alpha/Preview Release
 | 
						|
+
 | 
						|
+This document gives a quick overview of Google's TCP BBR v2
 | 
						|
+alpha/preview release for Linux, and how to download, build, install,
 | 
						|
+and test it.
 | 
						|
+
 | 
						|
+The TCP BBR v2 alpha/preview release is intended to enable research
 | 
						|
+collaboration and wider testing.  We encourage researchers to dive in
 | 
						|
+and help evaluate/improve the BBR v2 algorithm and code. We welcome
 | 
						|
+patches with good solutions to issues.
 | 
						|
+
 | 
						|
+This document shows how to download, build, install, and test
 | 
						|
+a Linux kernel running TCP BBR v2 alpha.
 | 
						|
+
 | 
						|
+## License
 | 
						|
+
 | 
						|
+Like Linux TCP BBR v1, the v2 code is dual-licensed as both GPLv2.0 (like the
 | 
						|
+Linux kernel) and BSD. You may use it under either license.
 | 
						|
+
 | 
						|
+## Viewing the TCP BBR v2 alpha sources
 | 
						|
+
 | 
						|
+You can view the current sources here:
 | 
						|
+[tcp_bbr2.c](https://github.com/google/bbr/blob/v2alpha/net/ipv4/tcp_bbr2.c)
 | 
						|
+
 | 
						|
+## Obtaining kernel sources with TCP BBR v2 alpha
 | 
						|
+
 | 
						|
+There are two main options for downloading the code:
 | 
						|
+
 | 
						|
+1. To create a new git repo starting from a Linux kernel with TCP BBR v2 alpha,
 | 
						|
+you can run:
 | 
						|
+
 | 
						|
+```
 | 
						|
+git clone -o google-bbr -b v2alpha  https://github.com/google/bbr.git
 | 
						|
+cd bbr/
 | 
						|
+```
 | 
						|
+
 | 
						|
+2. To download the code into an existing git repo, you can use:
 | 
						|
+
 | 
						|
+```
 | 
						|
+git remote add google-bbr https://github.com/google/bbr.git
 | 
						|
+git fetch google-bbr
 | 
						|
+git checkout google-bbr/v2alpha
 | 
						|
+```
 | 
						|
+
 | 
						|
+Note that if you already have a git repo that has imported the Linux source
 | 
						|
+tree, then the second option will be much faster and use much less space, since
 | 
						|
+it will only need to download the small deltas relative to the mainline Linux
 | 
						|
+source distribution.
 | 
						|
+
 | 
						|
+## Building and installing the kernel
 | 
						|
+
 | 
						|
+To build a Linux kernel with TCP BBR v2 support, copy that kernel to a target
 | 
						|
+(Debian or Ubuntu) test machine (bare metal or GCE), and reboot that machine,
 | 
						|
+you can use the following script, included in the TCP BBR v2 distribution:
 | 
						|
+
 | 
						|
+```
 | 
						|
+./gce-install.sh -m ${HOST}
 | 
						|
+```
 | 
						|
+
 | 
						|
+## Checking the kernel installation
 | 
						|
+
 | 
						|
+Once the target test machine has finished rebooting, then ssh to the target
 | 
						|
+test machine and become root with sudo or equivalent. First check that the
 | 
						|
+machine booted the kernel you built above:
 | 
						|
+
 | 
						|
+```
 | 
						|
+uname -a
 | 
						|
+```
 | 
						|
+
 | 
						|
+You should see the branch name SHA1 hash, and build time stamp from the kernel
 | 
						|
+you built above.
 | 
						|
+
 | 
						|
+
 | 
						|
+Then check what congestion control modules are available with:
 | 
						|
+```
 | 
						|
+sysctl net.ipv4.tcp_available_congestion_control
 | 
						|
+```
 | 
						|
+
 | 
						|
+You should see something like:
 | 
						|
+```
 | 
						|
+net.ipv4.tcp_available_congestion_control = reno bbr bbr2 cubic dctcp
 | 
						|
+```
 | 
						|
+
 | 
						|
+## Install test dependencies
 | 
						|
+
 | 
						|
+Next, copy the test scripts to the target test machine with:
 | 
						|
+
 | 
						|
+```
 | 
						|
+scp -r gtests/net/tcp/bbr/nsperf/ ${HOST}:/tmp/
 | 
						|
+```
 | 
						|
+
 | 
						|
+Before running the tests for the first time, as a one-time step you'll need to
 | 
						|
+install the dependencies on the test machine, as root:
 | 
						|
+
 | 
						|
+```
 | 
						|
+mv /tmp/nsperf /root/
 | 
						|
+apt-get install --yes python netperf gnuplot5-nox
 | 
						|
+```
 | 
						|
+
 | 
						|
+The 'tc' and 'ss' binaries on some prominent distributions, including Ubuntu 18
 | 
						|
+LTS, are out of date and buggy. To run the TCP BBR v2 test scripts, you will
 | 
						|
+probably need to download and use the latest versions:
 | 
						|
+
 | 
						|
+```
 | 
						|
+apt-get install pkg-config bison flex
 | 
						|
+mkdir -p /root/iproute2/
 | 
						|
+cd /root/iproute2
 | 
						|
+git clone git://git.kernel.org/pub/scm/network/iproute2/iproute2.git
 | 
						|
+cd iproute2/
 | 
						|
+./configure
 | 
						|
+make
 | 
						|
+```
 | 
						|
+
 | 
						|
+## Running TCP BBR v2 tests and generating graphs
 | 
						|
+
 | 
						|
+To run the tests, ssh to the target test machine and become root with sudo or
 | 
						|
+equivalent. Then run the tests and generate graphs with:
 | 
						|
+
 | 
						|
+```
 | 
						|
+cd /root/nsperf
 | 
						|
+./run_tests.sh
 | 
						|
+./graph_tests.sh
 | 
						|
+```
 | 
						|
+
 | 
						|
+This will run for hours, and place the graphs in the ./graphs/ directory.
 | 
						|
+
 | 
						|
+You can run and graph a subset of the tests by specifying the test by name as
 | 
						|
+an environment variable. For example:
 | 
						|
+
 | 
						|
+```
 | 
						|
+cd /root/nsperf
 | 
						|
+tests=random_loss ./run_tests.sh
 | 
						|
+tests=random_loss ./graph_tests.sh
 | 
						|
+```
 | 
						|
+
 | 
						|
+Enjoy!
 | 
						|
+
 | 
						|
+## Release Notes and Details
 | 
						|
+
 | 
						|
+### Enabling ECN support
 | 
						|
+
 | 
						|
+For lab testing, researchers can enable BBRv2 ECN support with the following
 | 
						|
+commands. This is for use when you know that any ECN marks that the connections
 | 
						|
+experience will be DCTCP/L4S-style ECN marks, rather than RFC3168 ECN marks:
 | 
						|
+```
 | 
						|
+# negotiate TCP ECN for active and passive connections:
 | 
						|
+sysctl net.ipv4.tcp_ecn=1
 | 
						|
+# enable BBRv2 ECN response:
 | 
						|
+echo 1 > /sys/module/tcp_bbr2/parameters/ecn_enable
 | 
						|
+# enable BBRv2 ECN response at any RTT:
 | 
						|
+echo 0 > /sys/module/tcp_bbr2/parameters/ecn_max_rtt_us
 | 
						|
+```
 | 
						|
+Production use of the BBRv2 ECN functionality depends on negotiation or
 | 
						|
+configuration that is outside the scope of the BBRv2 alpha release.
 | 
						|
+
 | 
						|
+### Enabling experimental pacing approach discussed at IETF 106 ICCRG session
 | 
						|
+
 | 
						|
+To try the experimental pacing approach described in our IETF 106 presentation,
 | 
						|
+you can check out the `v2alpha-experimental-pacing` branch from the Google
 | 
						|
+BBR github repository:
 | 
						|
+```
 | 
						|
+git remote add google-bbr https://github.com/google/bbr.git
 | 
						|
+git fetch google-bbr
 | 
						|
+git checkout google-bbr/v2alpha-experimental-pacing
 | 
						|
+```
 | 
						|
+
 | 
						|
+## FAQ
 | 
						|
+
 | 
						|
+If you have questions about BBR, check the [BBR FAQ](https://github.com/google/bbr/blob/master/Documentation/bbr-faq.md).
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 1ebc5cc0a0055ee0ec5fb9b0ceef5d4fbed36d77 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Thu, 21 Nov 2019 15:28:01 -0500
 | 
						|
Subject: [PATCH 19/27] net-tcp_bbr: v2: remove unnecessary rs.delivered_ce
 | 
						|
 logic upon loss
 | 
						|
 | 
						|
There is no reason to compute rs.delivered_ce upon loss.
 | 
						|
 | 
						|
In fact, we specifically do not want to compute rs.delivered_ce upon loss.
 | 
						|
 | 
						|
Two issues:
 | 
						|
 | 
						|
(1) This would be the wrong thing to do, in behavior terms.  With
 | 
						|
    RACK's dynamic reordering window, losses can be marked long after
 | 
						|
    the sequence hole appears in the ACK/SACK stream. We want to to
 | 
						|
    catch the ECN mark rate rising too high as quickly as possible,
 | 
						|
    which means we want to check for high ECN mark rates at ACK time
 | 
						|
    (as BBRv2 currently does) and not loss marking time.
 | 
						|
 | 
						|
(2) This is dead code. The ECN mark rate cannot be detected as too
 | 
						|
    high because the check needs rs->delivered to be > 0 as well:
 | 
						|
 | 
						|
       if (rs->delivered_ce > 0 && rs->delivered > 0 &&
 | 
						|
 | 
						|
    Since we are not setting rs->delivered upon loss, this check
 | 
						|
    cannot succeed, so setting delivered_ce is pointless.
 | 
						|
 | 
						|
This dead and wrong line was discovered by Randall Stewart at Netflix
 | 
						|
as he was reading the BBRv2 code.
 | 
						|
 | 
						|
Change-Id: I37f83f418a259ec31d8f82de986db071b364b76a
 | 
						|
---
 | 
						|
 net/ipv4/tcp_bbr2.c | 1 -
 | 
						|
 1 file changed, 1 deletion(-)
 | 
						|
 | 
						|
diff --git a/net/ipv4/tcp_bbr2.c b/net/ipv4/tcp_bbr2.c
 | 
						|
index a6959b70e51d..e00b47850dce 100644
 | 
						|
--- a/net/ipv4/tcp_bbr2.c
 | 
						|
+++ b/net/ipv4/tcp_bbr2.c
 | 
						|
@@ -2508,7 +2508,6 @@ static void bbr2_skb_marked_lost(struct sock *sk, const struct sk_buff *skb)
 | 
						|
 	memset(&rs, 0, sizeof(rs));
 | 
						|
 	rs.tx_in_flight = scb->tx.in_flight;
 | 
						|
 	rs.lost = tp->lost - scb->tx.lost;
 | 
						|
-	rs.delivered_ce = tp->delivered_ce - scb->tx.delivered_ce;
 | 
						|
 	rs.is_app_limited = scb->tx.is_app_limited;
 | 
						|
 	if (bbr2_is_inflight_too_high(sk, &rs)) {
 | 
						|
 		rs.tx_in_flight = bbr2_inflight_hi_from_lost_skb(sk, &rs, skb);
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From f862d14080d2f53983f5417678140aaf5b51ef8b Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Sat, 16 Nov 2019 16:54:59 -0500
 | 
						|
Subject: [PATCH 20/27] net-gbuild: add Gconfig.bbr2 to gbuild kernel with
 | 
						|
 CONFIG_TCP_CONG_BBR2=y
 | 
						|
 | 
						|
Change-Id: I6edbb4240c8af97e6248d85591f86d5548586d2b
 | 
						|
---
 | 
						|
 net/ipv4/Gconfig.bbr2 | 1 +
 | 
						|
 1 file changed, 1 insertion(+)
 | 
						|
 create mode 100644 net/ipv4/Gconfig.bbr2
 | 
						|
 | 
						|
diff --git a/net/ipv4/Gconfig.bbr2 b/net/ipv4/Gconfig.bbr2
 | 
						|
new file mode 100644
 | 
						|
index 000000000000..1cdc3953f2be
 | 
						|
--- /dev/null
 | 
						|
+++ b/net/ipv4/Gconfig.bbr2
 | 
						|
@@ -0,0 +1 @@
 | 
						|
+CONFIG_TCP_CONG_BBR2=y
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From aa5718aaea0df59629a98736cdbf5e4c16c27e8a Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Mon, 17 Aug 2020 19:08:41 -0400
 | 
						|
Subject: [PATCH 21/27] net-tcp_bbr: v2: remove field bw_rtts that is unused in
 | 
						|
 BBRv2
 | 
						|
 | 
						|
Change-Id: I58e3346c707748a6f316f3ed060d2da84c32a79b
 | 
						|
---
 | 
						|
 net/ipv4/tcp_bbr2.c | 7 +------
 | 
						|
 1 file changed, 1 insertion(+), 6 deletions(-)
 | 
						|
 | 
						|
diff --git a/net/ipv4/tcp_bbr2.c b/net/ipv4/tcp_bbr2.c
 | 
						|
index e00b47850dce..6121cd46f81a 100644
 | 
						|
--- a/net/ipv4/tcp_bbr2.c
 | 
						|
+++ b/net/ipv4/tcp_bbr2.c
 | 
						|
@@ -179,9 +179,8 @@ struct bbr {
 | 
						|
 			min_rtt_win_sec:5,	/* max allowed value: 31 */
 | 
						|
 			probe_rtt_mode_ms:9,	/* max allowed value: 511 */
 | 
						|
 			full_bw_cnt:3,		/* max allowed value: 7 */
 | 
						|
-			bw_rtts:5,		/* max allowed value: 31 */
 | 
						|
 			cwnd_tso_budget:1,	/* allowed values: {0, 1} */
 | 
						|
-			unused3:1,
 | 
						|
+			unused3:6,
 | 
						|
 			drain_to_target:1,	/* boolean */
 | 
						|
 			precise_ece_ack:1,	/* boolean */
 | 
						|
 			extra_acked_in_startup:1, /* allowed values: {0, 1} */
 | 
						|
@@ -237,8 +236,6 @@ struct bbr_context {
 | 
						|
 	u32 log:1;
 | 
						|
 };
 | 
						|
 
 | 
						|
-/* Window length of bw filter (in rounds). Max allowed value is 31 (0x1F) */
 | 
						|
-static int bbr_bw_rtts = CYCLE_LEN + 2;
 | 
						|
 /* Window length of min_rtt filter (in sec). Max allowed value is 31 (0x1F) */
 | 
						|
 static u32 bbr_min_rtt_win_sec = 10;
 | 
						|
 /* Minimum time (in ms) spent at bbr_cwnd_min_target in BBR_PROBE_RTT mode.
 | 
						|
@@ -390,7 +387,6 @@ static bool bbr_usage_based_cwnd;		/* default: disabled */
 | 
						|
  */
 | 
						|
 static bool bbr_ecn_enable = false;
 | 
						|
 
 | 
						|
-module_param_named(bw_rtts,           bbr_bw_rtts,           int,    0644);
 | 
						|
 module_param_named(min_tso_rate,      bbr_min_tso_rate,      int,    0644);
 | 
						|
 module_param_named(tso_rtt_shift,     bbr_tso_rtt_shift,     int,    0644);
 | 
						|
 module_param_named(high_gain,         bbr_high_gain,         int,    0644);
 | 
						|
@@ -1247,7 +1243,6 @@ static void bbr_init(struct sock *sk)
 | 
						|
 	bbr->params.min_rtt_win_sec = min(0x1FU, bbr_min_rtt_win_sec);
 | 
						|
 	bbr->params.probe_rtt_mode_ms = min(0x1FFU, bbr_probe_rtt_mode_ms);
 | 
						|
 	bbr->params.full_bw_cnt = min(0x7U, bbr_full_bw_cnt);
 | 
						|
-	bbr->params.bw_rtts = min(0x1F, bbr_bw_rtts);
 | 
						|
 	bbr->params.full_bw_thresh = min(0x3FFU, bbr_full_bw_thresh);
 | 
						|
 	bbr->params.extra_acked_gain = min(0x7FF, bbr_extra_acked_gain);
 | 
						|
 	bbr->params.extra_acked_win_rtts = min(0x1FU, bbr_extra_acked_win_rtts);
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 416700eb80d584802cfe40c4199f914485832fa0 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Mon, 17 Aug 2020 19:10:21 -0400
 | 
						|
Subject: [PATCH 22/27] net-tcp_bbr: v2: remove cycle_rand parameter that is
 | 
						|
 unused in BBRv2
 | 
						|
 | 
						|
Change-Id: Iee1df7e41e42de199068d7c89131ed3d228327c0
 | 
						|
---
 | 
						|
 net/ipv4/tcp_bbr2.c | 3 ---
 | 
						|
 1 file changed, 3 deletions(-)
 | 
						|
 | 
						|
diff --git a/net/ipv4/tcp_bbr2.c b/net/ipv4/tcp_bbr2.c
 | 
						|
index 6121cd46f81a..57b4abebb275 100644
 | 
						|
--- a/net/ipv4/tcp_bbr2.c
 | 
						|
+++ b/net/ipv4/tcp_bbr2.c
 | 
						|
@@ -303,8 +303,6 @@ static int bbr_pacing_gain[] = {
 | 
						|
 	BBR_UNIT, BBR_UNIT, BBR_UNIT,	/* cruise at 1.0*bw to utilize pipe, */
 | 
						|
 	BBR_UNIT, BBR_UNIT, BBR_UNIT	/* without creating excess queue... */
 | 
						|
 };
 | 
						|
-/* Randomize the starting gain cycling phase over N phases: */
 | 
						|
-static u32 bbr_cycle_rand = 7;
 | 
						|
 
 | 
						|
 /* Try to keep at least this many packets in flight, if things go smoothly. For
 | 
						|
  * smooth functioning, a sliding window protocol ACKing every other packet
 | 
						|
@@ -395,7 +393,6 @@ module_param_named(startup_cwnd_gain, bbr_startup_cwnd_gain, int,    0644);
 | 
						|
 module_param_named(cwnd_gain,         bbr_cwnd_gain,         int,    0644);
 | 
						|
 module_param_array_named(pacing_gain, bbr_pacing_gain,       int,
 | 
						|
 			 &bbr_pacing_gain_size, 0644);
 | 
						|
-module_param_named(cycle_rand,        bbr_cycle_rand,        uint,   0644);
 | 
						|
 module_param_named(cwnd_min_target,   bbr_cwnd_min_target,   uint,   0644);
 | 
						|
 module_param_named(probe_rtt_cwnd_gain,
 | 
						|
 		   bbr_probe_rtt_cwnd_gain,		     uint,   0664);
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 2547331871679f48054cd712131b519792d7cef6 Mon Sep 17 00:00:00 2001
 | 
						|
From: Jason Xing <kerneljasonxing@gmail.com>
 | 
						|
Date: Thu, 10 Sep 2020 09:02:18 -0400
 | 
						|
Subject: [PATCH 23/27] net-test: use crt namespace when nsperf disables crt.l
 | 
						|
 TSO/GSO/GRO
 | 
						|
 | 
						|
Changing the 'srt' to 'crt' is the right way to disable the features of
 | 
						|
the crt.l.
 | 
						|
 | 
						|
Signed-off-by: Jason Xing <kerneljasonxing@gmail.com>
 | 
						|
---
 | 
						|
 gtests/net/tcp/bbr/nsperf/nsperf.py | 2 +-
 | 
						|
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
						|
 | 
						|
diff --git a/gtests/net/tcp/bbr/nsperf/nsperf.py b/gtests/net/tcp/bbr/nsperf/nsperf.py
 | 
						|
index c8b5f697f0a8..ed107c2fa245 100755
 | 
						|
--- a/gtests/net/tcp/bbr/nsperf/nsperf.py
 | 
						|
+++ b/gtests/net/tcp/bbr/nsperf/nsperf.py
 | 
						|
@@ -134,7 +134,7 @@ def setup_veth():
 | 
						|
     c += 'ip netns exec srt ethtool -K srt.r tso off gso off gro off\n'
 | 
						|
     c += 'ip netns exec mid ethtool -K mid.l tso off gso off gro off\n'
 | 
						|
     c += 'ip netns exec mid ethtool -K mid.r tso off gso off gro off\n'
 | 
						|
-    c += 'ip netns exec srt ethtool -K crt.l tso off gso off gro off\n'
 | 
						|
+    c += 'ip netns exec crt ethtool -K crt.l tso off gso off gro off\n'
 | 
						|
 
 | 
						|
     # server
 | 
						|
     c += 'ip netns exec srv ip addr add 192.168.0.1/24 dev srv.r\n'
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 2955af01a0000c8e29e3202d401acadc0b6e6409 Mon Sep 17 00:00:00 2001
 | 
						|
From: Neal Cardwell <ncardwell@google.com>
 | 
						|
Date: Mon, 28 Dec 2020 19:23:09 -0500
 | 
						|
Subject: [PATCH 24/27] net-tcp_bbr: v2: don't assume prior_cwnd was set
 | 
						|
 entering CA_Loss
 | 
						|
 | 
						|
Fix WARN_ON_ONCE() warnings that were firing and pointing to a
 | 
						|
bbr->prior_cwnd of 0 when exiting CA_Loss and transitioning to
 | 
						|
CA_Open.
 | 
						|
 | 
						|
The issue was that tcp_simple_retransmit() calls:
 | 
						|
 | 
						|
  tcp_set_ca_state(sk, TCP_CA_Loss);
 | 
						|
 | 
						|
without first calling icsk_ca_ops->ssthresh(sk) (because
 | 
						|
tcp_simple_retransmit() is dealing with losses due to MTU issues and
 | 
						|
not congestion). The lack of this callback means that BBR did not get
 | 
						|
a chance to set bbr->prior_cwnd, and thus upon exiting CA_Loss in such
 | 
						|
cases the WARN_ON_ONCE() would fire due to a zero bbr->prior_cwnd.
 | 
						|
 | 
						|
This commit removes that warning, since a bbr->prior_cwnd of 0 is a
 | 
						|
valid situation in this state transition.
 | 
						|
 | 
						|
For setting inflight_lo upon entering CA_Loss, to avoid setting an
 | 
						|
inflight_lo of 0 in this case, this commit switches to taking the max
 | 
						|
of cwnd and prior_cwnd. We plan to remove that line of code when we
 | 
						|
switch to cautious (PRR-style) recovery, so that awkwardness will go
 | 
						|
away.
 | 
						|
 | 
						|
Change-Id: I575dce871c2f20e91e3e9449e1706f42a07b8118
 | 
						|
---
 | 
						|
 net/ipv4/tcp_bbr2.c | 7 ++-----
 | 
						|
 1 file changed, 2 insertions(+), 5 deletions(-)
 | 
						|
 | 
						|
diff --git a/net/ipv4/tcp_bbr2.c b/net/ipv4/tcp_bbr2.c
 | 
						|
index 57b4abebb275..5510adc92bbb 100644
 | 
						|
--- a/net/ipv4/tcp_bbr2.c
 | 
						|
+++ b/net/ipv4/tcp_bbr2.c
 | 
						|
@@ -2617,15 +2617,12 @@ static void bbr2_set_state(struct sock *sk, u8 new_state)
 | 
						|
 			/* bbr_adapt_lower_bounds() needs cwnd before
 | 
						|
 			 * we suffered an RTO, to update inflight_lo:
 | 
						|
 			 */
 | 
						|
-			WARN_ON_ONCE(bbr->prior_cwnd == 0);
 | 
						|
-			WARN_ON_ONCE(bbr->prior_cwnd == ~0U);
 | 
						|
-			bbr->inflight_lo = bbr->prior_cwnd;
 | 
						|
+			bbr->inflight_lo =
 | 
						|
+				max(tp->snd_cwnd, bbr->prior_cwnd);
 | 
						|
 		}
 | 
						|
 		bbr_debug(sk, 0, &rs, &ctx);
 | 
						|
 	} else if (bbr->prev_ca_state == TCP_CA_Loss &&
 | 
						|
 		   new_state != TCP_CA_Loss) {
 | 
						|
-		WARN_ON_ONCE(bbr->prior_cwnd == 0);
 | 
						|
-		WARN_ON_ONCE(bbr->prior_cwnd == ~0U);
 | 
						|
 		tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd);
 | 
						|
 		bbr->try_fast_path = 0; /* bound cwnd using latest model */
 | 
						|
 	}
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 81f6b1d79f9bccdfb2c10cea7930ccf6e18ce30f Mon Sep 17 00:00:00 2001
 | 
						|
From: Adithya Abraham Philip <abrahamphilip@google.com>
 | 
						|
Date: Fri, 11 Jun 2021 21:56:10 +0000
 | 
						|
Subject: [PATCH 25/27] net-tcp_bbr: v2: Fix missing ECT markings on
 | 
						|
 retransmits for BBRv2
 | 
						|
 | 
						|
Adds a new flag TCP_ECN_ECT_PERMANENT that is used by CCAs to
 | 
						|
indicate that retransmitted packets and pure ACKs must have the
 | 
						|
ECT bit set. This is a necessary fix for BBRv2, which when using
 | 
						|
ECN expects ECT to be set even on retransmitted packets and ACKs.
 | 
						|
Currently CCAs like BBRv2 which can use ECN but don't "need" it
 | 
						|
do not have a way to indicate that ECT should be set on
 | 
						|
retransmissions/ACKs.
 | 
						|
 | 
						|
Signed-off-by: Adithya Abraham Philip <abrahamphilip@google.com>
 | 
						|
Signed-off-by: Neal Cardwell <ncardwell@google.com>
 | 
						|
---
 | 
						|
 include/net/tcp.h     | 1 +
 | 
						|
 net/ipv4/tcp_bbr2.c   | 3 +++
 | 
						|
 net/ipv4/tcp_output.c | 3 ++-
 | 
						|
 3 files changed, 6 insertions(+), 1 deletion(-)
 | 
						|
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index b65268d3a3c2..a8868e515e13 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -375,6 +375,7 @@ static inline void tcp_dec_quickack_mode(struct sock *sk,
 | 
						|
 #define	TCP_ECN_QUEUE_CWR	2
 | 
						|
 #define	TCP_ECN_DEMAND_CWR	4
 | 
						|
 #define	TCP_ECN_SEEN		8
 | 
						|
+#define	TCP_ECN_ECT_PERMANENT	16
 | 
						|
 
 | 
						|
 enum tcp_tw_status {
 | 
						|
 	TCP_TW_SUCCESS = 0,
 | 
						|
diff --git a/net/ipv4/tcp_bbr2.c b/net/ipv4/tcp_bbr2.c
 | 
						|
index 5510adc92bbb..fa49e17c47ca 100644
 | 
						|
--- a/net/ipv4/tcp_bbr2.c
 | 
						|
+++ b/net/ipv4/tcp_bbr2.c
 | 
						|
@@ -2471,6 +2471,9 @@ static void bbr2_init(struct sock *sk)
 | 
						|
 	bbr->alpha_last_delivered_ce = 0;
 | 
						|
 
 | 
						|
 	tp->fast_ack_mode = min_t(u32, 0x2U, bbr_fast_ack_mode);
 | 
						|
+
 | 
						|
+	if ((tp->ecn_flags & TCP_ECN_OK) && bbr_ecn_enable)
 | 
						|
+		tp->ecn_flags |= TCP_ECN_ECT_PERMANENT;
 | 
						|
 }
 | 
						|
 
 | 
						|
 /* Core TCP stack informs us that the given skb was just marked lost. */
 | 
						|
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
 | 
						|
index 5284249f4689..a9ceec2702b2 100644
 | 
						|
--- a/net/ipv4/tcp_output.c
 | 
						|
+++ b/net/ipv4/tcp_output.c
 | 
						|
@@ -375,7 +375,8 @@ static void tcp_ecn_send(struct sock *sk, struct sk_buff *skb,
 | 
						|
 				th->cwr = 1;
 | 
						|
 				skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;
 | 
						|
 			}
 | 
						|
-		} else if (!tcp_ca_needs_ecn(sk)) {
 | 
						|
+		} else if (!(tp->ecn_flags & TCP_ECN_ECT_PERMANENT) &&
 | 
						|
+			!tcp_ca_needs_ecn(sk)) {
 | 
						|
 			/* ACK or retransmitted segment: clear ECT|CE */
 | 
						|
 			INET_ECN_dontxmit(sk);
 | 
						|
 		}
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From 5d6b1c62321349f5ec6361f4f698f3c1e03e8f20 Mon Sep 17 00:00:00 2001
 | 
						|
From: Mubashir Adnan Qureshi <mubashirq@google.com>
 | 
						|
Date: Wed, 20 Jul 2022 00:11:26 +0000
 | 
						|
Subject: [PATCH 26/27] net-tcp_bbr: v2: add support for PLB in TCP and BBRv2
 | 
						|
 | 
						|
PLB (Protective Load Balancing) is a host based mechanism for load
 | 
						|
balancing across switch links. It leverages congestion signals(e.g. ECN)
 | 
						|
from transport layer to randomly change the path of the connection
 | 
						|
experiencing congestion. PLB changes the path of the connection by
 | 
						|
changing the outgoing IPv6 flow label for IPv6 connections (implemented
 | 
						|
in Linux by calling sk_rethink_txhash()). Because of this implementation
 | 
						|
mechanism, PLB can currently only work for IPv6 traffic. For more
 | 
						|
information, see the SIGCOMM 2022 paper:
 | 
						|
  https://doi.org/10.1145/3544216.3544226
 | 
						|
 | 
						|
Congestion control algorithms track PLB state and cause the connection
 | 
						|
to trigger a path change when either of the 2 conditions is satisfied:
 | 
						|
 | 
						|
- No packets are in flight and (# consecutive congested rounds >=
 | 
						|
  sysctl_tcp_plb_idle_rehash_rounds)
 | 
						|
- (# consecutive congested rounds >= sysctl_tcp_plb_rehash_rounds)
 | 
						|
 | 
						|
A round (RTT) is marked as congested when congestion signal
 | 
						|
(ECN ce_ratio) over an RTT is greater than sysctl_tcp_plb_cong_thresh.
 | 
						|
In the event of RTO, PLB (via tcp_write_timeout()) triggers a path
 | 
						|
change and disables congestion-triggered path changes for random time
 | 
						|
between (sysctl_tcp_plb_suspend_rto_sec, 2*sysctl_tcp_plb_suspend_rto_sec)
 | 
						|
to avoid hopping onto the "connectivity blackhole". RTO-triggered
 | 
						|
path changes can still happen during this cool-off period.
 | 
						|
 | 
						|
Change-Id: I5d0fb3ab55b27b506b0cf32bc93df892b5336c2c
 | 
						|
---
 | 
						|
 Documentation/networking/ip-sysctl.rst |  58 ++++++++++++++
 | 
						|
 include/linux/tcp.h                    |   3 +
 | 
						|
 include/net/inet_connection_sock.h     |   2 +-
 | 
						|
 include/net/netns/ipv4.h               |   5 ++
 | 
						|
 include/net/tcp.h                      |  17 +++++
 | 
						|
 include/uapi/linux/snmp.h              |   1 +
 | 
						|
 net/ipv4/Makefile                      |   2 +-
 | 
						|
 net/ipv4/proc.c                        |   1 +
 | 
						|
 net/ipv4/sysctl_net_ipv4.c             |  43 +++++++++++
 | 
						|
 net/ipv4/tcp_bbr2.c                    |  28 +++++--
 | 
						|
 net/ipv4/tcp_ipv4.c                    |   7 ++
 | 
						|
 net/ipv4/tcp_plb.c                     | 100 +++++++++++++++++++++++++
 | 
						|
 12 files changed, 260 insertions(+), 7 deletions(-)
 | 
						|
 create mode 100644 net/ipv4/tcp_plb.c
 | 
						|
 | 
						|
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
 | 
						|
index e7b3fa7bb3f7..03a85332d5d1 100644
 | 
						|
--- a/Documentation/networking/ip-sysctl.rst
 | 
						|
+++ b/Documentation/networking/ip-sysctl.rst
 | 
						|
@@ -1069,6 +1069,64 @@ tcp_child_ehash_entries - INTEGER
 | 
						|
 
 | 
						|
 	Default: 0
 | 
						|
 
 | 
						|
+tcp_plb_enabled - BOOLEAN
 | 
						|
+	If set, TCP PLB (Protective Load Balancing) is enabled. PLB is
 | 
						|
+	described in the following paper:
 | 
						|
+	https://doi.org/10.1145/3544216.3544226. Based on PLB parameters,
 | 
						|
+	upon sensing sustained congestion, TCP triggers a change in
 | 
						|
+	flow label field for outgoing IPv6 packets. A change in flow label
 | 
						|
+	field potentially changes the path of outgoing packets for switches
 | 
						|
+	that use ECMP/WCMP for routing.
 | 
						|
+
 | 
						|
+	Default: 0
 | 
						|
+
 | 
						|
+tcp_plb_cong_thresh - INTEGER
 | 
						|
+	Fraction of packets marked with congestion over a round (RTT) to
 | 
						|
+	tag that round as congested. This is referred to as K in the PLB paper:
 | 
						|
+	https://doi.org/10.1145/3544216.3544226.
 | 
						|
+
 | 
						|
+	The 0-1 fraction range is mapped to 0-256 range to avoid floating
 | 
						|
+	point operations. For example, 128 means that if at least 50% of
 | 
						|
+	the packets in a round were marked as congested then the round
 | 
						|
+	will be tagged as congested.
 | 
						|
+
 | 
						|
+	Possible Values: 0 - 256
 | 
						|
+
 | 
						|
+	Default: 128
 | 
						|
+
 | 
						|
+tcp_plb_idle_rehash_rounds - INTEGER
 | 
						|
+	Number of consecutive congested rounds (RTT) seen after which
 | 
						|
+	a rehash can be performed, given there are no packets in flight.
 | 
						|
+	This is referred to as M in PLB paper:
 | 
						|
+	https://doi.org/10.1145/3544216.3544226.
 | 
						|
+
 | 
						|
+	Possible Values: 0 - 31
 | 
						|
+
 | 
						|
+	Default: 3
 | 
						|
+
 | 
						|
+tcp_plb_rehash_rounds - INTEGER
 | 
						|
+	Number of consecutive congested rounds (RTT) seen after which
 | 
						|
+	a forced rehash can be performed. Be careful when setting this
 | 
						|
+	parameter, as a small value increases the risk of retransmissions.
 | 
						|
+	This is referred to as N in PLB paper:
 | 
						|
+	https://doi.org/10.1145/3544216.3544226.
 | 
						|
+
 | 
						|
+	Possible Values: 0 - 31
 | 
						|
+
 | 
						|
+	Default: 12
 | 
						|
+
 | 
						|
+tcp_plb_suspend_rto_sec - INTEGER
 | 
						|
+	Time, in seconds, to suspend PLB in event of an RTO. In order to avoid
 | 
						|
+	having PLB repath onto a connectivity "black hole", after an RTO a TCP
 | 
						|
+	connection suspends PLB repathing for a random duration between 1x and
 | 
						|
+	2x of this parameter. Randomness is added to avoid concurrent rehashing
 | 
						|
+	of multiple TCP connections. This should be set corresponding to the
 | 
						|
+	amount of time it takes to repair a failed link.
 | 
						|
+
 | 
						|
+	Possible Values: 0 - 255
 | 
						|
+
 | 
						|
+	Default: 60
 | 
						|
+
 | 
						|
 UDP variables
 | 
						|
 =============
 | 
						|
 
 | 
						|
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
 | 
						|
index d8f94ef1a297..85a47c049662 100644
 | 
						|
--- a/include/linux/tcp.h
 | 
						|
+++ b/include/linux/tcp.h
 | 
						|
@@ -450,6 +450,9 @@ struct tcp_sock {
 | 
						|
 	 */
 | 
						|
 	struct request_sock __rcu *fastopen_rsk;
 | 
						|
 	struct saved_syn *saved_syn;
 | 
						|
+
 | 
						|
+/* Rerouting information */
 | 
						|
+	u16	ecn_rehash;	/* PLB triggered rehash attempts */
 | 
						|
 };
 | 
						|
 
 | 
						|
 enum tsq_enum {
 | 
						|
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
 | 
						|
index 1387e67a017f..30cc3b859a06 100644
 | 
						|
--- a/include/net/inet_connection_sock.h
 | 
						|
+++ b/include/net/inet_connection_sock.h
 | 
						|
@@ -136,7 +136,7 @@ struct inet_connection_sock {
 | 
						|
 	u32			  icsk_user_timeout;
 | 
						|
 
 | 
						|
 /* XXX inflated by temporary internal debugging info */
 | 
						|
-#define ICSK_CA_PRIV_SIZE      (216)
 | 
						|
+#define ICSK_CA_PRIV_SIZE      (224)
 | 
						|
 	u64			  icsk_ca_priv[ICSK_CA_PRIV_SIZE / sizeof(u64)];
 | 
						|
 };
 | 
						|
 
 | 
						|
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
 | 
						|
index 1b8004679445..78d7ced36f94 100644
 | 
						|
--- a/include/net/netns/ipv4.h
 | 
						|
+++ b/include/net/netns/ipv4.h
 | 
						|
@@ -183,6 +183,11 @@ struct netns_ipv4 {
 | 
						|
 	unsigned long tfo_active_disable_stamp;
 | 
						|
 	u32 tcp_challenge_timestamp;
 | 
						|
 	u32 tcp_challenge_count;
 | 
						|
+	u8 sysctl_tcp_plb_enabled;
 | 
						|
+	int sysctl_tcp_plb_cong_thresh;
 | 
						|
+	u8 sysctl_tcp_plb_idle_rehash_rounds;
 | 
						|
+	u8 sysctl_tcp_plb_rehash_rounds;
 | 
						|
+	u8 sysctl_tcp_plb_suspend_rto_sec;
 | 
						|
 
 | 
						|
 	int sysctl_udp_wmem_min;
 | 
						|
 	int sysctl_udp_rmem_min;
 | 
						|
diff --git a/include/net/tcp.h b/include/net/tcp.h
 | 
						|
index a8868e515e13..46e4b0da345d 100644
 | 
						|
--- a/include/net/tcp.h
 | 
						|
+++ b/include/net/tcp.h
 | 
						|
@@ -2171,6 +2171,23 @@ extern void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq,
 | 
						|
 extern void tcp_rack_reo_timeout(struct sock *sk);
 | 
						|
 extern void tcp_rack_update_reo_wnd(struct sock *sk, struct rate_sample *rs);
 | 
						|
 
 | 
						|
+/* tcp_plb.c */
 | 
						|
+
 | 
						|
+#define TCP_PLB_SCALE 8	/* scaling factor for fractions in PLB (e.g. ce_ratio) */
 | 
						|
+
 | 
						|
+/* State for PLB (Protective Load Balancing) for a single TCP connection. */
 | 
						|
+struct tcp_plb_state {
 | 
						|
+	u8	consec_cong_rounds:5, /* consecutive congested rounds */
 | 
						|
+		enabled:1,	/* Check if PLB is enabled */
 | 
						|
+		unused:2;
 | 
						|
+	u32	pause_until; /* jiffies32 when PLB can resume repathing */
 | 
						|
+};
 | 
						|
+
 | 
						|
+void tcp_plb_update_state(const struct sock *sk, struct tcp_plb_state *plb,
 | 
						|
+			  const int cong_ratio);
 | 
						|
+void tcp_plb_check_rehash(struct sock *sk, struct tcp_plb_state *plb);
 | 
						|
+void tcp_plb_update_state_upon_rto(struct sock *sk, struct tcp_plb_state *plb);
 | 
						|
+
 | 
						|
 /* At how many usecs into the future should the RTO fire? */
 | 
						|
 static inline s64 tcp_rto_delta_us(const struct sock *sk)
 | 
						|
 {
 | 
						|
diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
 | 
						|
index 4d7470036a8b..8ce035f1c874 100644
 | 
						|
--- a/include/uapi/linux/snmp.h
 | 
						|
+++ b/include/uapi/linux/snmp.h
 | 
						|
@@ -292,6 +292,7 @@ enum
 | 
						|
 	LINUX_MIB_TCPDSACKIGNOREDDUBIOUS,	/* TCPDSACKIgnoredDubious */
 | 
						|
 	LINUX_MIB_TCPMIGRATEREQSUCCESS,		/* TCPMigrateReqSuccess */
 | 
						|
 	LINUX_MIB_TCPMIGRATEREQFAILURE,		/* TCPMigrateReqFailure */
 | 
						|
+	LINUX_MIB_TCPECNREHASH,			/* TCPECNRehash */
 | 
						|
 	__LINUX_MIB_MAX
 | 
						|
 };
 | 
						|
 
 | 
						|
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
 | 
						|
index 8dee1547d820..e7a86a50838a 100644
 | 
						|
--- a/net/ipv4/Makefile
 | 
						|
+++ b/net/ipv4/Makefile
 | 
						|
@@ -10,7 +10,7 @@ obj-y     := route.o inetpeer.o protocol.o \
 | 
						|
 	     tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
 | 
						|
 	     tcp_minisocks.o tcp_cong.o tcp_metrics.o tcp_fastopen.o \
 | 
						|
 	     tcp_rate.o tcp_recovery.o tcp_ulp.o \
 | 
						|
-	     tcp_offload.o datagram.o raw.o udp.o udplite.o \
 | 
						|
+	     tcp_offload.o tcp_plb.o datagram.o raw.o udp.o udplite.o \
 | 
						|
 	     udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \
 | 
						|
 	     fib_frontend.o fib_semantics.o fib_trie.o fib_notifier.o \
 | 
						|
 	     inet_fragment.o ping.o ip_tunnel_core.o gre_offload.o \
 | 
						|
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
 | 
						|
index 5386f460bd20..2c33c19b2423 100644
 | 
						|
--- a/net/ipv4/proc.c
 | 
						|
+++ b/net/ipv4/proc.c
 | 
						|
@@ -297,6 +297,7 @@ static const struct snmp_mib snmp4_net_list[] = {
 | 
						|
 	SNMP_MIB_ITEM("TCPDSACKIgnoredDubious", LINUX_MIB_TCPDSACKIGNOREDDUBIOUS),
 | 
						|
 	SNMP_MIB_ITEM("TCPMigrateReqSuccess", LINUX_MIB_TCPMIGRATEREQSUCCESS),
 | 
						|
 	SNMP_MIB_ITEM("TCPMigrateReqFailure", LINUX_MIB_TCPMIGRATEREQFAILURE),
 | 
						|
+	SNMP_MIB_ITEM("TCPECNRehash", LINUX_MIB_TCPECNREHASH),
 | 
						|
 	SNMP_MIB_SENTINEL
 | 
						|
 };
 | 
						|
 
 | 
						|
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
 | 
						|
index 9b8a6db7a66b..74a2e916175e 100644
 | 
						|
--- a/net/ipv4/sysctl_net_ipv4.c
 | 
						|
+++ b/net/ipv4/sysctl_net_ipv4.c
 | 
						|
@@ -40,6 +40,8 @@ static int one_day_secs = 24 * 3600;
 | 
						|
 static u32 fib_multipath_hash_fields_all_mask __maybe_unused =
 | 
						|
 	FIB_MULTIPATH_HASH_FIELD_ALL_MASK;
 | 
						|
 static unsigned int tcp_child_ehash_entries_max = 16 * 1024 * 1024;
 | 
						|
+static int tcp_plb_max_rounds = 31;
 | 
						|
+static int tcp_plb_max_cong_thresh = 256;
 | 
						|
 
 | 
						|
 /* obsolete */
 | 
						|
 static int sysctl_tcp_low_latency __read_mostly;
 | 
						|
@@ -1384,6 +1386,47 @@ static struct ctl_table ipv4_net_table[] = {
 | 
						|
 		.extra1		= SYSCTL_ZERO,
 | 
						|
 		.extra2		= SYSCTL_TWO,
 | 
						|
 	},
 | 
						|
+	{
 | 
						|
+		.procname       = "tcp_plb_enabled",
 | 
						|
+		.data           = &init_net.ipv4.sysctl_tcp_plb_enabled,
 | 
						|
+		.maxlen         = sizeof(u8),
 | 
						|
+		.mode           = 0644,
 | 
						|
+		.proc_handler   = proc_dou8vec_minmax,
 | 
						|
+		.extra1         = SYSCTL_ZERO,
 | 
						|
+		.extra2         = SYSCTL_ONE,
 | 
						|
+	},
 | 
						|
+	{
 | 
						|
+		.procname       = "tcp_plb_cong_thresh",
 | 
						|
+		.data           = &init_net.ipv4.sysctl_tcp_plb_cong_thresh,
 | 
						|
+		.maxlen         = sizeof(int),
 | 
						|
+		.mode           = 0644,
 | 
						|
+		.proc_handler   = proc_dointvec_minmax,
 | 
						|
+		.extra1         = SYSCTL_ZERO,
 | 
						|
+		.extra2         = &tcp_plb_max_cong_thresh,
 | 
						|
+	},
 | 
						|
+	{
 | 
						|
+		.procname       = "tcp_plb_idle_rehash_rounds",
 | 
						|
+		.data           = &init_net.ipv4.sysctl_tcp_plb_idle_rehash_rounds,
 | 
						|
+		.maxlen         = sizeof(u8),
 | 
						|
+		.mode           = 0644,
 | 
						|
+		.proc_handler   = proc_dou8vec_minmax,
 | 
						|
+		.extra2		= &tcp_plb_max_rounds,
 | 
						|
+	},
 | 
						|
+	{
 | 
						|
+		.procname       = "tcp_plb_rehash_rounds",
 | 
						|
+		.data           = &init_net.ipv4.sysctl_tcp_plb_rehash_rounds,
 | 
						|
+		.maxlen         = sizeof(u8),
 | 
						|
+		.mode           = 0644,
 | 
						|
+		.proc_handler   = proc_dou8vec_minmax,
 | 
						|
+		.extra2         = &tcp_plb_max_rounds,
 | 
						|
+	},
 | 
						|
+	{
 | 
						|
+		.procname       = "tcp_plb_suspend_rto_sec",
 | 
						|
+		.data           = &init_net.ipv4.sysctl_tcp_plb_suspend_rto_sec,
 | 
						|
+		.maxlen         = sizeof(u8),
 | 
						|
+		.mode           = 0644,
 | 
						|
+		.proc_handler   = proc_dou8vec_minmax,
 | 
						|
+	},
 | 
						|
 	{ }
 | 
						|
 };
 | 
						|
 
 | 
						|
diff --git a/net/ipv4/tcp_bbr2.c b/net/ipv4/tcp_bbr2.c
 | 
						|
index fa49e17c47ca..09319695da82 100644
 | 
						|
--- a/net/ipv4/tcp_bbr2.c
 | 
						|
+++ b/net/ipv4/tcp_bbr2.c
 | 
						|
@@ -167,6 +167,7 @@ struct bbr {
 | 
						|
 		initialized:1;	       /* has bbr_init() been called? */
 | 
						|
 	u32	alpha_last_delivered;	 /* tp->delivered    at alpha update */
 | 
						|
 	u32	alpha_last_delivered_ce; /* tp->delivered_ce at alpha update */
 | 
						|
+	struct	tcp_plb_state plb;
 | 
						|
 
 | 
						|
 	/* Params configurable using setsockopt. Refer to correspoding
 | 
						|
 	 * module param for detailed description of params.
 | 
						|
@@ -733,7 +734,11 @@ static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event)
 | 
						|
 	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
 	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
 
 | 
						|
-	if (event == CA_EVENT_TX_START && tp->app_limited) {
 | 
						|
+	if (event == CA_EVENT_TX_START) {
 | 
						|
+		tcp_plb_check_rehash(sk, &bbr->plb);
 | 
						|
+
 | 
						|
+		if (!tp->app_limited)
 | 
						|
+			return;
 | 
						|
 		bbr->idle_restart = 1;
 | 
						|
 		bbr->ack_epoch_mstamp = tp->tcp_mstamp;
 | 
						|
 		bbr->ack_epoch_acked = 0;
 | 
						|
@@ -1389,7 +1394,7 @@ static void bbr2_check_ecn_too_high_in_startup(struct sock *sk, u32 ce_ratio)
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
-static void bbr2_update_ecn_alpha(struct sock *sk)
 | 
						|
+static int bbr2_update_ecn_alpha(struct sock *sk)
 | 
						|
 {
 | 
						|
 	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
 	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
@@ -1398,14 +1403,14 @@ static void bbr2_update_ecn_alpha(struct sock *sk)
 | 
						|
 	u32 gain;
 | 
						|
 
 | 
						|
 	if (bbr->params.ecn_factor == 0)
 | 
						|
-		return;
 | 
						|
+		return -1;
 | 
						|
 
 | 
						|
 	delivered = tp->delivered - bbr->alpha_last_delivered;
 | 
						|
 	delivered_ce = tp->delivered_ce - bbr->alpha_last_delivered_ce;
 | 
						|
 
 | 
						|
 	if (delivered == 0 ||		/* avoid divide by zero */
 | 
						|
 	    WARN_ON_ONCE(delivered < 0 || delivered_ce < 0))  /* backwards? */
 | 
						|
-		return;
 | 
						|
+		return -1;
 | 
						|
 
 | 
						|
 	/* See if we should use ECN sender logic for this connection. */
 | 
						|
 	if (!bbr->ecn_eligible && bbr_ecn_enable &&
 | 
						|
@@ -1424,6 +1429,7 @@ static void bbr2_update_ecn_alpha(struct sock *sk)
 | 
						|
 	bbr->alpha_last_delivered_ce = tp->delivered_ce;
 | 
						|
 
 | 
						|
 	bbr2_check_ecn_too_high_in_startup(sk, ce_ratio);
 | 
						|
+	return (int)ce_ratio;
 | 
						|
 }
 | 
						|
 
 | 
						|
 /* Each round trip of BBR_BW_PROBE_UP, double volume of probing data. */
 | 
						|
@@ -2238,6 +2244,7 @@ static void bbr2_main(struct sock *sk, const struct rate_sample *rs)
 | 
						|
 	struct bbr_context ctx = { 0 };
 | 
						|
 	bool update_model = true;
 | 
						|
 	u32 bw;
 | 
						|
+	int ce_ratio = -1;
 | 
						|
 
 | 
						|
 	bbr->debug.event = '.';  /* init to default NOP (no event yet) */
 | 
						|
 
 | 
						|
@@ -2245,7 +2252,9 @@ static void bbr2_main(struct sock *sk, const struct rate_sample *rs)
 | 
						|
 	if (bbr->round_start) {
 | 
						|
 		bbr->rounds_since_probe =
 | 
						|
 			min_t(s32, bbr->rounds_since_probe + 1, 0xFF);
 | 
						|
-		bbr2_update_ecn_alpha(sk);
 | 
						|
+		ce_ratio = bbr2_update_ecn_alpha(sk);
 | 
						|
+		tcp_plb_update_state(sk, &bbr->plb, ce_ratio);
 | 
						|
+		tcp_plb_check_rehash(sk, &bbr->plb);
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	bbr->ecn_in_round  |= rs->is_ece;
 | 
						|
@@ -2408,6 +2417,7 @@ static void bbr2_init(struct sock *sk)
 | 
						|
 {
 | 
						|
 	struct tcp_sock *tp = tcp_sk(sk);
 | 
						|
 	struct bbr *bbr = inet_csk_ca(sk);
 | 
						|
+	const struct net *net = sock_net(sk);
 | 
						|
 
 | 
						|
 	bbr_init(sk);	/* run shared init code for v1 and v2 */
 | 
						|
 
 | 
						|
@@ -2470,6 +2480,13 @@ static void bbr2_init(struct sock *sk)
 | 
						|
 	bbr->alpha_last_delivered = 0;
 | 
						|
 	bbr->alpha_last_delivered_ce = 0;
 | 
						|
 
 | 
						|
+	bbr->plb.enabled = 0;
 | 
						|
+	bbr->plb.consec_cong_rounds = 0;
 | 
						|
+	bbr->plb.pause_until = 0;
 | 
						|
+	if ((tp->ecn_flags & TCP_ECN_OK) &&
 | 
						|
+	    net->ipv4.sysctl_tcp_plb_enabled)
 | 
						|
+		bbr->plb.enabled = 1;
 | 
						|
+
 | 
						|
 	tp->fast_ack_mode = min_t(u32, 0x2U, bbr_fast_ack_mode);
 | 
						|
 
 | 
						|
 	if ((tp->ecn_flags & TCP_ECN_OK) && bbr_ecn_enable)
 | 
						|
@@ -2614,6 +2631,7 @@ static void bbr2_set_state(struct sock *sk, u8 new_state)
 | 
						|
 		struct rate_sample rs = { .losses = 1 };
 | 
						|
 		struct bbr_context ctx = { 0 };
 | 
						|
 
 | 
						|
+		tcp_plb_update_state_upon_rto(sk, &bbr->plb);
 | 
						|
 		bbr->prev_ca_state = TCP_CA_Loss;
 | 
						|
 		bbr->full_bw = 0;
 | 
						|
 		if (!bbr2_is_probing_bandwidth(sk) && bbr->inflight_lo == ~0U) {
 | 
						|
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
 | 
						|
index da46357f501b..e05fde56cddf 100644
 | 
						|
--- a/net/ipv4/tcp_ipv4.c
 | 
						|
+++ b/net/ipv4/tcp_ipv4.c
 | 
						|
@@ -3207,6 +3207,13 @@ static int __net_init tcp_sk_init(struct net *net)
 | 
						|
 	net->ipv4.sysctl_tcp_fastopen_blackhole_timeout = 0;
 | 
						|
 	atomic_set(&net->ipv4.tfo_active_disable_times, 0);
 | 
						|
 
 | 
						|
+	/* Set default values for PLB */
 | 
						|
+	net->ipv4.sysctl_tcp_plb_enabled = 0; /* Disabled by default */
 | 
						|
+	net->ipv4.sysctl_tcp_plb_cong_thresh = 128; /* 50% congestion */
 | 
						|
+	net->ipv4.sysctl_tcp_plb_idle_rehash_rounds = 3;
 | 
						|
+	net->ipv4.sysctl_tcp_plb_rehash_rounds = 12;
 | 
						|
+	net->ipv4.sysctl_tcp_plb_suspend_rto_sec = 60;
 | 
						|
+
 | 
						|
 	/* Reno is always built in */
 | 
						|
 	if (!net_eq(net, &init_net) &&
 | 
						|
 	    bpf_try_module_get(init_net.ipv4.tcp_congestion_control,
 | 
						|
diff --git a/net/ipv4/tcp_plb.c b/net/ipv4/tcp_plb.c
 | 
						|
new file mode 100644
 | 
						|
index 000000000000..71b02c0404ce
 | 
						|
--- /dev/null
 | 
						|
+++ b/net/ipv4/tcp_plb.c
 | 
						|
@@ -0,0 +1,100 @@
 | 
						|
+/* Protective Load Balancing (PLB)
 | 
						|
+ *
 | 
						|
+ * PLB was designed to reduce link load imbalance across datacenter
 | 
						|
+ * switches. PLB is a host-based optimization; it leverages congestion
 | 
						|
+ * signals from the transport layer to randomly change the path of the
 | 
						|
+ * connection experiencing sustained congestion. PLB prefers to repath
 | 
						|
+ * after idle periods to minimize packet reordering. It repaths by
 | 
						|
+ * changing the IPv6 Flow Label on the packets of a connection, which
 | 
						|
+ * datacenter switches include as part of ECMP/WCMP hashing.
 | 
						|
+ *
 | 
						|
+ * PLB is described in detail in:
 | 
						|
+ *
 | 
						|
+ *	Mubashir Adnan Qureshi, Yuchung Cheng, Qianwen Yin, Qiaobin Fu,
 | 
						|
+ *	Gautam Kumar, Masoud Moshref, Junhua Yan, Van Jacobson,
 | 
						|
+ *	David Wetherall,Abdul Kabbani:
 | 
						|
+ *	"PLB: Congestion Signals are Simple and Effective for
 | 
						|
+ *	 Network Load Balancing"
 | 
						|
+ *	In ACM SIGCOMM 2022, Amsterdam Netherlands.
 | 
						|
+ *
 | 
						|
+ */
 | 
						|
+
 | 
						|
+#include <net/tcp.h>
 | 
						|
+
 | 
						|
+/* Called once per round-trip to update PLB state for a connection. */
 | 
						|
+void tcp_plb_update_state(const struct sock *sk, struct tcp_plb_state *plb,
 | 
						|
+			  const int cong_ratio)
 | 
						|
+{
 | 
						|
+	struct net *net = sock_net(sk);
 | 
						|
+
 | 
						|
+	if (!plb->enabled)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	if (cong_ratio >= 0) {
 | 
						|
+		if (cong_ratio < net->ipv4.sysctl_tcp_plb_cong_thresh)
 | 
						|
+			plb->consec_cong_rounds = 0;
 | 
						|
+		else if (plb->consec_cong_rounds <
 | 
						|
+			 net->ipv4.sysctl_tcp_plb_rehash_rounds)
 | 
						|
+			plb->consec_cong_rounds++;
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+EXPORT_SYMBOL_GPL(tcp_plb_update_state);
 | 
						|
+
 | 
						|
+/* Check whether recent congestion has been persistent enough to warrant
 | 
						|
+ * a load balancing decision that switches the connection to another path.
 | 
						|
+ */
 | 
						|
+void tcp_plb_check_rehash(struct sock *sk, struct tcp_plb_state *plb)
 | 
						|
+{
 | 
						|
+	struct net *net = sock_net(sk);
 | 
						|
+	bool can_idle_rehash, can_force_rehash;
 | 
						|
+
 | 
						|
+	if (!plb->enabled)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	/* Note that tcp_jiffies32 can wrap, so we clear pause_until
 | 
						|
+	 * to 0 to indicate there is no recent RTO event that constrains
 | 
						|
+	 * PLB rehashing.
 | 
						|
+	 */
 | 
						|
+	if (plb->pause_until &&
 | 
						|
+	    !before(tcp_jiffies32, plb->pause_until))
 | 
						|
+		plb->pause_until = 0;
 | 
						|
+
 | 
						|
+	can_idle_rehash = net->ipv4.sysctl_tcp_plb_idle_rehash_rounds &&
 | 
						|
+			  !tcp_sk(sk)->packets_out &&
 | 
						|
+			  plb->consec_cong_rounds >=
 | 
						|
+			  net->ipv4.sysctl_tcp_plb_idle_rehash_rounds;
 | 
						|
+	can_force_rehash = plb->consec_cong_rounds >=
 | 
						|
+			   net->ipv4.sysctl_tcp_plb_rehash_rounds;
 | 
						|
+
 | 
						|
+	if (!plb->pause_until && (can_idle_rehash || can_force_rehash)) {
 | 
						|
+		sk_rethink_txhash(sk);
 | 
						|
+		plb->consec_cong_rounds = 0;
 | 
						|
+		tcp_sk(sk)->ecn_rehash++;
 | 
						|
+		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPECNREHASH);
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+EXPORT_SYMBOL_GPL(tcp_plb_check_rehash);
 | 
						|
+
 | 
						|
+/* Upon RTO, disallow load balancing for a while, to avoid having load
 | 
						|
+ * balancing decisions switch traffic to a black-holed path that was
 | 
						|
+ * previously avoided with a sk_rethink_txhash() call at RTO time.
 | 
						|
+ */
 | 
						|
+void tcp_plb_update_state_upon_rto(struct sock *sk, struct tcp_plb_state *plb)
 | 
						|
+{
 | 
						|
+	struct net *net = sock_net(sk);
 | 
						|
+	u32 pause;
 | 
						|
+
 | 
						|
+	if (!plb->enabled)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	pause = net->ipv4.sysctl_tcp_plb_suspend_rto_sec * HZ;
 | 
						|
+	pause += prandom_u32_max(pause);
 | 
						|
+	plb->pause_until = tcp_jiffies32 + pause;
 | 
						|
+
 | 
						|
+	/* Reset PLB state upon RTO, since an RTO causes a sk_rethink_txhash() call
 | 
						|
+	 * that may switch this connection to a path with completely different
 | 
						|
+	 * congestion characteristics.
 | 
						|
+	 */
 | 
						|
+	plb->consec_cong_rounds = 0;
 | 
						|
+}
 | 
						|
+EXPORT_SYMBOL_GPL(tcp_plb_update_state_upon_rto);
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 | 
						|
From bba01f8fcecc39dd89274d977508dd50ba620f65 Mon Sep 17 00:00:00 2001
 | 
						|
From: Mubashir Adnan Qureshi <mubashirq@google.com>
 | 
						|
Date: Thu, 21 Jul 2022 19:03:30 +0000
 | 
						|
Subject: [PATCH 27/27] net-test: tcp: plb: Add PLB tests
 | 
						|
 | 
						|
Add tests to check the following operations of PLB
 | 
						|
 | 
						|
1. Forced rehashing
 | 
						|
2. Idle rehashing when no packets in flight
 | 
						|
3. PLB state reset upon RTO
 | 
						|
 | 
						|
Change-Id: If74c7fb0107c8f9a4f740dcb2e488c73dd6cc08d
 | 
						|
---
 | 
						|
 .../net/tcp/plb/bbr2-ecn-plb-idle-rehash.pkt  |  59 +++++++
 | 
						|
 gtests/net/tcp/plb/bbr2-ecn-plb-rehash.pkt    | 146 ++++++++++++++++++
 | 
						|
 .../tcp/plb/bbr2-ecn-plb-rto-suspend-off.pkt  |  71 +++++++++
 | 
						|
 3 files changed, 276 insertions(+)
 | 
						|
 create mode 100644 gtests/net/tcp/plb/bbr2-ecn-plb-idle-rehash.pkt
 | 
						|
 create mode 100644 gtests/net/tcp/plb/bbr2-ecn-plb-rehash.pkt
 | 
						|
 create mode 100644 gtests/net/tcp/plb/bbr2-ecn-plb-rto-suspend-off.pkt
 | 
						|
 | 
						|
diff --git a/gtests/net/tcp/plb/bbr2-ecn-plb-idle-rehash.pkt b/gtests/net/tcp/plb/bbr2-ecn-plb-idle-rehash.pkt
 | 
						|
new file mode 100644
 | 
						|
index 000000000000..706fbf72a66c
 | 
						|
--- /dev/null
 | 
						|
+++ b/gtests/net/tcp/plb/bbr2-ecn-plb-idle-rehash.pkt
 | 
						|
@@ -0,0 +1,59 @@
 | 
						|
+// Verify BBR v2 changes flowlabel in ipv6 header when there are
 | 
						|
+// net.ipv4.tcp_plb_idle_rehash_rounds=3 consecutive rounds with the ECN mark rate >=
 | 
						|
+// net.ipv4.tcp_plb_cong_thresh=64(25%) and there are no packets in flight.
 | 
						|
+
 | 
						|
+`../common/defaults.sh
 | 
						|
+sysctl -q net.ipv4.tcp_ecn=1  # fully enabled
 | 
						|
+sysctl -q net.ipv4.tcp_congestion_control=bbr2
 | 
						|
+sysctl -q net.ipv4.tcp_plb_enabled=1
 | 
						|
+sysctl -q net.ipv4.tcp_plb_cong_thresh=64
 | 
						|
+sysctl -q net.ipv4.tcp_plb_idle_rehash_rounds=3
 | 
						|
+sysctl -q net.ipv4.tcp_plb_rehash_rounds=12
 | 
						|
+echo 1 > /sys/module/tcp_bbr2/parameters/ecn_enable
 | 
						|
+echo 0 > /sys/module/tcp_bbr2/parameters/ecn_max_rtt_us
 | 
						|
+`
 | 
						|
+
 | 
						|
+// Initialize connection
 | 
						|
+    0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
 | 
						|
+   +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
 | 
						|
+   +0 bind(3, ..., ...) = 0
 | 
						|
+   +0 listen(3, 1) = 0
 | 
						|
+
 | 
						|
+   +0 < SEW 0:0(0) ack 1 win 32792 <mss 1012,sackOK,TS val 200 ecr 0,nop,wscale 7>
 | 
						|
+   +0 > (flowlabel 0x1) SE. 0:0(0) ack 1 <mss 1460,sackOK,TS val 100 ecr 200,nop,wscale 8>
 | 
						|
+   +0 < . 1:1(0) ack 1 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 accept(3, ..., ...) = 4
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) P. 1:10001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < . 1:1(0) ack 10001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// no ECN mark, flowlabel won't change.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) P. 10001:20001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 17001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 20001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 1 congested round
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 20001:30001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 27001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 30001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 2 consecutive congested rounds
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 30001:40001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 37001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 40001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 3 consecutive congested round
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 40001:41001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 41001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// This ACK started a new round. PLB observes that past three rounds were
 | 
						|
+// congested and no packets are in flight so it changes the flowlabel.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+// As expected, packets of idle write carry new flow label
 | 
						|
+   +0 > (flowlabel 0x2) P. 41001:51001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 51001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
diff --git a/gtests/net/tcp/plb/bbr2-ecn-plb-rehash.pkt b/gtests/net/tcp/plb/bbr2-ecn-plb-rehash.pkt
 | 
						|
new file mode 100644
 | 
						|
index 000000000000..af500ef08768
 | 
						|
--- /dev/null
 | 
						|
+++ b/gtests/net/tcp/plb/bbr2-ecn-plb-rehash.pkt
 | 
						|
@@ -0,0 +1,146 @@
 | 
						|
+// Verify BBR v2 changes flowlabel in ipv6 header if and only if there are
 | 
						|
+// net.ipv4.tcp_plb_rehash_rounds=3 consecutive rounds with the ECN mark rate >=
 | 
						|
+// net.ipv4.tcp_plb_cong_thresh=64(25%).
 | 
						|
+
 | 
						|
+`../common/defaults.sh
 | 
						|
+sysctl -q net.ipv4.tcp_ecn=1  # fully enabled
 | 
						|
+sysctl -q net.ipv4.tcp_congestion_control=bbr2
 | 
						|
+sysctl -q net.ipv4.tcp_plb_enabled=1
 | 
						|
+sysctl -q net.ipv4.tcp_plb_cong_thresh=64
 | 
						|
+sysctl -q net.ipv4.tcp_plb_idle_rehash_rounds=0
 | 
						|
+sysctl -q net.ipv4.tcp_plb_rehash_rounds=3
 | 
						|
+echo 1 > /sys/module/tcp_bbr2/parameters/ecn_enable
 | 
						|
+echo 0 > /sys/module/tcp_bbr2/parameters/ecn_max_rtt_us
 | 
						|
+`
 | 
						|
+
 | 
						|
+// Initialize connection
 | 
						|
+    0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
 | 
						|
+   +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
 | 
						|
+   +0 bind(3, ..., ...) = 0
 | 
						|
+   +0 listen(3, 1) = 0
 | 
						|
+
 | 
						|
+   +0 < SEW 0:0(0) ack 1 win 32792 <mss 1012,sackOK,TS val 200 ecr 0,nop,wscale 7>
 | 
						|
+   +0 > (flowlabel 0x1) SE. 0:0(0) ack 1 <mss 1460,sackOK,TS val 100 ecr 200,nop,wscale 8>
 | 
						|
+   +0 < . 1:1(0) ack 1 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 accept(3, ..., ...) = 4
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) P. 1:10001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < . 1:1(0) ack 10001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// no ECN mark, flowlabel won't change.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) P. 10001:20001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 19001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 20001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 1/10 packets ECN-marked. Not enough.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 20001:30001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 28001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 30001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 2/10 packets ECN-marked. Not enough.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 30001:40001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 37001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 40001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, but only 1 round.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 40001:41001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 41001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// no ECN mark, flowlabel won't change.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) P. 41001:51001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 48001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 51001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, but only 1 round.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 51001:61001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 58001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 61001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 2 consecutive rounds.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 61001:62001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 62001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// no ECN mark, flowlabel won't change.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) P. 62001:72001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 69001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 72001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, but only 1 round.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 72001:82001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 79001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 82001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 2 consecutive rounds.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 82001:83001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 83001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// no ECN mark, flowlabel won't change.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) P. 83001:93001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 90001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 93001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, but only 1 round.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 93001:103001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 100001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 103001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 2 consecutive rounds.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 103001:113001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 110001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 113001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 3 consecutive rounds.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+// Since a new round haven't started, flowlabel is not updated.
 | 
						|
+   +0 > (flowlabel 0x1) PW. 113001:123001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 120001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 123001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 1 consecutive rounds.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+// Verify the new flowlabel
 | 
						|
+   +0 > (flowlabel 0x2) PW. 123001:133001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 130001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 133001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 2 consecutive rounds.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 10000) = 10000
 | 
						|
+   +0 > (flowlabel 0x2) PW. 133001:143001(10000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 140001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 < E. 1:1(0) ack 143001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// 3/10 packets ECN-marked, >25%, 3 consecutive rounds. flowlabel will change in a new round.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+// Since a new round haven't started, flowlabel is not updated.
 | 
						|
+   +0 > (flowlabel 0x2) PW. 143001:144001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 144001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// A new round starts after the ack above, new flowlabel assigned from here.
 | 
						|
+
 | 
						|
+// Verify the new flowlabel
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x3) P. 144001:145001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 145001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+
 | 
						|
+// Verify the new flowlabel sticks and does't change again
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x3) P. 145001:146001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 146001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+
 | 
						|
+// Verify the new flowlabel sticks and does't change again
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x3) P. 146001:147001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 147001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
diff --git a/gtests/net/tcp/plb/bbr2-ecn-plb-rto-suspend-off.pkt b/gtests/net/tcp/plb/bbr2-ecn-plb-rto-suspend-off.pkt
 | 
						|
new file mode 100644
 | 
						|
index 000000000000..d46e759e57e5
 | 
						|
--- /dev/null
 | 
						|
+++ b/gtests/net/tcp/plb/bbr2-ecn-plb-rto-suspend-off.pkt
 | 
						|
@@ -0,0 +1,71 @@
 | 
						|
+// Verify BBR v2 changes flowlabel in ipv6 header when there are
 | 
						|
+// net.ipv4.tcp_plb_idle_rehash_rounds=3 consecutive rounds with
 | 
						|
+// the ECN mark rate >= net.ipv4.tcp_plb_cong_thresh=64(25%) after
 | 
						|
+// an RTO resets PLB state. This test confirms that PLB state is reset
 | 
						|
+// after an RTO. TLP is disabled for this test.
 | 
						|
+
 | 
						|
+`../common/defaults.sh
 | 
						|
+sysctl -q net.ipv4.tcp_ecn=1  # fully enabled
 | 
						|
+sysctl -q net.ipv4.tcp_congestion_control=bbr2
 | 
						|
+sysctl -q net.ipv4.tcp_plb_enabled=1
 | 
						|
+sysctl -q net.ipv4.tcp_plb_cong_thresh=64
 | 
						|
+sysctl -q net.ipv4.tcp_plb_idle_rehash_rounds=0
 | 
						|
+sysctl -q net.ipv4.tcp_plb_rehash_rounds=3
 | 
						|
+sysctl -q net.ipv4.tcp_plb_suspend_rto_sec=0
 | 
						|
+sysctl -q net.ipv4.tcp_early_retrans=0
 | 
						|
+sysctl -q net.ipv4.tcp_recovery=0
 | 
						|
+echo 1 > /sys/module/tcp_bbr2/parameters/ecn_enable
 | 
						|
+echo 0 > /sys/module/tcp_bbr2/parameters/ecn_max_rtt_us
 | 
						|
+`
 | 
						|
+
 | 
						|
+// Initialize connection
 | 
						|
+    0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
 | 
						|
+   +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
 | 
						|
+   +0 bind(3, ..., ...) = 0
 | 
						|
+   +0 listen(3, 1) = 0
 | 
						|
+
 | 
						|
+   +0 < SEW 0:0(0) ack 1 win 32792 <mss 1012,sackOK,TS val 200 ecr 0,nop,wscale 7>
 | 
						|
+   +0 > (flowlabel 0x1) SE. 0:0(0) ack 1 <mss 1460,sackOK,TS val 100 ecr 200,nop,wscale 8>
 | 
						|
+   +0 < . 1:1(0) ack 1 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+   +0 accept(3, ..., ...) = 4
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x1) P. 1:1001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < E. 1:1(0) ack 1001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// ECN mark, 1 congested round
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 1001:2001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < E.  1:1(0) ack 2001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// ECN mark, 2 consecutive congested rounds.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x1) PW. 2001:3001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+// Flowlabel should be changed after kernel retransmit
 | 
						|
++.2~+.22  > (flowlabel 0x2) P. 2001:3001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < E. 1:1(0) ack 3001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// PLB state should reset, 1 congested round
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x2) PW. 3001:4001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < E.  1:1(0) ack 4001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// ECN mark, 2 consecutive congested rounds.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x2) PW. 4001:5001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < E.  1:1(0) ack 5001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+// ECN mark, 3 consecutive congested rounds. Flowlabel should change in next round.
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+   +0 > (flowlabel 0x3) PW. 5001:6001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 6001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+// Verify new flow label
 | 
						|
+   +0 > (flowlabel 0x3) P. 6001:7001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 7001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
+
 | 
						|
+   +0 write(4, ..., 1000) = 1000
 | 
						|
+// Verify new flow label sticks
 | 
						|
+   +0 > (flowlabel 0x3) P. 7001:8001(1000) ack 1 <nop,nop,TS val 100 ecr 200>
 | 
						|
+   +0 < .  1:1(0) ack 8001 win 1000 <nop,nop,TS val 200 ecr 100>
 | 
						|
-- 
 | 
						|
2.34.1
 | 
						|
 |