| 1 | /*- |
| 2 | * Copyright (c) 2016-2020 Netflix, Inc. |
| 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions |
| 6 | * are met: |
| 7 | * 1. Redistributions of source code must retain the above copyright |
| 8 | * notice, this list of conditions and the following disclaimer. |
| 9 | * 2. Redistributions in binary form must reproduce the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer in the |
| 11 | * documentation and/or other materials provided with the distribution. |
| 12 | * |
| 13 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 16 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| 17 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 19 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 20 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 23 | * SUCH DAMAGE. |
| 24 | */ |
| 25 | |
| 26 | #ifndef _NETINET_TCP_BBR_H_ |
| 27 | #define _NETINET_TCP_BBR_H_ |
| 28 | |
| 29 | #define BBR_INITIAL_RTO 1000000	/* 1 second in micro-seconds */ |
| 30 | /* Send map flags */ |
| 31 | #define BBR_ACKED	 0x0001	/* The remote endpoint acked this */ |
| 32 | #define BBR_WAS_RENEGED	 0x0002	/* The peer reneged the ack */ |
| 33 | #define BBR_RXT_CLEARED	 0x0004	/* ACK Cleared by the RXT timer */ |
| 34 | #define BBR_OVERMAX	 0x0008	/* We have more retran's then we can |
| 35 | 					 * fit */ |
| 36 | #define BBR_SACK_PASSED 0x0010	/* A sack was done above this block */ |
| 37 | #define BBR_WAS_SACKPASS 0x0020	/* We retransmitted due to SACK pass */ |
| 38 | #define BBR_HAS_FIN	 0x0040	/* segment is sent with fin */ |
| 39 | #define BBR_TLP	 	 0x0080	/* segment sent as tail-loss-probe */ |
| 40 | #define BBR_HAS_SYN	 0x0100	/* segment has the syn */ |
| 41 | #define BBR_MARKED_LOST 0x0200	/* |
| 42 | 					 * This segments is lost and |
| 43 | 					 * totaled into bbr->rc_ctl.rc_lost |
| 44 | 					 */ |
| 45 | #define BBR_RWND_COLLAPSED 0x0400	/* The peer collapsed the rwnd on the segment */ |
| 46 | #define BBR_NUM_OF_RETRANS 7 |
| 47 | |
| 48 | /* Defines for socket options to set pacing overheads */ |
| 49 | #define BBR_INCL_ENET_OH 0x01 |
| 50 | #define BBR_INCL_IP_OH 0x02 |
| 51 | #define BBR_INCL_TCP_OH 0x03 |
| 52 | |
| 53 | /* |
| 54 | * With the addition of both measurement algorithms |
| 55 | * I had to move over the size of a |
| 56 | * cache line (unfortunately). For now there is |
| 57 | * no way around this. We may be able to cut back |
| 58 | * at some point I hope. |
| 59 | */ |
| 60 | struct bbr_sendmap { |
| 61 | 	TAILQ_ENTRY(bbr_sendmap) r_next;	/* seq number arrayed next */ |
| 62 | 	TAILQ_ENTRY(bbr_sendmap) r_tnext;	/* Time of tmit based next */ |
| 63 | 	uint32_t r_start;	/* Sequence number of the segment */ |
| 64 | 	uint32_t r_end;		/* End seq, this is 1 beyond actually */ |
| 65 | |
| 66 | 	uint32_t r_rtr_bytes;	/* How many bytes have been retransmitted */ |
| 67 | 	uint32_t r_delivered;	/* Delivered amount at send */ |
| 68 | |
| 69 | 	uint32_t r_del_time;	/* The time of the last delivery update */ |
| 70 | 	uint8_t r_rtr_cnt:4,	/* Retran count, index this -1 to get time |
| 71 | 				 * sent */ |
| 72 | 		r_rtt_not_allowed:1,	/* No rtt measurement allowed */ |
| 73 | 	 r_is_drain:1,	/* In a draining cycle */ |
| 74 | 		r_app_limited:1,/* We went app limited */ |
| 75 | 	 r_ts_valid:1;	/* Timestamp field is valid (r_del_ack_ts) */ |
| 76 | 	uint8_t r_dupack;	/* Dup ack count */ |
| 77 | 	uint8_t r_in_tmap:1,	/* Flag to see if its in the r_tnext array */ |
| 78 | 	 r_is_smallmap:1,/* Was logged as a small-map send-map item */ |
| 79 | 		r_is_gain:1,	/* Was in gain cycle */ |
| 80 | 		r_bbr_state:5; /* The BBR state at send */ |
| 81 | 	uint8_t r_limit_type;	/* is this entry counted against a limit? */ |
| 82 | |
| 83 | 	uint16_t r_flags;	/* Flags as defined above */ |
| 84 | 	uint16_t r_spare16; |
| 85 | 	uint32_t r_del_ack_ts; /* At send what timestamp of peer was (if r_ts_valid set) */ |
| 86 | 	/****************Cache line*****************/ |
| 87 | 	uint32_t r_tim_lastsent[BBR_NUM_OF_RETRANS]; |
| 88 | 	/* |
| 89 | 	 * Question, should we instead just grab the sending b/w |
| 90 | 	 * from the filter with the gain and store it in a |
| 91 | 	 * uint64_t instead? |
| 92 | 	 */ |
| 93 | 	uint32_t r_first_sent_time; /* Time of first pkt in flight sent */ |
| 94 | 	uint32_t r_pacing_delay;	/* pacing delay of this send */ |
| 95 | 	uint32_t r_flight_at_send;	/* flight at the time of the send */ |
| 96 | #ifdef _KERNEL |
| 97 | } __aligned(CACHE_LINE_SIZE); |
| 98 | #else |
| 99 | }; |
| 100 | #endif |
| 101 | #define BBR_LIMIT_TYPE_SPLIT	1 |
| 102 | |
| 103 | TAILQ_HEAD(bbr_head, bbr_sendmap); |
| 104 | |
| 105 | #define BBR_SEGMENT_TIME_SIZE 1500	/* How many bytes in time_between */ |
| 106 | |
| 107 | #define BBR_MIN_SEG 1460		/* MSS size */ |
| 108 | #define BBR_MAX_GAIN_VALUE 0xffff |
| 109 | |
| 110 | #define BBR_TIMER_FUDGE 1500	/* 1.5ms in micro seconds */ |
| 111 | |
| 112 | /* BW twiddle secret codes */ |
| 113 | #define BBR_RED_BW_CONGSIG 	 0	/* We enter recovery and set using b/w */ |
| 114 | #define BBR_RED_BW_RATECAL 	 1	/* We are calculating the loss rate */ |
| 115 | #define BBR_RED_BW_USELRBW 2	/* We are dropping the lower b/w with |
| 116 | 					 * cDR */ |
| 117 | #define BBR_RED_BW_SETHIGHLOSS	 3	/* We have set our highloss value at |
| 118 | 					 * exit from probe-rtt */ |
| 119 | #define BBR_RED_BW_PE_CLREARLY	 4	/* We have decided to clear the |
| 120 | 					 * reduction early */ |
| 121 | #define BBR_RED_BW_PE_CLAFDEL	 5	/* We are clearing it on schedule |
| 122 | 					 * delayed */ |
| 123 | #define BBR_RED_BW_REC_ENDCLL	 6	/* Recover exits save high if needed |
| 124 | 					 * an clear to start measuring */ |
| 125 | #define BBR_RED_BW_PE_NOEARLY_OUT 7	/* Set pkt epoch judged that we do not |
| 126 | 					 * get out of jail early */ |
| 127 | /* For calculating a rate */ |
| 128 | #define BBR_CALC_BW 	1 |
| 129 | #define BBR_CALC_LOSS 	2 |
| 130 | |
| 131 | #define BBR_RTT_BY_TIMESTAMP	0 |
| 132 | #define BBR_RTT_BY_EXACTMATCH	1 |
| 133 | #define BBR_RTT_BY_EARLIER_RET	2 |
| 134 | #define BBR_RTT_BY_THIS_RETRAN 3 |
| 135 | #define BBR_RTT_BY_SOME_RETRAN	4 |
| 136 | #define BBR_RTT_BY_TSMATCHING	5 |
| 137 | |
| 138 | /* Markers to track where we enter persists from */ |
| 139 | #define BBR_PERSISTS_FROM_1	1 |
| 140 | #define BBR_PERSISTS_FROM_2	2 |
| 141 | #define BBR_PERSISTS_FROM_3	3 |
| 142 | #define BBR_PERSISTS_FROM_4	4 |
| 143 | #define BBR_PERSISTS_FROM_5	5 |
| 144 | |
| 145 | /* magic cookies to ask for the RTT */ |
| 146 | #define BBR_RTT_PROP 0 |
| 147 | #define BBR_RTT_RACK 1 |
| 148 | #define BBR_RTT_PKTRTT 2 |
| 149 | #define BBR_SRTT	3 |
| 150 | |
| 151 | #define BBR_SACKED 0 |
| 152 | #define BBR_CUM_ACKED 1 |
| 153 | |
| 154 | /* threshold in useconds where we consider we need a higher min cwnd */ |
| 155 | #define BBR_HIGH_SPEED 1000 |
| 156 | #define BBR_HIGHSPEED_NUM_MSS 12 |
| 157 | |
| 158 | #define MAX_REDUCE_RXT 3	/* What is the maximum times we are willing to |
| 159 | 				 * reduce b/w in RTX's. Setting this has a |
| 160 | 				 * multiplicative effect e.g. if we are |
| 161 | 				 * reducing by 20% then setting it to 3 means |
| 162 | 				 * you will have reduced the b/w estimate by > |
| 163 | 				 * 60% before you stop. */ |
| 164 | /* |
| 165 | * We use the rate sample structure to |
| 166 | * assist in single sack/ack rate and rtt |
| 167 | * calculation. In the future we will expand |
| 168 | * this in BBR to do forward rate sample |
| 169 | * b/w estimation. |
| 170 | */ |
| 171 | #define BBR_RS_RTT_EMPTY 0x00000001	/* Nothing yet stored in RTT's */ |
| 172 | #define BBR_RS_BW_EMPTY 0x00000002	/* Nothing yet stored in cDR */ |
| 173 | #define BBR_RS_RTT_VALID 0x00000004	/* We have at least one valid RTT */ |
| 174 | #define BBR_RS_BW_VAILD 0x00000008	/* We have a valid cDR */ |
| 175 | #define BBR_RS_EMPTY (BBR_RS_RTT_EMPTY|BBR_RS_BW_EMPTY) |
| 176 | struct bbr_rtt_sample { |
| 177 | 	uint32_t rs_flags; |
| 178 | 	uint32_t rs_rtt_lowest; |
| 179 | 	uint32_t rs_rtt_lowest_sendtime; |
| 180 | 	uint32_t rs_rtt_low_seq_start; |
| 181 | |
| 182 | 	uint32_t rs_rtt_highest; |
| 183 | 	uint32_t rs_rtt_cnt; |
| 184 | |
| 185 | 	uint64_t rs_rtt_tot; |
| 186 | 	uint32_t cur_rtt; |
| 187 | 	uint32_t cur_rtt_bytecnt; |
| 188 | |
| 189 | 	uint32_t cur_rtt_rsmcnt; |
| 190 | 	uint32_t rc_crtt_set:1, |
| 191 | 		avail_bits:31; |
| 192 | 	uint64_t rs_cDR; |
| 193 | }; |
| 194 | |
| 195 | /* RTT shrink reasons */ |
| 196 | #define BBR_RTTS_INIT 0 |
| 197 | #define BBR_RTTS_NEWRTT 1 |
| 198 | #define BBR_RTTS_RTTPROBE 2 |
| 199 | #define BBR_RTTS_WASIDLE 3 |
| 200 | #define BBR_RTTS_PERSIST 4 |
| 201 | #define BBR_RTTS_REACHTAR 5 |
| 202 | #define BBR_RTTS_ENTERPROBE 6 |
| 203 | #define BBR_RTTS_SHRINK_PG 7 |
| 204 | #define BBR_RTTS_SHRINK_PG_FINAL 8 |
| 205 | #define BBR_RTTS_NEW_TARGET 9 |
| 206 | #define BBR_RTTS_LEAVE_DRAIN 10 |
| 207 | #define BBR_RTTS_RESETS_VALUES 11 |
| 208 | |
| 209 | #define BBR_NUM_RATES 5 |
| 210 | /* Rate flags */ |
| 211 | #define BBR_RT_FLAG_FREE 0x00	/* Is on the free list */ |
| 212 | #define BBR_RT_FLAG_INUSE 0x01	/* Has been allocated */ |
| 213 | #define BBR_RT_FLAG_READY 0x02	/* Ready to initiate a measurement. */ |
| 214 | #define BBR_RT_FLAG_CAPPED_PRE 0x04	/* Ready to cap if we send the next segment */ |
| 215 | #define BBR_RT_FLAG_CAPPED 0x08	/* Measurement is capped */ |
| 216 | #define BBR_RT_FLAG_PASTFA 0x10	/* Past the first ack. */ |
| 217 | #define BBR_RT_FLAG_LIMITED 0x20	/* Saw application/cwnd or rwnd limited period */ |
| 218 | #define BBR_RT_SEEN_A_ACK 0x40	/* A ack has been saved */ |
| 219 | #define BBR_RT_PREV_RTT_SET 0x80	/* There was a RTT set in */ |
| 220 | #define BBR_RT_PREV_SEND_TIME 0x100	/* |
| 221 | 					 *There was a RTT send time set that can be used |
| 222 | 					 * no snd_limits |
| 223 | 					 */ |
| 224 | #define BBR_RT_SET_GRADIENT 0x200 |
| 225 | #define BBR_RT_TS_VALID 0x400 |
| 226 | |
| 227 | struct bbr_log { |
| 228 | 	union { |
| 229 | 		struct bbr_sendmap *rsm;	/* For alloc/free */ |
| 230 | 		uint64_t sb_acc;	/* For out/ack or t-o */ |
| 231 | 	}; |
| 232 | 	struct tcpcb *tp; |
| 233 | 	uint32_t t_flags; |
| 234 | 	uint32_t th_seq; |
| 235 | 	uint32_t th_ack; |
| 236 | 	uint32_t snd_una; |
| 237 | 	uint32_t snd_nxt; |
| 238 | 	uint32_t snd_max; |
| 239 | 	uint32_t snd_cwnd; |
| 240 | 	uint32_t snd_wnd; |
| 241 | 	uint32_t rc_lost; |
| 242 | 	uint32_t target_cwnd;	/* UU */ |
| 243 | 	uint32_t inflight;	/* UU */ |
| 244 | 	uint32_t applimited;	/* UU */ |
| 245 | 	/* Things for BBR */ |
| 246 | 	uint32_t delivered;	/* UU */ |
| 247 | 	uint64_t cur_del_rate;	/* UU */ |
| 248 | 	uint64_t delRate;	/* UU */ |
| 249 | 	uint64_t rttProp;	/* UU */ |
| 250 | 	uint64_t lt_bw;		/* UU */ |
| 251 | 	uint32_t timeStamp; |
| 252 | 	uint32_t time; |
| 253 | 	uint32_t slot;		/* UU */ |
| 254 | 	uint32_t delayed_by; |
| 255 | 	uint32_t exp_del; |
| 256 | 	uint32_t pkts_out; |
| 257 | 	uint32_t new_win; |
| 258 | 	uint32_t hptsi_gain;	/* UU */ |
| 259 | 	uint32_t cwnd_gain;	/* UU */ |
| 260 | 	uint32_t epoch;		/* UU */ |
| 261 | 	uint32_t lt_epoch;	/* UU */ |
| 262 | 	/* Sack fun */ |
| 263 | 	uint32_t blk_start[4];	/* xx */ |
| 264 | 	uint32_t blk_end[4]; |
| 265 | 	uint32_t len;		/* Timeout T3=1, TLP=2, RACK=3 */ |
| 266 | 	uint8_t type; |
| 267 | 	uint8_t n_sackblks; |
| 268 | 	uint8_t applied;	/* UU */ |
| 269 | 	uint8_t inhpts;		/* UU */ |
| 270 | 	uint8_t __spare;	/* UU */ |
| 271 | 	uint8_t use_lt_bw;	/* UU */ |
| 272 | }; |
| 273 | |
| 274 | struct bbr_log_sysctl_out { |
| 275 | 	uint32_t bbr_log_at; |
| 276 | 	uint32_t bbr_log_max; |
| 277 | 	struct bbr_log entries[0]; |
| 278 | }; |
| 279 | |
| 280 | /* |
| 281 | * Magic numbers for logging timeout events if the |
| 282 | * logging is enabled. |
| 283 | */ |
| 284 | #define BBR_TO_FRM_TMR 1 |
| 285 | #define BBR_TO_FRM_TLP 2 |
| 286 | #define BBR_TO_FRM_RACK 3 |
| 287 | #define BBR_TO_FRM_KEEP 4 |
| 288 | #define BBR_TO_FRM_PERSIST 5 |
| 289 | #define BBR_TO_FRM_DELACK 6 |
| 290 | |
| 291 | #define BBR_SEES_STRETCH_ACK 1 |
| 292 | #define BBR_SEES_COMPRESSED_ACKS 2 |
| 293 | |
| 294 | /* |
| 295 | * As we get each SACK we wade through the |
| 296 | * rc_map and mark off what is acked. |
| 297 | * We also increment rc_sacked as well. |
| 298 | * |
| 299 | * We also pay attention to missing entries |
| 300 | * based on the time and possibly mark them |
| 301 | * for retransmit. If we do and we are not already |
| 302 | * in recovery we enter recovery. In doing |
| 303 | * so we claer prr_delivered/holes_rxt and prr_sent_dur_rec. |
| 304 | * We also setup rc_next/rc_snd_nxt/rc_send_end so |
| 305 | * we will know where to send from. When not in |
| 306 | * recovery rc_next will be NULL and rc_snd_nxt should |
| 307 | * equal snd_max. |
| 308 | * |
| 309 | * Whenever we retransmit from recovery we increment |
| 310 | * rc_holes_rxt as we retran a block and mark it as retransmitted |
| 311 | * with the time it was sent. During non-recovery sending we |
| 312 | * add to our map and note the time down of any send expanding |
| 313 | * the rc_map at the tail and moving rc_snd_nxt up with snd_max. |
| 314 | * |
| 315 | * In recovery during SACK/ACK processing if a chunk has |
| 316 | * been retransmitted and it is now acked, we decrement rc_holes_rxt. |
| 317 | * When we retransmit from the scoreboard we use |
| 318 | * rc_next and rc_snd_nxt/rc_send_end to help us |
| 319 | * find what needs to be retran. |
| 320 | * |
| 321 | * To calculate pipe we simply take (snd_max - snd_una) + rc_holes_rxt |
| 322 | * This gets us the effect of RFC6675 pipe, counting twice for |
| 323 | * bytes retransmitted. |
| 324 | */ |
| 325 | |
| 326 | #define TT_BBR_FR_TMR	0x2001 |
| 327 | |
| 328 | #define BBR_SCALE 8 |
| 329 | #define BBR_UNIT (1 << BBR_SCALE) |
| 330 | |
| 331 | #define BBR_NUM_RTTS_FOR_DEL_LIMIT 8	/* How many pkt-rtts do we keep |
| 332 | 					 * Delivery rate for */ |
| 333 | #define BBR_NUM_RTTS_FOR_GOOG_DEL_LIMIT 10	/* How many pkt-rtts do we keep |
| 334 | 						 * Delivery rate for google */ |
| 335 | |
| 336 | #define BBR_SECONDS_NO_RTT 10	/* 10 seconds with no RTT shrinkage */ |
| 337 | #define BBR_PROBERTT_MAX 200	/* 200ms */ |
| 338 | #define BBR_PROBERTT_NUM_MSS 4 |
| 339 | #define BBR_STARTUP_EPOCHS 3 |
| 340 | #define USECS_IN_MSEC 1000 |
| 341 | #define BBR_TIME_TO_SECONDS(a) (a / USECS_IN_SECOND) |
| 342 | #define BBR_TIME_TO_MILLI(a) (a / MS_IN_USEC) |
| 343 | |
| 344 | /* BBR keeps time in usec's so we divide by 1000 and round up */ |
| 345 | #define BBR_TS_TO_MS(t) ((t+999)/MS_IN_USEC) |
| 346 | |
| 347 | /* |
| 348 | * Locking for the rack control block. |
| 349 | * a) Locked by INP_WLOCK |
| 350 | */ |
| 351 | #define BBR_STATE_STARTUP 0x01 |
| 352 | #define BBR_STATE_DRAIN 0x02 |
| 353 | #define BBR_STATE_PROBE_BW 0x03 |
| 354 | #define BBR_STATE_PROBE_RTT 0x04 |
| 355 | #define BBR_STATE_IDLE_EXIT 0x05 |
| 356 | |
| 357 | /* Substate defines for STATE == PROBE_BW */ |
| 358 | #define BBR_SUB_GAIN 0		/* State 0 where we are 5/4 BBR_UNIT */ |
| 359 | #define BBR_SUB_DRAIN 1		/* State 1 where we are at 3/4 BBR_UNIT */ |
| 360 | #define BBR_SUB_LEVEL1 2	/* State 1 first BBR_UNIT */ |
| 361 | #define BBR_SUB_LEVEL2 3	/* State 2nd BBR_UNIT */ |
| 362 | #define BBR_SUB_LEVEL3 4	/* State 3rd BBR_UNIT */ |
| 363 | #define BBR_SUB_LEVEL4 5	/* State 4th BBR_UNIT */ |
| 364 | #define BBR_SUB_LEVEL5 6	/* State 5th BBR_UNIT */ |
| 365 | #define BBR_SUB_LEVEL6 7	/* State last BBR_UNIT */ |
| 366 | #define BBR_SUBSTATE_COUNT 8 |
| 367 | |
| 368 | /* Single remaining reduce log */ |
| 369 | #define BBR_REDUCE_AT_FR 5 |
| 370 | |
| 371 | #define BBR_BIG_LOG_SIZE 300000 |
| 372 | |
| 373 | struct bbr_stats { |
| 374 | 	uint64_t bbr_badfr;		/* 0 */ |
| 375 | 	uint64_t bbr_badfr_bytes;	/* 1 */ |
| 376 | 	uint64_t bbr_saw_oerr;		/* 2 */ |
| 377 | 	uint64_t bbr_saw_emsgsiz;	/* 3 */ |
| 378 | 	uint64_t bbr_reorder_seen;	/* 4 */ |
| 379 | 	uint64_t bbr_tlp_tot;		/* 5 */ |
| 380 | 	uint64_t bbr_tlp_newdata;	/* 6 */ |
| 381 | 	uint64_t bbr_offset_recovery;	/* 7 */ |
| 382 | 	uint64_t bbr_tlp_retran_fail;	/* 8 */ |
| 383 | 	uint64_t bbr_to_tot;		/* 9 */ |
| 384 | 	uint64_t bbr_to_arm_rack;	/* 10 */ |
| 385 | 	uint64_t bbr_enter_probertt;	/* 11 */ |
| 386 | 	uint64_t bbr_tlp_set;		/* 12 */ |
| 387 | 	uint64_t bbr_resends_set;	/* 13 */ |
| 388 | 	uint64_t bbr_force_output;	/* 14 */ |
| 389 | 	uint64_t bbr_to_arm_tlp;	/* 15 */ |
| 390 | 	uint64_t bbr_paced_segments;	/* 16 */ |
| 391 | 	uint64_t bbr_saw_enobuf;	/* 17 */ |
| 392 | 	uint64_t bbr_to_alloc_failed;	/* 18 */ |
| 393 | 	uint64_t bbr_to_alloc_emerg;	/* 19 */ |
| 394 | 	uint64_t bbr_sack_proc_all;	/* 20 */ |
| 395 | 	uint64_t bbr_sack_proc_short;	/* 21 */ |
| 396 | 	uint64_t bbr_sack_proc_restart;	/* 22 */ |
| 397 | 	uint64_t bbr_to_alloc;		/* 23 */ |
| 398 | 	uint64_t bbr_offset_drop;	/* 24 */ |
| 399 | 	uint64_t bbr_runt_sacks;	/* 25 */ |
| 400 | 	uint64_t bbr_sack_passed;	/* 26 */ |
| 401 | 	uint64_t bbr_rlock_left_ret0;	/* 27 */ |
| 402 | 	uint64_t bbr_rlock_left_ret1;	/* 28 */ |
| 403 | 	uint64_t bbr_dynamic_rwnd;	/* 29 */ |
| 404 | 	uint64_t bbr_static_rwnd;	/* 30 */ |
| 405 | 	uint64_t bbr_sack_blocks;	/* 31 */ |
| 406 | 	uint64_t bbr_sack_blocks_skip;	/* 32 */ |
| 407 | 	uint64_t bbr_sack_search_both;	/* 33 */ |
| 408 | 	uint64_t bbr_sack_search_fwd;	/* 34 */ |
| 409 | 	uint64_t bbr_sack_search_back;	/* 35 */ |
| 410 | 	uint64_t bbr_plain_acks;	/* 36 */ |
| 411 | 	uint64_t bbr_acks_with_sacks;	/* 37 */ |
| 412 | 	uint64_t bbr_progress_drops;	/* 38 */ |
| 413 | 	uint64_t bbr_early;		/* 39 */ |
| 414 | 	uint64_t bbr_reneges_seen;	/* 40 */ |
| 415 | 	uint64_t bbr_persist_reneg;	/* 41 */ |
| 416 | 	uint64_t bbr_dropped_af_data;	/* 42 */ |
| 417 | 	uint64_t bbr_failed_mbuf_aloc;	/* 43 */ |
| 418 | 	uint64_t bbr_cwnd_limited;	/* 44 */ |
| 419 | 	uint64_t bbr_rwnd_limited;	/* 45 */ |
| 420 | 	uint64_t bbr_app_limited;	/* 46 */ |
| 421 | 	uint64_t bbr_force_timer_start;	/* 47 */ |
| 422 | 	uint64_t bbr_hpts_min_time;	/* 48 */ |
| 423 | 	uint64_t bbr_meets_tso_thresh; /* 49 */ |
| 424 | 	uint64_t bbr_miss_tso_rwnd;	/* 50 */ |
| 425 | 	uint64_t bbr_miss_tso_cwnd;	/* 51 */ |
| 426 | 	uint64_t bbr_miss_tso_app;	/* 52 */ |
| 427 | 	uint64_t bbr_miss_retran;	/* 53 */ |
| 428 | 	uint64_t bbr_miss_tlp;		/* 54 */ |
| 429 | 	uint64_t bbr_miss_unknown;	/* 55 */ |
| 430 | 	uint64_t bbr_hdwr_rl_add_ok;	/* 56 */ |
| 431 | 	uint64_t bbr_hdwr_rl_add_fail;	/* 57 */ |
| 432 | 	uint64_t bbr_hdwr_rl_mod_ok;	/* 58 */ |
| 433 | 	uint64_t bbr_hdwr_rl_mod_fail;	/* 59 */ |
| 434 | 	uint64_t bbr_collapsed_win; /* 60 */ |
| 435 | 	uint64_t bbr_alloc_limited;	/* 61 */ |
| 436 | 	uint64_t bbr_alloc_limited_conns; /* 62 */ |
| 437 | 	uint64_t bbr_split_limited;	/* 63 */ |
| 438 | }; |
| 439 | |
| 440 | /* |
| 441 | * The structure bbr_opt_stats is a simple |
| 442 | * way to see how many options are being |
| 443 | * changed in the stack. |
| 444 | */ |
| 445 | struct bbr_opts_stats { |
| 446 | 	uint64_t tcp_bbr_pace_per_sec; |
| 447 | 	uint64_t tcp_bbr_pace_del_tar; |
| 448 | 	uint64_t tcp_bbr_pace_seg_max; |
| 449 | 	uint64_t tcp_bbr_pace_seg_min; |
| 450 | 	uint64_t tcp_bbr_pace_cross; |
| 451 | 	uint64_t tcp_bbr_drain_inc_extra; |
| 452 | 	uint64_t tcp_bbr_unlimited; |
| 453 | 	uint64_t tcp_bbr_iwintso; |
| 454 | 	uint64_t tcp_bbr_rec_over_hpts; |
| 455 | 	uint64_t tcp_bbr_recforce; |
| 456 | 	uint64_t tcp_bbr_startup_pg; |
| 457 | 	uint64_t tcp_bbr_drain_pg; |
| 458 | 	uint64_t tcp_bbr_rwnd_is_app; |
| 459 | 	uint64_t tcp_bbr_probe_rtt_int; |
| 460 | 	uint64_t tcp_bbr_one_retran; |
| 461 | 	uint64_t tcp_bbr_startup_loss_exit; |
| 462 | 	uint64_t tcp_bbr_use_lowgain; |
| 463 | 	uint64_t tcp_bbr_lowgain_thresh; |
| 464 | 	uint64_t tcp_bbr_lowgain_half; |
| 465 | 	uint64_t tcp_bbr_lowgain_fd; |
| 466 | 	uint64_t tcp_bbr_usedel_rate; |
| 467 | 	uint64_t tcp_bbr_min_rto; |
| 468 | 	uint64_t tcp_bbr_max_rto; |
| 469 | 	uint64_t tcp_rack_pace_max_seg; |
| 470 | 	uint64_t tcp_rack_min_to; |
| 471 | 	uint64_t tcp_rack_reord_thresh; |
| 472 | 	uint64_t tcp_rack_reord_fade; |
| 473 | 	uint64_t tcp_rack_tlp_thresh; |
| 474 | 	uint64_t tcp_rack_pkt_delay; |
| 475 | 	uint64_t tcp_bbr_startup_exit_epoch; |
| 476 | 	uint64_t tcp_bbr_ack_comp_alg; |
| 477 | 	uint64_t tcp_rack_cheat; |
| 478 | 	uint64_t tcp_iwnd_tso; |
| 479 | 	uint64_t tcp_utter_max_tso; |
| 480 | 	uint64_t tcp_hdwr_pacing; |
| 481 | 	uint64_t tcp_extra_state; |
| 482 | 	uint64_t tcp_floor_min_tso; |
| 483 | 	/* New */ |
| 484 | 	uint64_t tcp_bbr_algorithm; |
| 485 | 	uint64_t tcp_bbr_tslimits; |
| 486 | 	uint64_t tcp_bbr_probertt_len; |
| 487 | 	uint64_t tcp_bbr_probertt_gain; |
| 488 | 	uint64_t tcp_bbr_topaceout; |
| 489 | 	uint64_t tcp_use_rackcheat; |
| 490 | 	uint64_t tcp_delack; |
| 491 | 	uint64_t tcp_maxpeak; |
| 492 | 	uint64_t tcp_retran_wtso; |
| 493 | 	uint64_t tcp_data_ac; |
| 494 | 	uint64_t tcp_ts_raises; |
| 495 | 	uint64_t tcp_pacing_oh_tmr; |
| 496 | 	uint64_t tcp_pacing_oh; |
| 497 | 	uint64_t tcp_policer_det; |
| 498 | }; |
| 499 | |
| 500 | #ifdef _KERNEL |
| 501 | #define BBR_STAT_SIZE (sizeof(struct bbr_stats)/sizeof(uint64_t)) |
| 502 | extern counter_u64_t bbr_stat_arry[BBR_STAT_SIZE]; |
| 503 | #define BBR_STAT_ADD(name, amm) counter_u64_add(bbr_stat_arry[(offsetof(struct bbr_stats, name)/sizeof(uint64_t))], (amm)) |
| 504 | #define BBR_STAT_INC(name) BBR_STAT_ADD(name, 1) |
| 505 | #define BBR_OPTS_SIZE (sizeof(struct bbr_stats)/sizeof(uint64_t)) |
| 506 | extern counter_u64_t bbr_opts_arry[BBR_OPTS_SIZE]; |
| 507 | #define BBR_OPTS_ADD(name, amm) counter_u64_add(bbr_opts_arry[(offsetof(struct bbr_opts_stats, name)/sizeof(uint64_t))], (amm)) |
| 508 | #define BBR_OPTS_INC(name) BBR_OPTS_ADD(name, 1) |
| 509 | #endif |
| 510 | |
| 511 | #define BBR_NUM_LOSS_RATES 3 |
| 512 | #define BBR_NUM_BW_RATES 3 |
| 513 | |
| 514 | #define BBR_RECOVERY_LOWRTT 1 |
| 515 | #define BBR_RECOVERY_MEDRTT 2 |
| 516 | #define BBR_RECOVERY_HIGHRTT 3 |
| 517 | #define BBR_RECOVERY_EXTREMERTT 4 |
| 518 | |
| 519 | struct bbr_control { |
| 520 | 	/*******************************/ |
| 521 | 	/* Cache line 2 from bbr start */ |
| 522 | 	/*******************************/ |
| 523 | 	struct bbr_head rc_map;	/* List of all segments Lock(a) */ |
| 524 | 	struct bbr_head rc_tmap;	/* List in transmit order Lock(a) */ |
| 525 | 	struct bbr_sendmap *rc_resend;	/* something we have been asked to |
| 526 | 					 * resend */ |
| 527 | 	uint32_t rc_last_delay_val;	/* How much we expect to delay Lock(a) */ |
| 528 | 	uint32_t rc_bbr_hptsi_gain:16,	/* Current hptsi gain Lock(a) */ |
| 529 | 	 rc_hpts_flags:16;	/* flags on whats on the pacer wheel */ |
| 530 | |
| 531 | 	uint32_t rc_delivered;	/* BRR delivered amount Lock(a) */ |
| 532 | 	uint32_t rc_hptsi_agg_delay;	/* How much time are we behind */ |
| 533 | |
| 534 | 	uint32_t rc_flight_at_input; |
| 535 | 	uint32_t rc_lost_bytes;		/* Total bytes currently marked lost */ |
| 536 | 	/*******************************/ |
| 537 | 	/* Cache line 3 from bbr start */ |
| 538 | 	/*******************************/ |
| 539 | 	struct time_filter rc_delrate; |
| 540 | 	/*******************************/ |
| 541 | 	/* Cache line 4 from bbr start */ |
| 542 | 	/*******************************/ |
| 543 | 	struct bbr_head rc_free;	/* List of Free map entries Lock(a) */ |
| 544 | 	struct bbr_sendmap *rc_tlp_send;	/* something we have been |
| 545 | 						 * asked to resend */ |
| 546 | 	uint32_t rc_del_time; |
| 547 | 	uint32_t rc_target_at_state;	/* Target for a state */ |
| 548 | |
| 549 | 	uint16_t rc_free_cnt;	/* Number of free entries on the rc_free list |
| 550 | 				 * Lock(a) */ |
| 551 | 	uint16_t rc_startup_pg; |
| 552 | |
| 553 | 	uint32_t cur_rtt;	/* Last RTT from ack */ |
| 554 | |
| 555 | 	uint32_t rc_went_idle_time;	/* Used for persits to see if its |
| 556 | 					 * probe-rtt qualified */ |
| 557 | 	uint32_t rc_pace_max_segs:17,	/* How much in any single TSO we send Lock(a) */ |
| 558 | 		 rc_pace_min_segs:15;	/* The minimum single segment size before we enter persists */ |
| 559 | |
| 560 | 	uint32_t rc_rtt_shrinks;	/* Time of last rtt shrinkage Lock(a) */ |
| 561 | 	uint32_t r_app_limited_until; |
| 562 | 	uint32_t rc_timer_exp;	/* If a timer ticks of expiry */ |
| 563 | 	uint32_t rc_rcv_epoch_start;	/* Start time of the Epoch Lock(a) */ |
| 564 | |
| 565 | 	/*******************************/ |
| 566 | 	/* Cache line 5 from bbr start */ |
| 567 | 	/*******************************/ |
| 568 | |
| 569 | 	uint32_t rc_lost_at_pktepoch;	/* what the lost value was at the last |
| 570 | 					 * pkt-epoch */ |
| 571 | 	uint32_t r_measurement_count;	/* count of measurement applied lock(a) */ |
| 572 | |
| 573 | 	uint32_t rc_last_tlp_seq;	/* Last tlp sequence Lock(a) */ |
| 574 | 	uint16_t rc_reorder_shift;	/* Socket option value Lock(a) */ |
| 575 | 	uint16_t rc_pkt_delay;	/* Socket option value Lock(a) */ |
| 576 | |
| 577 | 	struct bbr_sendmap *rc_sacklast;	/* sack remembered place |
| 578 | 						 * Lock(a) */ |
| 579 | 	struct bbr_sendmap *rc_next;	/* remembered place where we next |
| 580 | 					 * retransmit at Lock(a) */ |
| 581 | |
| 582 | 	uint32_t rc_sacked;	/* Tot sacked on scoreboard Lock(a) */ |
| 583 | 	uint32_t rc_holes_rxt;	/* Tot retraned from scoreboard Lock(a) */ |
| 584 | |
| 585 | 	uint32_t rc_reorder_ts;	/* Last time we saw reordering Lock(a) */ |
| 586 | 	uint32_t rc_init_rwnd;	/* Initial rwnd when we transitioned */ |
| 587 | 				/*- --- |
| 588 | 				 * used only initial and close |
| 589 | 				 */ |
| 590 | 	uint32_t rc_high_rwnd;	/* Highest rwnd seen */ |
| 591 | 	uint32_t rc_lowest_rtt;	/* Smallest RTT we have seen */ |
| 592 | |
| 593 | 	uint32_t rc_last_rtt;	/* Last valid measured RTT that ack'd data */ |
| 594 | 	uint32_t bbr_cross_over; |
| 595 | |
| 596 | 	/*******************************/ |
| 597 | 	/* Cache line 6 from bbr start */ |
| 598 | 	/*******************************/ |
| 599 | 	struct sack_filter bbr_sf; |
| 600 | |
| 601 | 	/*******************************/ |
| 602 | 	/* Cache line 7 from bbr start */ |
| 603 | 	/*******************************/ |
| 604 | 	struct time_filter_small rc_rttprop; |
| 605 | 	uint32_t last_inbound_ts;	/* Peers last timestamp */ |
| 606 | |
| 607 | 	uint32_t rc_inc_tcp_oh: 1, |
| 608 | 		 rc_inc_ip_oh: 1, |
| 609 | 		 rc_inc_enet_oh:1, |
| 610 | 		 rc_incr_tmrs:1, |
| 611 | 		 restrict_growth:28; |
| 612 | 	uint32_t rc_lt_epoch_use;	/* When we started lt-bw use Lock(a) */ |
| 613 | |
| 614 | 	uint32_t rc_recovery_start;	/* Time we start recovery Lock(a) */ |
| 615 | 	uint32_t rc_lt_del;	/* Delivered at lt bw sampling start Lock(a) */ |
| 616 | |
| 617 | 	uint64_t rc_bbr_cur_del_rate;	/* Current measured delivery rate |
| 618 | 					 * Lock(a) */ |
| 619 | |
| 620 | 	/*******************************/ |
| 621 | 	/* Cache line 8 from bbr start */ |
| 622 | 	/*******************************/ |
| 623 | 	uint32_t rc_cwnd_on_ent;	/* On entry to recovery the cwnd |
| 624 | 					 * Lock(a) */ |
| 625 | 	uint32_t rc_agg_early;	/* aggregate amount early */ |
| 626 | |
| 627 | 	uint32_t rc_rcvtime;	/* When we last received data Lock(a) */ |
| 628 | 	uint32_t rc_pkt_epoch_del;	/* seq num that we need for RTT epoch */ |
| 629 | |
| 630 | 	uint32_t rc_pkt_epoch;	/* Epoch based on packet RTTs */ |
| 631 | 	uint32_t rc_pkt_epoch_time;	/* Time we started the pkt epoch */ |
| 632 | |
| 633 | 	uint32_t rc_pkt_epoch_rtt;	/* RTT using the packet epoch */ |
| 634 | 	uint32_t rc_rtt_epoch;	/* Current RTT epoch, it ticks every rttProp |
| 635 | 				 * Lock(a) */ |
| 636 | 	uint32_t lowest_rtt; |
| 637 | 	uint32_t bbr_smallest_srtt_this_state; |
| 638 | |
| 639 | 	uint32_t rc_lt_epoch;	/* LT epoch start of bw_sampling */ |
| 640 | 	uint32_t rc_lost_at_startup; |
| 641 | |
| 642 | 	uint32_t rc_bbr_state_atflight; |
| 643 | 	uint32_t rc_bbr_last_startup_epoch;	/* Last startup epoch where we |
| 644 | 						 * increased 20% */ |
| 645 | 	uint32_t rc_bbr_enters_probertt;	/* Timestamp we entered |
| 646 | 						 * probertt Lock(a) */ |
| 647 | 	uint32_t rc_lt_time;	/* Time of lt sampling start Lock(a) */ |
| 648 | |
| 649 | 	/*******************************/ |
| 650 | 	/* Cache line 9 from bbr start */ |
| 651 | 	/*******************************/ |
| 652 | 	uint64_t rc_lt_bw;	/* LT bw calculated Lock(a) */ |
| 653 | 	uint64_t rc_bbr_lastbtlbw;	/* For startup, what was last btlbw I |
| 654 | 					 * saw to check the 20% gain Lock(a) */ |
| 655 | |
| 656 | 	uint32_t rc_bbr_cwnd_gain;	/* Current cwnd gain Lock(a) */ |
| 657 | 	uint32_t rc_pkt_epoch_loss_rate;	/* pkt-epoch loss rate */ |
| 658 | |
| 659 | 	uint32_t rc_saved_cwnd;	/* Saved cwnd during Probe-rtt drain Lock(a) */ |
| 660 | 	uint32_t substate_pe; |
| 661 | |
| 662 | 	uint32_t rc_lost;	/* Number of bytes lost Lock(a) */ |
| 663 | 	uint32_t rc_exta_time_gd; /* How much extra time we got in d/g */ |
| 664 | |
| 665 | 	uint32_t rc_lt_lost;	/* Number of lt bytes lost at sampling start |
| 666 | 				 * Lock(a) */ |
| 667 | 	uint32_t rc_bbr_state_time; |
| 668 | |
| 669 | 	uint32_t rc_min_to;	/* Socket option value Lock(a) */ |
| 670 | 	uint32_t rc_initial_hptsi_bw;	/* Our initial startup bw Lock(a) */ |
| 671 | |
| 672 | 	uint32_t bbr_lost_at_state;	/* Temp counter debug lost value as we |
| 673 | 					 * enter a state */ |
| 674 | 	/*******************************/ |
| 675 | 	/* Cache line 10 from bbr start */ |
| 676 | 	/*******************************/ |
| 677 | 	uint32_t rc_level_state_extra; |
| 678 | 	uint32_t rc_red_cwnd_pe; |
| 679 | 	const struct tcp_hwrate_limit_table *crte; |
| 680 | 	uint64_t red_bw; |
| 681 | |
| 682 | 	uint32_t rc_probertt_int; |
| 683 | 	uint32_t rc_probertt_srttchktim;	/* Time we last did a srtt |
| 684 | 						 * check */ |
| 685 | 	uint32_t gain_epoch;	/* Epoch we should be out of gain */ |
| 686 | 	uint32_t rc_min_rto_ms; |
| 687 | |
| 688 | 	uint32_t rc_reorder_fade;	/* Socket option value Lock(a) */ |
| 689 | 	uint32_t last_startup_measure; |
| 690 | |
| 691 | 	int32_t bbr_hptsi_per_second; |
| 692 | 	int32_t bbr_hptsi_segments_delay_tar; |
| 693 | |
| 694 | 	int32_t bbr_hptsi_segments_max; |
| 695 | 	uint32_t bbr_rttprobe_gain_val; |
| 696 | 	/*******************************/ |
| 697 | 	/* Cache line 11 from bbr start */ |
| 698 | 	/*******************************/ |
| 699 | 	uint32_t cur_rtt_send_time;	/* Time we sent our rtt measured packet */ |
| 700 | 	uint32_t bbr_peer_tsratio;	/* Our calculated ts ratio to multply */ |
| 701 | 	uint32_t bbr_ts_check_tstmp;	/* When we filled it the TS that came on the ack */ |
| 702 | 	uint32_t bbr_ts_check_our_cts;	/* When we filled it the cts of the send */ |
| 703 | 	uint32_t rc_tlp_rxt_last_time; |
| 704 | 	uint32_t bbr_smallest_srtt_state2; |
| 705 | 	uint32_t bbr_hdwr_cnt_noset_snt;	/* count of hw pacing sends during delay */ |
| 706 | 	uint32_t startup_last_srtt; |
| 707 | 	uint32_t rc_ack_hdwr_delay; |
| 708 | 	uint32_t highest_hdwr_delay;		/* Largest delay we have seen from hardware */ |
| 709 | 	uint32_t non_gain_extra; |
| 710 | 	uint32_t recovery_lr;			/* The sum of the loss rate from the pe's during recovery */ |
| 711 | 	uint32_t last_in_probertt; |
| 712 | 	uint32_t flightsize_at_drain;		/* In draining what was the last marked flight size */ |
| 713 | 	uint32_t rc_pe_of_prtt;			/* PE we went into probe-rtt */ |
| 714 | 	uint32_t ts_in;				/* ts that went with the last rtt */ |
| 715 | |
| 716 | 	uint16_t rc_tlp_seg_send_cnt;	/* Number of times we have TLP sent |
| 717 | 					 * rc_last_tlp_seq Lock(a) */ |
| 718 | 	uint16_t rc_drain_pg; |
| 719 | 	uint32_t rc_num_maps_alloced;		/* num send map entries allocated */ |
| 720 | 	uint32_t rc_num_split_allocs;		/* num split map entries allocated */ |
| 721 | 	uint16_t rc_num_small_maps_alloced;	/* Number of sack blocks |
| 722 | 						 * allocated */ |
| 723 | 	uint16_t bbr_hptsi_bytes_min; |
| 724 | |
| 725 | 	uint16_t bbr_hptsi_segments_floor; |
| 726 | 	uint16_t bbr_utter_max; |
| 727 | 	uint16_t bbr_google_discount; |
| 728 | |
| 729 | }; |
| 730 | |
| 731 | struct socket; |
| 732 | struct tcp_bbr { |
| 733 | 	/* First cache line 0x00 */ |
| 734 | 	int32_t(*r_substate) (struct mbuf *, struct tcphdr *, |
| 735 | 	 struct socket *, struct tcpcb *, struct tcpopt *, |
| 736 | 	 int32_t, int32_t, uint32_t, int32_t, int32_t, uint8_t);	/* Lock(a) */ |
| 737 | 	struct tcpcb *rc_tp;	/* The tcpcb Lock(a) */ |
| 738 | 	struct inpcb *rc_inp;	/* The inpcb Lock(a) */ |
| 739 | 	struct timeval rc_tv; |
| 740 | 	uint32_t rc_pacer_started; /* Time we started the pacer */ |
| 741 | 	uint16_t no_pacing_until:8, /* No pacing until N packet epochs */ |
| 742 | 		 ts_can_raise:1,/* TS b/w calculations can raise the bw higher */ |
| 743 | 		 skip_gain:1,	/* Skip the gain cycle (hardware pacing) */ |
| 744 | 		 gain_is_limited:1,	/* With hardware pacing we are limiting gain */ |
| 745 | 		 output_error_seen:1, |
| 746 | 		 oerror_cnt:4, |
| 747 | 		hw_pacing_set:1;	/* long enough has passed for us to start pacing */ |
| 748 | 	uint16_t xxx_r_ack_count;	/* During recovery count of ack's received |
| 749 | 				 * that added data since output */ |
| 750 | 	uint16_t bbr_segs_rcvd;	/* In Segment count since we sent a ack */ |
| 751 | |
| 752 | 	uint8_t bbr_timer_src:4,	/* Used for debugging Lock(a) */ |
| 753 | 		bbr_use_rack_cheat:1, /* Use the rack cheat */ |
| 754 | 		bbr_init_win_cheat:1,	/* Send full IW for TSO */ |
| 755 | 		bbr_attempt_hdwr_pace:1,/* Try to do hardware pacing */ |
| 756 | 		bbr_hdrw_pacing:1;	/* Hardware pacing is available */ |
| 757 | 	uint8_t bbr_hdw_pace_ena:1,	/* Does the connection allow hardware pacing to be attempted */ |
| 758 | 		bbr_prev_in_rec:1,	/* We were previously in recovery */ |
| 759 | 		pkt_conservation:1, |
| 760 | 		use_policer_detection:1, |
| 761 | 		xxx_bbr_hdw_pace_idx:4;	/* If hardware pacing is on, index to slot in pace tbl */ |
| 762 | 	uint16_t r_wanted_output:1, |
| 763 | 		 rtt_valid:1, |
| 764 | 		 rc_timer_first:1, |
| 765 | 		 rc_output_starts_timer:1, |
| 766 | 		 rc_resends_use_tso:1, |
| 767 | 		 rc_all_timers_stopped:1, |
| 768 | 		 rc_loss_exit:1, |
| 769 | 		 rc_ack_was_delayed:1, |
| 770 | 		 rc_lt_is_sampling:1, |
| 771 | 		 rc_filled_pipe:1, |
| 772 | 		 rc_tlp_new_data:1, |
| 773 | 		 rc_hit_state_1:1, |
| 774 | 		 rc_ts_valid:1, |
| 775 | 		 rc_prtt_set_ts:1, |
| 776 | 		 rc_is_pkt_epoch_now:1, |
| 777 | 		 rc_has_collapsed:1; |
| 778 | |
| 779 | 	uint8_t r_state:4,	/* Current bbr state Lock(a) */ |
| 780 | 	 r_agg_early_set:1,	/* Did we get called early */ |
| 781 | 		r_init_rtt:1, |
| 782 | 		r_use_policer:1,	/* For google mode only */ |
| 783 | 		r_recovery_bw:1; |
| 784 | 	uint8_t r_timer_override:1,	/* pacer override Lock(a) 0/1 */ |
| 785 | 	 rc_in_persist:1, |
| 786 | 		rc_lt_use_bw:1, |
| 787 | 		rc_allow_data_af_clo:1, |
| 788 | 		rc_tlp_rtx_out:1,	/* A TLP is in flight */ |
| 789 | 	 rc_tlp_in_progress:1,	/* a TLP timer is running needed? */ |
| 790 | 	 rc_use_idle_restart:1; /* Do we restart fast after idle (persist or applim) */ |
| 791 | 	uint8_t rc_bbr_state:3,	/* What is the major BBR state */ |
| 792 | 	 rc_bbr_substate:3,	/* For probeBW state */ |
| 793 | 	 r_is_v6:1, |
| 794 | 		rc_past_init_win:1; |
| 795 | 	uint8_t rc_last_options; |
| 796 | 	uint8_t rc_tlp_threshold;	/* Socket option value Lock(a) */ |
| 797 | 	uint8_t rc_max_rto_sec; |
| 798 | 	uint8_t rc_cwnd_limited:1,	/* We are cwnd limited */ |
| 799 | 		rc_tmr_stopped:7;	/* What timers have been stopped */ |
| 800 | 	uint8_t rc_use_google:1, |
| 801 | 		rc_use_ts_limit:1, |
| 802 | 		rc_ts_data_set:1,	/* We have filled a set point to determine */ |
| 803 | 		rc_ts_clock_set:1, 	/* We have determined the ts type */ |
| 804 | 		rc_ts_cant_be_used:1,	/* We determined we can't use ts values */ |
| 805 | 		rc_ack_is_cumack:1, |
| 806 | 		rc_no_pacing:1, |
| 807 | 		alloc_limit_reported:1; |
| 808 | 	uint8_t rc_init_win; |
| 809 | 	/* Cache line 2 0x40 */ |
| 810 | 	struct bbr_control r_ctl; |
| 811 | #ifdef _KERNEL |
| 812 | } __aligned(CACHE_LINE_SIZE); |
| 813 | #else |
| 814 | }; |
| 815 | #endif |
| 816 | |
| 817 | #endif |