Skip to content

Commit

Permalink
issue: 1897191 Implement extra TCP statistics
Browse files Browse the repository at this point in the history
VMA doesn't provide enough information to investigate TCP bottlenecks.

Collect more counters and metrics for a TCP connection and integrate
them into vma_stats. This statistics will help to see internals and
describe TCP behavior.

Signed-off-by: Dmytro Podgornyi <[email protected]>
  • Loading branch information
pasis committed Dec 2, 2019
1 parent eb4a79f commit a73ffb5
Show file tree
Hide file tree
Showing 12 changed files with 312 additions and 41 deletions.
14 changes: 14 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,20 @@ if test ${revision:-0} -ne 0 ; then
CXXFLAGS="-DVMA_SVN_REVISION=$revision $CXXFLAGS"
fi

# Extra TCP statistics
#
AC_ARG_ENABLE([extra-stats],
AC_HELP_STRING([--enable-extra-stats],
[Enable extra TCP statistics (default=no)]))
AC_MSG_CHECKING(
[for extra TCP statistics support])
if test "x$enable_extra_stats" = xyes; then
AC_DEFINE_UNQUOTED([DEFINED_EXTRA_STATS], [1], [Define to 1 to provide extra TCP statistics])
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi

# OFED configuration.
#
AC_MSG_CHECKING([for OFED path])
Expand Down
3 changes: 3 additions & 0 deletions src/stats/stats_data_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,12 @@ class stats_data_reader : public timer_handler
void handle_timer_expired(void *ctx);
void register_to_timer();
void add_data_reader(void* local_addr, void* shm_addr, int size);
void* find_data_reader(void* local_addr);
void* pop_data_reader(void* local_addr);

private:
void* find_data_reader_unlocked(void* local_addr);

void* m_timer_handler;
stats_read_map_t m_data_map;
lock_spin m_lock_data_map;
Expand Down
55 changes: 45 additions & 10 deletions src/stats/stats_printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void print_full_stats(socket_stats_t* p_si_stats, mc_grp_info_t* p_mc_grp_info,

if (!filename) return;

bool b_any_activiy = false;
bool b_any_activity = false;
char post_fix[3] = "";

if (user_params.print_details_mode == e_deltas)
Expand Down Expand Up @@ -143,44 +143,44 @@ void print_full_stats(socket_stats_t* p_si_stats, mc_grp_info_t* p_mc_grp_info,
if (p_si_stats->counters.n_tx_sent_byte_count || p_si_stats->counters.n_tx_sent_pkt_count || p_si_stats->counters.n_tx_drops || p_si_stats->counters.n_tx_errors)
{
fprintf(filename, "Tx Offload: %u / %u / %u / %u [kilobytes/packets/drops/errors]%s\n", p_si_stats->counters.n_tx_sent_byte_count/BYTES_TRAFFIC_UNIT,p_si_stats->counters.n_tx_sent_pkt_count, p_si_stats->counters.n_tx_drops, p_si_stats->counters.n_tx_errors, post_fix);
b_any_activiy = true;
b_any_activity = true;
}
if (p_si_stats->counters.n_tx_os_bytes || p_si_stats->counters.n_tx_os_packets || p_si_stats->counters.n_tx_os_eagain || p_si_stats->counters.n_tx_os_errors)
{
fprintf(filename, "Tx OS info: %u / %u / %u / %u [kilobytes/packets/eagains/errors]%s\n", p_si_stats->counters.n_tx_os_bytes/BYTES_TRAFFIC_UNIT, p_si_stats->counters.n_tx_os_packets, p_si_stats->counters.n_tx_os_eagain, p_si_stats->counters.n_tx_os_errors, post_fix);
b_any_activiy = true;
b_any_activity = true;
}
if (p_si_stats->counters.n_tx_dummy) {
fprintf(filename, "Tx Dummy messages : %d\n", p_si_stats->counters.n_tx_dummy);
b_any_activiy = true;
b_any_activity = true;
}
if (p_si_stats->counters.n_rx_bytes || p_si_stats->counters.n_rx_packets || p_si_stats->counters.n_rx_eagain || p_si_stats->counters.n_rx_errors)
{
fprintf(filename, "Rx Offload: %u / %u / %u / %u [kilobytes/packets/eagains/errors]%s\n", p_si_stats->counters.n_rx_bytes/BYTES_TRAFFIC_UNIT, p_si_stats->counters.n_rx_packets, p_si_stats->counters.n_rx_eagain, p_si_stats->counters.n_rx_errors, post_fix);
b_any_activiy = true;
b_any_activity = true;
}
if (p_si_stats->counters.n_rx_os_bytes || p_si_stats->counters.n_rx_os_packets || p_si_stats->counters.n_rx_os_eagain || p_si_stats->counters.n_rx_os_errors)
{
fprintf(filename, "Rx OS info: %u / %u / %u / %u [kilobytes/packets/eagains/errors]%s\n", p_si_stats->counters.n_rx_os_bytes/BYTES_TRAFFIC_UNIT, p_si_stats->counters.n_rx_os_packets, p_si_stats->counters.n_rx_os_eagain, p_si_stats->counters.n_rx_os_errors, post_fix);
b_any_activiy = true;
b_any_activity = true;
}
if (p_si_stats->counters.n_rx_packets || p_si_stats->n_rx_ready_pkt_count)
{
fprintf(filename, "Rx byte: cur %u / max %u / dropped%s %u / limit %u\n", p_si_stats->n_rx_ready_byte_count, p_si_stats->counters.n_rx_ready_byte_max, post_fix,p_si_stats->counters.n_rx_ready_byte_drop, p_si_stats->n_rx_ready_byte_limit);
fprintf(filename, "Rx pkt : cur %u / max %u / dropped%s %u\n", p_si_stats->n_rx_ready_pkt_count, p_si_stats->counters.n_rx_ready_pkt_max, post_fix,p_si_stats->counters.n_rx_ready_pkt_drop);
b_any_activiy = true;
b_any_activity = true;
}
if (p_si_stats->n_rx_zcopy_pkt_count)
{
fprintf(filename, "Rx zero copy buffers: cur %u\n", p_si_stats->n_rx_zcopy_pkt_count);
b_any_activiy = true;
b_any_activity = true;
}
if (p_si_stats->counters.n_rx_poll_miss || p_si_stats->counters.n_rx_poll_hit)
{
double rx_poll_hit = (double)p_si_stats->counters.n_rx_poll_hit;
double rx_poll_hit_percentage = (rx_poll_hit / (rx_poll_hit + (double)p_si_stats->counters.n_rx_poll_miss)) * 100;
fprintf(filename, "Rx poll: %u / %u (%2.2f%%) [miss/hit]\n", p_si_stats->counters.n_rx_poll_miss, p_si_stats->counters.n_rx_poll_hit, rx_poll_hit_percentage);
b_any_activiy = true;
b_any_activity = true;
}

if (p_si_stats->counters.n_rx_migrations || p_si_stats->counters.n_tx_migrations)
Expand All @@ -193,9 +193,44 @@ void print_full_stats(socket_stats_t* p_si_stats, mc_grp_info_t* p_mc_grp_info,
fprintf(filename, "Retransmissions: %u\n", p_si_stats->counters.n_tx_retransmits);
}

if (b_any_activiy == false) {
if (b_any_activity == false) {
fprintf(filename, "Rx and Tx where not active\n");
}

#ifdef DEFINED_EXTRA_STATS
if (p_si_stats->socket_type == SOCK_STREAM && b_any_activity) {
fprintf(filename, "TCP n_rto: %u\n", p_si_stats->tcp_stats.n_rto);
fprintf(filename, "TCP n_rtx_fast: %u\n", p_si_stats->tcp_stats.n_rtx_fast);
fprintf(filename, "TCP n_rtx_rto: %u\n", p_si_stats->tcp_stats.n_rtx_rto);
fprintf(filename, "TCP n_rtx_ss: %u\n", p_si_stats->tcp_stats.n_rtx_ss);
fprintf(filename, "TCP n_rtx_spurious: %u\n", p_si_stats->tcp_stats.n_rtx_spurious);
fprintf(filename, "TCP n_recovered_fast: %u\n", p_si_stats->tcp_stats.n_recovered_fast);
fprintf(filename, "TCP n_dupacks: %u\n", p_si_stats->tcp_stats.n_dupacks);
fprintf(filename, "TCP n_ofo: %u\n", p_si_stats->tcp_stats.n_ofo);
fprintf(filename, "TCP n_underruns: %u\n", p_si_stats->tcp_stats.n_underruns);
fprintf(filename, "TCP n_blocked_cwnd: %u\n", p_si_stats->tcp_stats.n_blocked_cwnd);
fprintf(filename, "TCP n_blocked_rwnd: %u\n", p_si_stats->tcp_stats.n_blocked_rwnd);
fprintf(filename, "TCP n_blocked_sndbuf: %u\n", p_si_stats->tcp_stats.n_blocked_sndbuf);
fprintf(filename, "TCP n_updates_rtt: %u\n", p_si_stats->tcp_stats.n_updates_rtt);
fprintf(filename, "TCP n_rst: %u\n", p_si_stats->tcp_stats.n_rst);
fprintf(filename, "TCP --------------------------------\n");
fprintf(filename, "TCP n_rx_ignored: %u\n", p_si_stats->tcp_stats.n_rx_ignored);
fprintf(filename, "TCP n_dropped: %u\n", p_si_stats->tcp_stats.n_dropped);
fprintf(filename, "TCP n_memerr_pbuf: %u\n", p_si_stats->tcp_stats.n_memerr_pbuf);
fprintf(filename, "TCP n_memerr_seg: %u\n", p_si_stats->tcp_stats.n_memerr_seg);
fprintf(filename, "TCP --------------------------------\n");
fprintf(filename, "TCP n_mss: %u\n", p_si_stats->tcp_stats.n_mss);
fprintf(filename, "TCP n_rto_timer(ms): %u\n", p_si_stats->tcp_stats.n_rto_timer);
fprintf(filename, "TCP n_snd_wnd: %u\n", p_si_stats->tcp_stats.n_snd_wnd);
fprintf(filename, "TCP n_cwnd: %u\n", p_si_stats->tcp_stats.n_cwnd);
fprintf(filename, "TCP n_ssthresh: %u\n", p_si_stats->tcp_stats.n_ssthresh);
fprintf(filename, "TCP n_snd_nxt: %u\n", p_si_stats->tcp_stats.n_snd_nxt);
fprintf(filename, "TCP n_lastack: %u\n", p_si_stats->tcp_stats.n_lastack);
fprintf(filename, "TCP n_unsent_q: %u\n", p_si_stats->tcp_stats.n_unsent_q);
fprintf(filename, "TCP n_unacked_q: %u\n", p_si_stats->tcp_stats.n_unacked_q);
fprintf(filename, "TCP n_ooseq_q: %u\n", p_si_stats->tcp_stats.n_ooseq_q);
}
#endif /* DEFINED_EXTRA_STATS */
}

// Print statistics headers for all sockets - used in case view mode is e_netstat_like
Expand Down
44 changes: 40 additions & 4 deletions src/stats/stats_publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,30 @@ void stats_data_reader::add_data_reader(void* local_addr, void* shm_addr, int si
m_lock_data_map.unlock();
}

void* stats_data_reader::find_data_reader_unlocked(void* local_addr)
{
stats_read_map_t::iterator iter = m_data_map.find(local_addr);
if (iter != m_data_map.end()) {//found
return SHM_DATA_ADDRESS;
}
return NULL;
}

void* stats_data_reader::find_data_reader(void* local_addr)
{
void* rv;
m_lock_data_map.lock();
rv = find_data_reader_unlocked(local_addr);
m_lock_data_map.unlock();
return rv;
}

void* stats_data_reader::pop_data_reader(void* local_addr)
{
void* rv = NULL;
void* rv;
m_lock_data_map.lock();
stats_read_map_t::iterator iter = m_data_map.find(local_addr);
if (iter != m_data_map.end()) {//found
rv = SHM_DATA_ADDRESS;
rv = find_data_reader_unlocked(local_addr);
if (rv) {
m_data_map.erase(local_addr);
}
m_lock_data_map.unlock();
Expand Down Expand Up @@ -381,6 +398,25 @@ void vma_stats_instance_remove_socket_block(socket_stats_t* local_addr)
g_lock_skt_inst_arr.unlock();
}

#ifdef DEFINED_EXTRA_STATS
void vma_stats_instance_add_tcp(socket_tcp_stats_t* tcp_stats_addr, socket_stats_t* stats_addr)
{
socket_stats_t* p_skt_stats;

p_skt_stats = (socket_stats_t*)g_p_stats_data_reader->find_data_reader(stats_addr);
if (p_skt_stats) {
g_p_stats_data_reader->add_data_reader(tcp_stats_addr,
&p_skt_stats->tcp_stats,
sizeof(socket_tcp_stats_t));
}
}

void vma_stats_instance_del_tcp(socket_tcp_stats_t* tcp_stats_addr)
{
(void)g_p_stats_data_reader->pop_data_reader(tcp_stats_addr);
}
#endif /* DEFINED_EXTRA_STATS */

void vma_stats_mc_group_add(in_addr_t mc_grp, socket_stats_t* p_socket_stats)
{
int empty_entry = -1;
Expand Down
92 changes: 68 additions & 24 deletions src/stats/stats_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,41 +174,85 @@ void usage(const char *argv0)
void update_delta_stat(socket_stats_t* p_curr_stat, socket_stats_t* p_prev_stat)
{
int delay = INTERVAL;
p_prev_stat->counters.n_tx_sent_byte_count = (p_curr_stat->counters.n_tx_sent_byte_count - p_prev_stat->counters.n_tx_sent_byte_count) / delay;
p_prev_stat->counters.n_tx_sent_pkt_count = (p_curr_stat->counters.n_tx_sent_pkt_count - p_prev_stat->counters.n_tx_sent_pkt_count) / delay;
p_prev_stat->counters.n_tx_drops = (p_curr_stat->counters.n_tx_drops - p_prev_stat->counters.n_tx_drops) / delay;
p_prev_stat->counters.n_tx_errors = (p_curr_stat->counters.n_tx_errors - p_prev_stat->counters.n_tx_errors) / delay;
p_prev_stat->counters.n_tx_dummy = (p_curr_stat->counters.n_tx_dummy - p_prev_stat->counters.n_tx_dummy) / delay;
p_prev_stat->counters.n_tx_os_bytes = (p_curr_stat->counters.n_tx_os_bytes - p_prev_stat->counters.n_tx_os_bytes) / delay;
p_prev_stat->counters.n_tx_os_packets = (p_curr_stat->counters.n_tx_os_packets - p_prev_stat->counters.n_tx_os_packets) / delay;
p_prev_stat->counters.n_tx_os_eagain = (p_curr_stat->counters.n_tx_os_eagain - p_prev_stat->counters.n_tx_os_eagain) / delay;
p_prev_stat->counters.n_tx_os_errors = (p_curr_stat->counters.n_tx_os_errors - p_prev_stat->counters.n_tx_os_errors) / delay;
p_prev_stat->counters.n_rx_bytes = (p_curr_stat->counters.n_rx_bytes - p_prev_stat->counters.n_rx_bytes) / delay;
p_prev_stat->counters.n_rx_packets = (p_curr_stat->counters.n_rx_packets - p_prev_stat->counters.n_rx_packets) / delay;
p_prev_stat->counters.n_rx_eagain = (p_curr_stat->counters.n_rx_eagain - p_prev_stat->counters.n_rx_eagain) / delay;
p_prev_stat->counters.n_rx_errors = (p_curr_stat->counters.n_rx_errors - p_prev_stat->counters.n_rx_errors) / delay;
p_prev_stat->counters.n_rx_os_bytes = (p_curr_stat->counters.n_rx_os_bytes - p_prev_stat->counters.n_rx_os_bytes) / delay;
p_prev_stat->counters.n_rx_os_packets = (p_curr_stat->counters.n_rx_os_packets - p_prev_stat->counters.n_rx_os_packets) / delay;
p_prev_stat->counters.n_rx_os_eagain = (p_curr_stat->counters.n_rx_os_eagain - p_prev_stat->counters.n_rx_os_eagain) / delay;
p_prev_stat->counters.n_rx_os_errors = (p_curr_stat->counters.n_rx_os_errors - p_prev_stat->counters.n_rx_os_errors) / delay;
p_prev_stat->counters.n_rx_poll_miss = (p_curr_stat->counters.n_rx_poll_miss - p_prev_stat->counters.n_rx_poll_miss) / delay;
p_prev_stat->counters.n_rx_poll_hit = (p_curr_stat->counters.n_rx_poll_hit - p_prev_stat->counters.n_rx_poll_hit) / delay;

#define STAT_DELTA(field) p_prev_stat->field = (p_curr_stat->field - p_prev_stat->field) / delay
#define STAT_COUNTERS_DELTA(field) STAT_DELTA(counters.field)
#define STAT_TCP_DELTA(field) STAT_DELTA(tcp_stats.field)

STAT_COUNTERS_DELTA(n_tx_sent_byte_count);
STAT_COUNTERS_DELTA(n_tx_sent_pkt_count);
STAT_COUNTERS_DELTA(n_tx_drops);
STAT_COUNTERS_DELTA(n_tx_errors);
STAT_COUNTERS_DELTA(n_tx_dummy);
STAT_COUNTERS_DELTA(n_tx_os_bytes);
STAT_COUNTERS_DELTA(n_tx_os_packets);
STAT_COUNTERS_DELTA(n_tx_os_eagain);
STAT_COUNTERS_DELTA(n_tx_os_errors);
STAT_COUNTERS_DELTA(n_rx_bytes);
STAT_COUNTERS_DELTA(n_rx_packets);
STAT_COUNTERS_DELTA(n_rx_eagain);
STAT_COUNTERS_DELTA(n_rx_errors);
STAT_COUNTERS_DELTA(n_rx_os_bytes);
STAT_COUNTERS_DELTA(n_rx_os_packets);
STAT_COUNTERS_DELTA(n_rx_os_eagain);
STAT_COUNTERS_DELTA(n_rx_os_errors);
STAT_COUNTERS_DELTA(n_rx_poll_miss);
STAT_COUNTERS_DELTA(n_rx_poll_hit);
p_prev_stat->n_rx_ready_byte_count = p_curr_stat->n_rx_ready_byte_count;
p_prev_stat->n_tx_ready_byte_count = p_curr_stat->n_tx_ready_byte_count;
p_prev_stat->n_rx_ready_byte_limit = p_curr_stat->n_rx_ready_byte_limit;
p_prev_stat->counters.n_rx_ready_byte_max = p_curr_stat->counters.n_rx_ready_byte_max;
p_prev_stat->counters.n_rx_ready_byte_drop = (p_curr_stat->counters.n_rx_ready_byte_drop - p_prev_stat->counters.n_rx_ready_byte_drop) / delay;
p_prev_stat->counters.n_rx_ready_pkt_drop = (p_curr_stat->counters.n_rx_ready_pkt_drop - p_prev_stat->counters.n_rx_ready_pkt_drop) / delay;
STAT_COUNTERS_DELTA(n_rx_ready_byte_drop);
STAT_COUNTERS_DELTA(n_rx_ready_pkt_drop);
p_prev_stat->n_rx_ready_pkt_count = p_curr_stat->n_rx_ready_pkt_count;
p_prev_stat->counters.n_rx_ready_pkt_max = p_curr_stat->counters.n_rx_ready_pkt_max;
p_prev_stat->n_rx_zcopy_pkt_count = p_curr_stat->n_rx_zcopy_pkt_count;

p_prev_stat->threadid_last_rx = p_curr_stat->threadid_last_rx;
p_prev_stat->threadid_last_tx = p_curr_stat->threadid_last_tx;

p_prev_stat->counters.n_rx_migrations = (p_curr_stat->counters.n_rx_migrations - p_prev_stat->counters.n_rx_migrations) / delay;
p_prev_stat->counters.n_tx_migrations = (p_curr_stat->counters.n_tx_migrations - p_prev_stat->counters.n_tx_migrations) / delay;
p_prev_stat->counters.n_tx_retransmits = (p_curr_stat->counters.n_tx_retransmits - p_prev_stat->counters.n_tx_retransmits) / delay;
STAT_COUNTERS_DELTA(n_rx_migrations);
STAT_COUNTERS_DELTA(n_tx_migrations);
STAT_COUNTERS_DELTA(n_tx_retransmits);

#ifdef DEFINED_EXTRA_STATS
if (p_curr_stat->socket_type == SOCK_STREAM) {
STAT_TCP_DELTA(n_rto);
STAT_TCP_DELTA(n_rtx_fast);
STAT_TCP_DELTA(n_rtx_rto);
STAT_TCP_DELTA(n_rtx_ss);
STAT_TCP_DELTA(n_rtx_spurious);
STAT_TCP_DELTA(n_recovered_fast);
STAT_TCP_DELTA(n_dupacks);
STAT_TCP_DELTA(n_ofo);
STAT_TCP_DELTA(n_underruns);
STAT_TCP_DELTA(n_blocked_cwnd);
STAT_TCP_DELTA(n_blocked_rwnd);
STAT_TCP_DELTA(n_blocked_sndbuf);
STAT_TCP_DELTA(n_updates_rtt);
STAT_TCP_DELTA(n_rst);

STAT_TCP_DELTA(n_rx_ignored);
STAT_TCP_DELTA(n_dropped);
STAT_TCP_DELTA(n_memerr_pbuf);
STAT_TCP_DELTA(n_memerr_seg);

p_prev_stat->tcp_stats.n_mss = p_curr_stat->tcp_stats.n_mss;
p_prev_stat->tcp_stats.n_rto_timer = p_curr_stat->tcp_stats.n_rto_timer;
p_prev_stat->tcp_stats.n_snd_wnd = p_curr_stat->tcp_stats.n_snd_wnd;
p_prev_stat->tcp_stats.n_cwnd = p_curr_stat->tcp_stats.n_cwnd;
p_prev_stat->tcp_stats.n_ssthresh = p_curr_stat->tcp_stats.n_ssthresh;
p_prev_stat->tcp_stats.n_snd_nxt = p_curr_stat->tcp_stats.n_snd_nxt;
p_prev_stat->tcp_stats.n_lastack = p_curr_stat->tcp_stats.n_lastack;
p_prev_stat->tcp_stats.n_unsent_q = p_curr_stat->tcp_stats.n_unsent_q;
p_prev_stat->tcp_stats.n_unacked_q = p_curr_stat->tcp_stats.n_unacked_q;
p_prev_stat->tcp_stats.n_ooseq_q = p_curr_stat->tcp_stats.n_ooseq_q;
}
#endif /* DEFINED_EXTRA_STATS */

#undef STAT_TCP_DELTA
#undef STAT_COUNTERS_DELTA
#undef STAT_DELTA
}

void update_delta_iomux_stat(iomux_func_stats_t* p_curr_stats, iomux_func_stats_t* p_prev_stats)
Expand Down
45 changes: 45 additions & 0 deletions src/vma/lwip/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,51 @@ void stats_display_proto(struct stats_proto *proto, char *name);
#define stats_display_proto(proto, name)
#endif /* LWIP_STATS_DISPLAY */

#ifdef DEFINED_EXTRA_STATS

struct socket_tcp_stats {
u32_t n_rto; /* number of RTO */
u32_t n_rtx_fast; /* fast retransmits */
u32_t n_rtx_rto; /* retransmits caused by RTO */
u32_t n_rtx_ss; /* retransmits in slow start phase */
u32_t n_rtx_spurious; /* number of segments removed from unsent queue */
u32_t n_recovered_fast; /* recovered after fast retransmit without RTO */
u32_t n_dupacks; /* duplicate ACKs */
u32_t n_ofo; /* out of order segments */
u32_t n_underruns; /* underruns (no segments to send) */
u32_t n_blocked_cwnd; /* sending blocked by cwnd */
u32_t n_blocked_rwnd; /* sending blocked by rwnd */
u32_t n_blocked_sndbuf; /* sending blocked by snd_buf */
u32_t n_updates_rtt; /* RTT measurements */
u32_t n_rst; /* RST segments */

u32_t n_rx_ignored; /* ignored incoming segments */
u32_t n_dropped; /* dropped segments due to an error */
u32_t n_memerr_pbuf; /* pbuf allocation errors */
u32_t n_memerr_seg; /* segment allocation errors */

u32_t n_mss;
u32_t n_rto_timer;
u32_t n_snd_wnd;
u32_t n_cwnd;
u32_t n_ssthresh;
u32_t n_snd_nxt;
u32_t n_lastack;
u32_t n_unsent_q;
u32_t n_unacked_q;
u32_t n_ooseq_q;
};

typedef struct socket_tcp_stats socket_tcp_stats_t;

#define EXTRA_STATS_INC(x) ++x

#else /* DEFINED_EXTRA_STATS */
#define EXTRA_STATS_INC(x) do {} while (0)
#endif /* DEFINED_EXTRA_STATS */

#define PCB_STATS_INC(x) EXTRA_STATS_INC(pcb->stats.x)

#ifdef __cplusplus
}
#endif
Expand Down
Loading

0 comments on commit a73ffb5

Please sign in to comment.