xref: /freebsd/sys/netinet/tcp_stacks/tcp_rack.h (revision 8df12ffcc21e5daf45cbde70aa8e37320b667e63)
189e560f4SRandall Stewart /*-
235c7bb34SRandall Stewart  * Copyright (c) 2016-9 Netflix, Inc.
389e560f4SRandall Stewart  *
489e560f4SRandall Stewart  * Redistribution and use in source and binary forms, with or without
589e560f4SRandall Stewart  * modification, are permitted provided that the following conditions
689e560f4SRandall Stewart  * are met:
789e560f4SRandall Stewart  * 1. Redistributions of source code must retain the above copyright
889e560f4SRandall Stewart  *    notice, this list of conditions and the following disclaimer.
989e560f4SRandall Stewart  * 2. Redistributions in binary form must reproduce the above copyright
1089e560f4SRandall Stewart  *    notice, this list of conditions and the following disclaimer in the
1189e560f4SRandall Stewart  *    documentation and/or other materials provided with the distribution.
1289e560f4SRandall Stewart  *
1389e560f4SRandall Stewart  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1489e560f4SRandall Stewart  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1589e560f4SRandall Stewart  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1689e560f4SRandall Stewart  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1789e560f4SRandall Stewart  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1889e560f4SRandall Stewart  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1989e560f4SRandall Stewart  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2089e560f4SRandall Stewart  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2189e560f4SRandall Stewart  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2289e560f4SRandall Stewart  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2389e560f4SRandall Stewart  * SUCH DAMAGE.
2489e560f4SRandall Stewart  *
2589e560f4SRandall Stewart  * $FreeBSD$
2689e560f4SRandall Stewart  */
2789e560f4SRandall Stewart 
2889e560f4SRandall Stewart #ifndef _NETINET_TCP_RACK_H_
2989e560f4SRandall Stewart #define _NETINET_TCP_RACK_H_
3089e560f4SRandall Stewart 
3189e560f4SRandall Stewart #define RACK_ACKED	    0x0001/* The remote endpoint acked this */
3235c7bb34SRandall Stewart #define RACK_TO_MIXED	    0x0002/* A timeout occured that mixed the send order - not used */
3335c7bb34SRandall Stewart #define RACK_DEFERRED	    0x0004/* We can't use this for RTT calc - not used */
3489e560f4SRandall Stewart #define RACK_OVERMAX	    0x0008/* We have more retran's then we can fit */
3589e560f4SRandall Stewart #define RACK_SACK_PASSED    0x0010/* A sack was done above this block */
3689e560f4SRandall Stewart #define RACK_WAS_SACKPASS   0x0020/* We retransmitted due to SACK pass */
3789e560f4SRandall Stewart #define RACK_HAS_FIN	    0x0040/* segment is sent with fin */
3889e560f4SRandall Stewart #define RACK_TLP	    0x0080/* segment sent as tail-loss-probe */
3935c7bb34SRandall Stewart #define RACK_RWND_COLLAPSED 0x0100/* The peer collapsed the rwnd on the segment */
4089e560f4SRandall Stewart #define RACK_NUM_OF_RETRANS 3
4189e560f4SRandall Stewart 
4289e560f4SRandall Stewart #define RACK_INITIAL_RTO 1000 /* 1 second in milli seconds */
4389e560f4SRandall Stewart 
4489e560f4SRandall Stewart struct rack_sendmap {
4589e560f4SRandall Stewart 	uint32_t r_start;	/* Sequence number of the segment */
4689e560f4SRandall Stewart 	uint32_t r_end;		/* End seq, this is 1 beyond actually */
4735c7bb34SRandall Stewart 	TAILQ_ENTRY(rack_sendmap) r_tnext;	/* Time of transmit based next */
4835c7bb34SRandall Stewart 	RB_ENTRY(rack_sendmap) r_next;		/* RB Tree next */
4989e560f4SRandall Stewart 	uint32_t r_rtr_bytes;	/* How many bytes have been retransmitted */
5089e560f4SRandall Stewart 	uint16_t r_rtr_cnt;	/* Retran count, index this -1 to get time
5189e560f4SRandall Stewart 				 * sent */
5235c7bb34SRandall Stewart 	uint16_t r_flags;	/* Flags as defined above */
5335c7bb34SRandall Stewart 	uint32_t r_tim_lastsent[RACK_NUM_OF_RETRANS];
5435c7bb34SRandall Stewart 	uint8_t r_dupack;	/* Dup ack count */
5589e560f4SRandall Stewart 	uint8_t r_in_tmap;	/* Flag to see if its in the r_tnext array */
565e02b277SJonathan T. Looney 	uint8_t r_limit_type;	/* is this entry counted against a limit? */
5735c7bb34SRandall Stewart 	uint8_t r_resv[49];
5889e560f4SRandall Stewart };
5989e560f4SRandall Stewart 
6035c7bb34SRandall Stewart RB_HEAD(rack_rb_tree_head, rack_sendmap);
6189e560f4SRandall Stewart TAILQ_HEAD(rack_head, rack_sendmap);
6289e560f4SRandall Stewart 
6335c7bb34SRandall Stewart #define RACK_LIMIT_TYPE_SPLIT	1
6489e560f4SRandall Stewart 
6589e560f4SRandall Stewart /*
6689e560f4SRandall Stewart  * We use the rate sample structure to
6789e560f4SRandall Stewart  * assist in single sack/ack rate and rtt
6889e560f4SRandall Stewart  * calculation. In the future we will expand
6989e560f4SRandall Stewart  * this in BBR to do forward rate sample
7089e560f4SRandall Stewart  * b/w estimation.
7189e560f4SRandall Stewart  */
7289e560f4SRandall Stewart #define RACK_RTT_EMPTY 0x00000001	/* Nothing yet stored in RTT's */
7389e560f4SRandall Stewart #define RACK_RTT_VALID 0x00000002	/* We have at least one valid RTT */
7489e560f4SRandall Stewart struct rack_rtt_sample {
7589e560f4SRandall Stewart 	uint32_t rs_flags;
7689e560f4SRandall Stewart 	uint32_t rs_rtt_lowest;
7789e560f4SRandall Stewart 	uint32_t rs_rtt_highest;
7889e560f4SRandall Stewart 	uint32_t rs_rtt_cnt;
7989e560f4SRandall Stewart 	uint64_t rs_rtt_tot;
8089e560f4SRandall Stewart };
8189e560f4SRandall Stewart 
8289e560f4SRandall Stewart #define RACK_LOG_TYPE_ACK	0x01
8389e560f4SRandall Stewart #define RACK_LOG_TYPE_OUT	0x02
8489e560f4SRandall Stewart #define RACK_LOG_TYPE_TO	0x03
8589e560f4SRandall Stewart #define RACK_LOG_TYPE_ALLOC     0x04
8689e560f4SRandall Stewart #define RACK_LOG_TYPE_FREE      0x05
8789e560f4SRandall Stewart 
8889e560f4SRandall Stewart 
8989e560f4SRandall Stewart struct rack_log {
9089e560f4SRandall Stewart 	union {
9189e560f4SRandall Stewart 		struct rack_sendmap *rsm;	/* For alloc/free */
9289e560f4SRandall Stewart 		uint64_t sb_acc;/* For out/ack or t-o */
9389e560f4SRandall Stewart 	};
9489e560f4SRandall Stewart 	uint32_t th_seq;
9589e560f4SRandall Stewart 	uint32_t th_ack;
9689e560f4SRandall Stewart 	uint32_t snd_una;
9789e560f4SRandall Stewart 	uint32_t snd_nxt;	/* th_win for TYPE_ACK */
9889e560f4SRandall Stewart 	uint32_t snd_max;
9989e560f4SRandall Stewart 	uint32_t blk_start[4];
10089e560f4SRandall Stewart 	uint32_t blk_end[4];
10189e560f4SRandall Stewart 	uint8_t type;
10289e560f4SRandall Stewart 	uint8_t n_sackblks;
10389e560f4SRandall Stewart 	uint16_t len;		/* Timeout T3=1, TLP=2, RACK=3 */
10489e560f4SRandall Stewart };
10589e560f4SRandall Stewart 
10689e560f4SRandall Stewart /*
10789e560f4SRandall Stewart  * Magic numbers for logging timeout events if the
10889e560f4SRandall Stewart  * logging is enabled.
10989e560f4SRandall Stewart  */
11089e560f4SRandall Stewart #define RACK_TO_FRM_TMR  1
11189e560f4SRandall Stewart #define RACK_TO_FRM_TLP  2
11289e560f4SRandall Stewart #define RACK_TO_FRM_RACK 3
11389e560f4SRandall Stewart #define RACK_TO_FRM_KEEP 4
11489e560f4SRandall Stewart #define RACK_TO_FRM_PERSIST 5
11589e560f4SRandall Stewart #define RACK_TO_FRM_DELACK 6
11689e560f4SRandall Stewart 
11789e560f4SRandall Stewart struct rack_opts_stats {
11889e560f4SRandall Stewart 	uint64_t tcp_rack_prop_rate;
11989e560f4SRandall Stewart  	uint64_t tcp_rack_prop;
12089e560f4SRandall Stewart 	uint64_t tcp_rack_tlp_reduce;
12189e560f4SRandall Stewart 	uint64_t tcp_rack_early_recov;
12289e560f4SRandall Stewart 	uint64_t tcp_rack_pace_always;
12389e560f4SRandall Stewart 	uint64_t tcp_rack_pace_reduce;
12489e560f4SRandall Stewart 	uint64_t tcp_rack_max_seg;
12589e560f4SRandall Stewart 	uint64_t tcp_rack_prr_sendalot;
12689e560f4SRandall Stewart 	uint64_t tcp_rack_min_to;
12789e560f4SRandall Stewart 	uint64_t tcp_rack_early_seg;
12889e560f4SRandall Stewart 	uint64_t tcp_rack_reord_thresh;
12989e560f4SRandall Stewart 	uint64_t tcp_rack_reord_fade;
13089e560f4SRandall Stewart 	uint64_t tcp_rack_tlp_thresh;
13189e560f4SRandall Stewart 	uint64_t tcp_rack_pkt_delay;
13289e560f4SRandall Stewart 	uint64_t tcp_rack_tlp_inc_var;
13389e560f4SRandall Stewart 	uint64_t tcp_tlp_use;
13489e560f4SRandall Stewart 	uint64_t tcp_rack_idle_reduce;
13589e560f4SRandall Stewart 	uint64_t tcp_rack_idle_reduce_high;
13689e560f4SRandall Stewart 	uint64_t rack_no_timer_in_hpts;
13789e560f4SRandall Stewart 	uint64_t tcp_rack_min_pace_seg;
13889e560f4SRandall Stewart 	uint64_t tcp_rack_min_pace;
13935c7bb34SRandall Stewart 	uint64_t tcp_rack_cheat;
14035c7bb34SRandall Stewart 	uint64_t tcp_rack_no_sack;
14189e560f4SRandall Stewart };
14289e560f4SRandall Stewart 
14389e560f4SRandall Stewart #define TLP_USE_ID	1	/* Internet draft behavior */
14489e560f4SRandall Stewart #define TLP_USE_TWO_ONE 2	/* Use 2.1 behavior */
14589e560f4SRandall Stewart #define TLP_USE_TWO_TWO 3	/* Use 2.2 behavior */
14689e560f4SRandall Stewart 
14789e560f4SRandall Stewart #ifdef _KERNEL
14889e560f4SRandall Stewart #define RACK_OPTS_SIZE (sizeof(struct rack_opts_stats)/sizeof(uint64_t))
14989e560f4SRandall Stewart extern counter_u64_t rack_opts_arry[RACK_OPTS_SIZE];
15089e560f4SRandall Stewart #define RACK_OPTS_ADD(name, amm) counter_u64_add(rack_opts_arry[(offsetof(struct rack_opts_stats, name)/sizeof(uint64_t))], (amm))
15189e560f4SRandall Stewart #define RACK_OPTS_INC(name) RACK_OPTS_ADD(name, 1)
15289e560f4SRandall Stewart #endif
15389e560f4SRandall Stewart /*
15489e560f4SRandall Stewart  * As we get each SACK we wade through the
15589e560f4SRandall Stewart  * rc_map and mark off what is acked.
15689e560f4SRandall Stewart  * We also increment rc_sacked as well.
15789e560f4SRandall Stewart  *
15889e560f4SRandall Stewart  * We also pay attention to missing entries
15989e560f4SRandall Stewart  * based on the time and possibly mark them
16089e560f4SRandall Stewart  * for retransmit. If we do and we are not already
16189e560f4SRandall Stewart  * in recovery we enter recovery. In doing
16289e560f4SRandall Stewart  * so we claer prr_delivered/holes_rxt and prr_sent_dur_rec.
16389e560f4SRandall Stewart  * We also setup rc_next/rc_snd_nxt/rc_send_end so
16489e560f4SRandall Stewart  * we will know where to send from. When not in
16589e560f4SRandall Stewart  * recovery rc_next will be NULL and rc_snd_nxt should
16689e560f4SRandall Stewart  * equal snd_max.
16789e560f4SRandall Stewart  *
16889e560f4SRandall Stewart  * Whenever we retransmit from recovery we increment
16989e560f4SRandall Stewart  * rc_holes_rxt as we retran a block and mark it as retransmitted
17089e560f4SRandall Stewart  * with the time it was sent. During non-recovery sending we
17189e560f4SRandall Stewart  * add to our map and note the time down of any send expanding
17289e560f4SRandall Stewart  * the rc_map at the tail and moving rc_snd_nxt up with snd_max.
17389e560f4SRandall Stewart  *
17489e560f4SRandall Stewart  * In recovery during SACK/ACK processing if a chunk has
17589e560f4SRandall Stewart  * been retransmitted and it is now acked, we decrement rc_holes_rxt.
17689e560f4SRandall Stewart  * When we retransmit from the scoreboard we use
17789e560f4SRandall Stewart  * rc_next and rc_snd_nxt/rc_send_end to help us
17889e560f4SRandall Stewart  * find what needs to be retran.
17989e560f4SRandall Stewart  *
18089e560f4SRandall Stewart  * To calculate pipe we simply take (snd_max - snd_una) + rc_holes_rxt
18189e560f4SRandall Stewart  * This gets us the effect of RFC6675 pipe, counting twice for
18289e560f4SRandall Stewart  * bytes retransmitted.
18389e560f4SRandall Stewart  */
18489e560f4SRandall Stewart 
18589e560f4SRandall Stewart #define TT_RACK_FR_TMR	0x2000
18689e560f4SRandall Stewart 
18789e560f4SRandall Stewart /*
18889e560f4SRandall Stewart  * Locking for the rack control block.
18989e560f4SRandall Stewart  * a) Locked by INP_WLOCK
19089e560f4SRandall Stewart  * b) Locked by the hpts-mutex
19189e560f4SRandall Stewart  *
19289e560f4SRandall Stewart  */
19335c7bb34SRandall Stewart #define RACK_GP_HIST 4	/* How much goodput history do we maintain? */
19489e560f4SRandall Stewart 
19589e560f4SRandall Stewart struct rack_control {
19689e560f4SRandall Stewart 	/* Second cache line 0x40 from tcp_rack */
19735c7bb34SRandall Stewart 	struct rack_rb_tree_head rc_mtree; /* Tree of all segments Lock(a) */
19889e560f4SRandall Stewart 	struct rack_head rc_tmap;	/* List in transmit order Lock(a) */
19989e560f4SRandall Stewart 	struct rack_sendmap *rc_tlpsend;	/* Remembered place for
20089e560f4SRandall Stewart 						 * tlp_sending Lock(a) */
20189e560f4SRandall Stewart 	struct rack_sendmap *rc_resend;	/* something we have been asked to
20289e560f4SRandall Stewart 					 * resend */
20335c7bb34SRandall Stewart 	struct timeval rc_last_time_decay;	/* SAD time decay happened here */
20435c7bb34SRandall Stewart 	uint32_t input_pkt;
20535c7bb34SRandall Stewart 	uint32_t saved_input_pkt;
20689e560f4SRandall Stewart 	uint32_t rc_hpts_flags;
20789e560f4SRandall Stewart 	uint32_t rc_timer_exp;	/* If a timer ticks of expiry */
20889e560f4SRandall Stewart 	uint32_t rc_rack_min_rtt;	/* lowest RTT seen Lock(a) */
20989e560f4SRandall Stewart 	uint32_t rc_rack_largest_cwnd;	/* Largest CWND we have seen Lock(a) */
21089e560f4SRandall Stewart 
21189e560f4SRandall Stewart 	/* Third Cache line 0x80 */
21289e560f4SRandall Stewart 	struct rack_head rc_free;	/* Allocation array */
21389e560f4SRandall Stewart 	uint32_t rc_time_last_sent;	/* Time we last sent some data and
21489e560f4SRandall Stewart 					 * logged it Lock(a). */
21589e560f4SRandall Stewart 	uint32_t rc_reorder_ts;	/* Last time we saw reordering Lock(a) */
21689e560f4SRandall Stewart 
21789e560f4SRandall Stewart 	uint32_t rc_tlp_new_data;	/* we need to send new-data on a TLP
21889e560f4SRandall Stewart 					 * Lock(a) */
21989e560f4SRandall Stewart 	uint32_t rc_prr_out;	/* bytes sent during recovery Lock(a) */
22089e560f4SRandall Stewart 
22189e560f4SRandall Stewart 	uint32_t rc_prr_recovery_fs;	/* recovery fs point Lock(a) */
22289e560f4SRandall Stewart 
22389e560f4SRandall Stewart 	uint32_t rc_prr_sndcnt;	/* Prr sndcnt Lock(a) */
22489e560f4SRandall Stewart 
22589e560f4SRandall Stewart 	uint32_t rc_sacked;	/* Tot sacked on scoreboard Lock(a) */
22689e560f4SRandall Stewart 	uint32_t rc_last_tlp_seq;	/* Last tlp sequence Lock(a) */
22789e560f4SRandall Stewart 
22889e560f4SRandall Stewart 	uint32_t rc_prr_delivered;	/* during recovery prr var Lock(a) */
22989e560f4SRandall Stewart 	uint16_t rc_tlp_send_cnt;	/* Number of TLP sends we have done
23089e560f4SRandall Stewart 					 * since peer spoke to us Lock(a) */
23189e560f4SRandall Stewart 	uint16_t rc_tlp_seg_send_cnt;	/* Number of times we have TLP sent
23289e560f4SRandall Stewart 					 * rc_last_tlp_seq Lock(a) */
23389e560f4SRandall Stewart 
23489e560f4SRandall Stewart 	uint32_t rc_loss_count;	/* During recovery how many segments were lost
23589e560f4SRandall Stewart 				 * Lock(a) */
23689e560f4SRandall Stewart 	uint32_t rc_reorder_fade;	/* Socket option value Lock(a) */
23789e560f4SRandall Stewart 
23889e560f4SRandall Stewart 	/* Forth cache line 0xc0  */
23989e560f4SRandall Stewart 	/* Times */
24089e560f4SRandall Stewart 
24189e560f4SRandall Stewart 	uint32_t rc_rack_tmit_time;	/* Rack transmit time Lock(a) */
24289e560f4SRandall Stewart 	uint32_t rc_holes_rxt;	/* Tot retraned from scoreboard Lock(a) */
24389e560f4SRandall Stewart 
24489e560f4SRandall Stewart 	/* Variables to track bad retransmits and recover */
24589e560f4SRandall Stewart 	uint32_t rc_rsm_start;	/* RSM seq number we retransmitted Lock(a) */
24689e560f4SRandall Stewart 	uint32_t rc_cwnd_at;	/* cwnd at the retransmit Lock(a) */
24789e560f4SRandall Stewart 
24889e560f4SRandall Stewart 	uint32_t rc_ssthresh_at;/* ssthresh at the retransmit Lock(a) */
24989e560f4SRandall Stewart 	uint32_t rc_num_maps_alloced;	/* Number of map blocks (sacks) we
25089e560f4SRandall Stewart 					 * have allocated */
25189e560f4SRandall Stewart 	uint32_t rc_rcvtime;	/* When we last received data */
2525e02b277SJonathan T. Looney 	uint32_t rc_num_split_allocs;	/* num split map entries allocated */
25335c7bb34SRandall Stewart 
25489e560f4SRandall Stewart 	uint32_t rc_last_output_to;
25589e560f4SRandall Stewart 	uint32_t rc_went_idle_time;
25689e560f4SRandall Stewart 
25789e560f4SRandall Stewart 	struct rack_sendmap *rc_sacklast;	/* sack remembered place
25889e560f4SRandall Stewart 						 * Lock(a) */
25989e560f4SRandall Stewart 
26089e560f4SRandall Stewart 	struct rack_sendmap *rc_rsm_at_retran;	/* Debug variable kept for
26189e560f4SRandall Stewart 						 * cache line alignment
26289e560f4SRandall Stewart 						 * Lock(a) */
26335c7bb34SRandall Stewart 	struct timeval rc_last_ack;
26489e560f4SRandall Stewart 	/* Cache line split 0x100 */
26589e560f4SRandall Stewart 	struct sack_filter rack_sf;
26689e560f4SRandall Stewart 	/* Cache line split 0x140 */
26789e560f4SRandall Stewart 	/* Flags for various things */
26835c7bb34SRandall Stewart 	uint32_t rc_pace_max_segs;
26935c7bb34SRandall Stewart 	uint32_t rc_pace_min_segs;
27035c7bb34SRandall Stewart 	uint32_t rc_high_rwnd;
27135c7bb34SRandall Stewart 	uint32_t ack_count;
27235c7bb34SRandall Stewart 	uint32_t sack_count;
27335c7bb34SRandall Stewart 	uint32_t sack_noextra_move;
27435c7bb34SRandall Stewart 	uint32_t sack_moved_extra;
27589e560f4SRandall Stewart 	struct rack_rtt_sample rack_rs;
27635c7bb34SRandall Stewart 	uint32_t rc_tlp_rxt_last_time;
27735c7bb34SRandall Stewart 	uint32_t rc_saved_cwnd;
27835c7bb34SRandall Stewart 	uint32_t rc_gp_history[RACK_GP_HIST];
27989e560f4SRandall Stewart 	uint32_t rc_tlp_threshold;	/* Socket option value Lock(a) */
28089e560f4SRandall Stewart 	uint16_t rc_early_recovery_segs;	/* Socket option value Lock(a) */
28189e560f4SRandall Stewart 	uint16_t rc_reorder_shift;	/* Socket option value Lock(a) */
28289e560f4SRandall Stewart 	uint16_t rc_pkt_delay;	/* Socket option value Lock(a) */
28389e560f4SRandall Stewart 	uint8_t rc_prop_rate;	/* Socket option value Lock(a) */
28489e560f4SRandall Stewart 	uint8_t rc_prop_reduce;	/* Socket option value Lock(a) */
28589e560f4SRandall Stewart 	uint8_t rc_tlp_cwnd_reduce;	/* Socket option value Lock(a) */
28689e560f4SRandall Stewart 	uint8_t rc_early_recovery;	/* Socket option value Lock(a) */
28789e560f4SRandall Stewart 	uint8_t rc_prr_sendalot;/* Socket option value Lock(a) */
28889e560f4SRandall Stewart 	uint8_t rc_min_to;	/* Socket option value Lock(a) */
28989e560f4SRandall Stewart 	uint8_t rc_tlp_rtx_out;	/* This is TLPRtxOut in the draft */
29089e560f4SRandall Stewart 	uint8_t rc_rate_sample_method;
29135c7bb34SRandall Stewart 	uint8_t rc_gp_hist_idx: 7,
29235c7bb34SRandall Stewart 		rc_gp_hist_filled: 1;
29335c7bb34SRandall Stewart 
29489e560f4SRandall Stewart };
29589e560f4SRandall Stewart 
29689e560f4SRandall Stewart #ifdef _KERNEL
29789e560f4SRandall Stewart 
29889e560f4SRandall Stewart struct tcp_rack {
29989e560f4SRandall Stewart 	/* First cache line 0x00 */
30089e560f4SRandall Stewart 	TAILQ_ENTRY(tcp_rack) r_hpts;	/* hptsi queue next Lock(b) */
30189e560f4SRandall Stewart 	int32_t(*r_substate) (struct mbuf *, struct tcphdr *,
30289e560f4SRandall Stewart 	    struct socket *, struct tcpcb *, struct tcpopt *,
303*8df12ffcSMichael Tuexen 	    int32_t, int32_t, uint32_t, int, int, uint8_t);	/* Lock(a) */
30489e560f4SRandall Stewart 	struct tcpcb *rc_tp;	/* The tcpcb Lock(a) */
30589e560f4SRandall Stewart 	struct inpcb *rc_inp;	/* The inpcb Lock(a) */
30689e560f4SRandall Stewart 	uint32_t rc_free_cnt;	/* Number of free entries on the rc_free list
30789e560f4SRandall Stewart 				 * Lock(a) */
30889e560f4SRandall Stewart 	uint32_t rc_rack_rtt;	/* RACK-RTT Lock(a) */
30989e560f4SRandall Stewart 	uint16_t r_wanted_output;	/* Output routine wanted to be called */
31089e560f4SRandall Stewart 	uint16_t r_cpu;		/* CPU that the INP is running on Lock(a) */
31189e560f4SRandall Stewart 	uint16_t rc_pace_max_segs;	/* Socket option value Lock(a) */
31289e560f4SRandall Stewart 	uint16_t rc_pace_reduce;/* Socket option value Lock(a) */
31389e560f4SRandall Stewart 
31489e560f4SRandall Stewart 	uint8_t r_state;	/* Current rack state Lock(a) */
31589e560f4SRandall Stewart 	uint8_t rc_tmr_stopped : 7,
31689e560f4SRandall Stewart 		t_timers_stopped : 1;
31789e560f4SRandall Stewart 	uint8_t rc_enobuf;	/* count of enobufs on connection provides
31889e560f4SRandall Stewart 				 * backoff Lock(a) */
31989e560f4SRandall Stewart 	uint8_t r_timer_override : 1,	/* hpts override Lock(a) */
32089e560f4SRandall Stewart 		r_tlp_running : 1, 	/* Running from a TLP timeout Lock(a) */
32189e560f4SRandall Stewart 		r_is_v6 : 1,	/* V6 pcb Lock(a)  */
32289e560f4SRandall Stewart 		rc_in_persist : 1,
32389e560f4SRandall Stewart 		rc_last_pto_set : 1, /* XXX not used */
32489e560f4SRandall Stewart 		rc_tlp_in_progress : 1,
32589e560f4SRandall Stewart 		rc_always_pace : 1,	/* Socket option value Lock(a) */
32635c7bb34SRandall Stewart 		tlp_timer_up : 1;	/* The tlp timer is up flag Lock(a) */
32735c7bb34SRandall Stewart 	uint8_t r_enforce_min_pace : 2,
32835c7bb34SRandall Stewart 		rc_has_collapsed : 1,
32935c7bb34SRandall Stewart 		r_rep_attack : 1,
33035c7bb34SRandall Stewart 		r_rep_reverse : 1,
33135c7bb34SRandall Stewart 		r_xxx_min_pace_seg_thresh : 3;
33289e560f4SRandall Stewart 	uint8_t rack_tlp_threshold_use;
33389e560f4SRandall Stewart 	uint8_t rc_allow_data_af_clo: 1,
33489e560f4SRandall Stewart 		delayed_ack : 1,
33535c7bb34SRandall Stewart 		set_pacing_done_a_iw : 1,
33635c7bb34SRandall Stewart 		use_rack_cheat : 1,
3375e02b277SJonathan T. Looney 		alloc_limit_reported : 1,
33835c7bb34SRandall Stewart 		sack_attack_disable : 1,
33935c7bb34SRandall Stewart 		do_detection : 1,
34035c7bb34SRandall Stewart 		rc_avail : 1;
34135c7bb34SRandall Stewart 	uint16_t rack_per_of_gp;
34289e560f4SRandall Stewart 	/* Cache line 2 0x40 */
34389e560f4SRandall Stewart 	struct rack_control r_ctl;
34489e560f4SRandall Stewart }        __aligned(CACHE_LINE_SIZE);
34589e560f4SRandall Stewart 
34689e560f4SRandall Stewart #endif
34789e560f4SRandall Stewart #endif
348