diff --git a/6.1/target/linux/generic/config-6.1 b/6.1/target/linux/generic/config-6.1 index 0bd3774c..8122569f 100644 --- a/6.1/target/linux/generic/config-6.1 +++ b/6.1/target/linux/generic/config-6.1 @@ -1461,6 +1461,8 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_ZBOOT is not set # CONFIG_DECNET is not set # CONFIG_DEFAULT_CODEL is not set +# CONFIG_DEFAULT_BBR is not set +# CONFIG_DEFAULT_BBR2 is not set CONFIG_DEFAULT_CUBIC=y CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_FQ is not set @@ -4435,6 +4437,7 @@ CONFIG_NET_VENDOR_XIRCOM=y # CONFIG_NET_VRF is not set # CONFIG_NET_XGENE is not set CONFIG_NEW_LEDS=y +CONFIG_NF_CONNTRACK_CUSTOM=4 # CONFIG_NFC is not set # CONFIG_NFP is not set # CONFIG_NFSD is not set @@ -6712,22 +6715,23 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TCG_XEN is not set # CONFIG_TCIC is not set CONFIG_TCP_CONG_ADVANCED=y -# CONFIG_TCP_CONG_BBR is not set -# CONFIG_TCP_CONG_BIC is not set -# CONFIG_TCP_CONG_CDG is not set +CONFIG_TCP_CONG_BBR=y +CONFIG_TCP_CONG_BBR2=y +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CDG=y CONFIG_TCP_CONG_CUBIC=y -# CONFIG_TCP_CONG_DCTCP is not set -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_ILLINOIS is not set -# CONFIG_TCP_CONG_LP is not set -# CONFIG_TCP_CONG_NV is not set -# CONFIG_TCP_CONG_SCALABLE is not set -# CONFIG_TCP_CONG_VEGAS is not set -# CONFIG_TCP_CONG_VENO is not set -# CONFIG_TCP_CONG_WESTWOOD is not set -# CONFIG_TCP_CONG_YEAH is not set +CONFIG_TCP_CONG_DCTCP=y +CONFIG_TCP_CONG_HSTCP=y +CONFIG_TCP_CONG_HTCP=y +CONFIG_TCP_CONG_HYBLA=y +CONFIG_TCP_CONG_ILLINOIS=y +CONFIG_TCP_CONG_LP=y +CONFIG_TCP_CONG_NV=y +CONFIG_TCP_CONG_SCALABLE=y +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_VENO=y +CONFIG_TCP_CONG_WESTWOOD=y +CONFIG_TCP_CONG_YEAH=y # CONFIG_TCP_MD5SIG is not set # CONFIG_TCS3414 is not set # CONFIG_TCS3472 is not set diff --git a/6.1/target/linux/generic/hack-6.1/999-BBRv2.patch b/6.1/target/linux/generic/hack-6.1/999-BBRv2.patch new file mode 100644 index 00000000..343e0e79 --- /dev/null +++ b/6.1/target/linux/generic/hack-6.1/999-BBRv2.patch @@ -0,0 +1,10575 @@ +From 092758f89a20d9d2f00ce022152ed447ee1b0380 Mon Sep 17 00:00:00 2001 +From: Neal Cardwell +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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; ++ u64 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 +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 +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,2683 @@ ++/* 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 ++#include ++#include ++#include ++#include ++ ++#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) ++{ ++ 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' */ ++ }; ++ 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; ++ ++ 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"); ++ 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; ++ u64 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 "); ++MODULE_AUTHOR("Neal Cardwell "); ++MODULE_AUTHOR("Yuchung Cheng "); ++MODULE_AUTHOR("Soheil Hassas Yeganeh "); ++MODULE_AUTHOR("Priyaranjan Jha "); ++MODULE_AUTHOR("Yousuk Seung "); ++MODULE_AUTHOR("Kevin Yang "); ++MODULE_AUTHOR("Arjun Roy "); ++ ++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 +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 +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 + +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="" ++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 +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 "$TITLE $TITLE
\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 "\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 "\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 "\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 "\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 "\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 "\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: