90 memset (bts, 0xfc,
sizeof (*bts));
146 while (seq != cur->
key)
284 u32 available_bytes, flight_size;
290 if (available_bytes + flight_size + tc->snd_mss < tc->cwnd
292 && tc->sack_sb.lost_bytes <= tc->snd_rxt_bytes)
293 tc->app_limited = tc->delivered + flight_size ? : 1;
304 if (tail && tail->
max_seq == tc->snd_nxt
311 if (tc->snd_una == tc->snd_nxt)
314 tc->first_tx_time = tc->delivered_time;
322 tail->
next = bts_index;
324 bt->
tail = bts_index;
337 u32 bts_index, cur_index, next_index, prev_index, max_seq;
338 u8 is_end = end == tc->snd_nxt;
343 if (bts && bts->
max_seq == start
357 bts_flags = bts->
flags;
368 prev_index = bts->
prev;
377 cur->
next = next_index;
378 cur->
prev = prev_index;
385 next->
prev = cur_index;
389 bt->
tail = cur_index;
395 prev->
next = cur_index;
399 bt->
head = cur_index;
419 cur->
prev = bts_index;
423 if (
seq_lt (end, max_seq))
455 next->
prev = cur_index;
458 bt->
tail = cur_index;
461 bts->
next = cur_index;
482 tc->first_tx_time = bts->
tx_time;
512 for (i = 0; i <
vec_len (blks); i++)
517 if (
seq_lt (blk->end, tc->snd_una))
593 delivered = tc->bytes_acked + tc->sack_sb.last_sacked_bytes;
595 delivered -= tc->sack_sb.last_bytes_delivered;
599 tc->delivered += delivered;
602 if (tc->app_limited && tc->delivered > tc->app_limited)
608 if (tc->sack_sb.last_sacked_bytes)
615 rs->
lost = tc->sack_sb.last_lost_bytes;
623 u32 *samples = 0, *si;
630 vec_add1 (samples, bts - bt->samples);
673 s =
format (s,
"[%u, %u] d %u dt %.3f txt %.3f ftxt %.3f flags 0x%x",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static tcp_bt_sample_t * bt_next_sample(tcp_byte_tracker_t *bt, tcp_bt_sample_t *bts)
rb_node_t * rb_tree_predecessor(rb_tree_t *rt, rb_node_t *x)
f64 tx_time
Transmit time for the burst.
#define TCP_BTS_INVALID_INDEX
static f64 tcp_time_now_us(u32 thread_index)
u8 * format_tcp_bt_sample(u8 *s, va_list *args)
#define seq_leq(_s1, _s2)
struct _sack_block sack_block_t
int tcp_bt_is_sane(tcp_byte_tracker_t *bt)
Check if the byte tracker is in sane state.
u8 * format_tcp_bt(u8 *s, va_list *args)
u32 prev
Previous sample index in list.
f64 first_tx_time
Connection first tx time at tx.
static tcp_bt_sample_t * bt_split_sample(tcp_byte_tracker_t *bt, tcp_bt_sample_t *bts, u32 seq)
static rb_node_t * rb_node_left(rb_tree_t *rt, rb_node_t *n)
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
static void bt_free_sample(tcp_byte_tracker_t *bt, tcp_bt_sample_t *bts)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
enum tcp_bts_flags_ tcp_bts_flags_t
static tcp_bt_sample_t * bt_lookup_seq(tcp_byte_tracker_t *bt, u32 seq)
f64 prior_time
Delivered time of sample used for rate.
static rb_node_t * rb_node(rb_tree_t *rt, rb_node_index_t ri)
struct _tcp_connection tcp_connection_t
static rb_node_t * rb_node_right(rb_tree_t *rt, rb_node_t *n)
u32 head
Head of samples linked list.
void rb_tree_free_nodes(rb_tree_t *rt)
static void tcp_bt_sample_to_rate_sample(tcp_connection_t *tc, tcp_bt_sample_t *bts, tcp_rate_sample_t *rs)
static void tcp_bt_walk_samples(tcp_connection_t *tc, tcp_rate_sample_t *rs)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static tcp_bt_sample_t * bt_prev_sample(tcp_byte_tracker_t *bt, tcp_bt_sample_t *bts)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
void tcp_bt_sample_delivery_rate(tcp_connection_t *tc, tcp_rate_sample_t *rs)
Generate a delivery rate sample from recently acked bytes.
static tcp_bt_sample_t * bt_alloc_sample(tcp_byte_tracker_t *bt, u32 min_seq, u32 max_seq)
static tcp_bt_sample_t * bt_get_sample(tcp_byte_tracker_t *bt, u32 bts_index)
u32 max_seq
Max seq number.
void tcp_bt_init(tcp_connection_t *tc)
Byte tracker initialize.
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
u32 delivered
Bytes delivered in interval_time.
uword opaque
value stored by node
rb_tree_t sample_lookup
Rbtree for sample lookup by min_seq.
tcp_bt_sample_t * samples
Pool of samples.
f64 interval_time
Time to ack the bytes delivered.
void tcp_bt_cleanup(tcp_connection_t *tc)
Byte tracker cleanup.
#define pool_put(P, E)
Free an object E in pool P.
static u32 tcp_flight_size(const tcp_connection_t *tc)
Our estimate of the number of bytes in flight (pipe size)
void rb_tree_init(rb_tree_t *rt)
u32 next
Next sample index in list.
tcp_bts_flags_t flags
Sample flag.
f64 delivered_time
Delivered time when sample taken.
#define pool_free(p)
Free a pool.
void tcp_bt_track_tx(tcp_connection_t *tc, u32 len)
Track a tcp tx burst.
#define vec_free(V)
Free vector's memory (no header).
#define clib_warning(format, args...)
static u32 bt_sample_index(tcp_byte_tracker_t *bt, tcp_bt_sample_t *bts)
f64 rtt_time
RTT for sample.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
static int bt_seq_lt(u32 a, u32 b)
static u32 transport_max_tx_dequeue(transport_connection_t *tc)
void tcp_bt_check_app_limited(tcp_connection_t *tc)
Check if sample to be generated is app limited.
void tcp_bt_track_rxt(tcp_connection_t *tc, u32 start, u32 end)
Track a tcp retransmission.
#define seq_geq(_s1, _s2)
static tcp_bt_sample_t * bt_merge_sample(tcp_byte_tracker_t *bt, tcp_bt_sample_t *prev, tcp_bt_sample_t *cur)
void rb_tree_del_custom(rb_tree_t *rt, u32 key, rb_tree_lt_fn ltfn)
static void clib_mem_free(void *p)
u32 last_ooo
Cached last ooo sample.
static void * clib_mem_alloc(uword size)
u64 delivered
Total delivered bytes for sample.
static u8 rb_node_is_tnil(rb_tree_t *rt, rb_node_t *n)
u32 tail
Tail of samples linked list.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void bt_update_sample(tcp_byte_tracker_t *bt, tcp_bt_sample_t *bts, u32 seq)
u32 min_seq
Min seq number in sample.
void tcp_bt_flush_samples(tcp_connection_t *tc)
Flush byte tracker samples.
u64 prior_delivered
Delivered of sample used for rate, i.e., total bytes delivered at prior_time.
static tcp_bt_sample_t * bt_fix_overlapped(tcp_byte_tracker_t *bt, tcp_bt_sample_t *start, u32 seq, u8 is_end)
#define vec_foreach(var, vec)
Vector iterator.
rb_node_t * nodes
pool of nodes
rb_node_index_t rb_tree_add_custom(rb_tree_t *rt, u32 key, uword opaque, rb_tree_lt_fn ltfn)
tcp_bts_flags_t flags
Rate sample flags from bt sample.
static tcp_bt_sample_t * tcp_bt_alloc_tx_sample(tcp_connection_t *tc, u32 min_seq, u32 max_seq)
static void tcp_bt_walk_samples_ooo(tcp_connection_t *tc, tcp_rate_sample_t *rs)
rb_node_index_t root
root index
u32 acked_and_sacked
Bytes acked + sacked now.
static uword pool_elts(void *v)
Number of active elements in a pool.