1721fffe3SKacheong Poon /* 2721fffe3SKacheong Poon * CDDL HEADER START 3721fffe3SKacheong Poon * 4721fffe3SKacheong Poon * The contents of this file are subject to the terms of the 5721fffe3SKacheong Poon * Common Development and Distribution License (the "License"). 6721fffe3SKacheong Poon * You may not use this file except in compliance with the License. 7721fffe3SKacheong Poon * 8721fffe3SKacheong Poon * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9721fffe3SKacheong Poon * or http://www.opensolaris.org/os/licensing. 10721fffe3SKacheong Poon * See the License for the specific language governing permissions 11721fffe3SKacheong Poon * and limitations under the License. 12721fffe3SKacheong Poon * 13721fffe3SKacheong Poon * When distributing Covered Code, include this CDDL HEADER in each 14721fffe3SKacheong Poon * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15721fffe3SKacheong Poon * If applicable, add the following below this CDDL HEADER, with the 16721fffe3SKacheong Poon * fields enclosed by brackets "[]" replaced with your own identifying 17721fffe3SKacheong Poon * information: Portions Copyright [yyyy] [name of copyright owner] 18721fffe3SKacheong Poon * 19721fffe3SKacheong Poon * CDDL HEADER END 20721fffe3SKacheong Poon */ 215dd46ab5SKacheong Poon 22721fffe3SKacheong Poon /* 235dd46ab5SKacheong Poon * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24a2f04351SSebastien Roy * Copyright (c) 2015 by Delphix. All rights reserved. 25*1edba515SAndy Fiddaman * Copyright 2024 Oxide Computer Company 26721fffe3SKacheong Poon */ 27721fffe3SKacheong Poon 28721fffe3SKacheong Poon #ifndef _INET_TCP_STATS_H 29721fffe3SKacheong Poon #define _INET_TCP_STATS_H 30721fffe3SKacheong Poon 31721fffe3SKacheong Poon /* 32721fffe3SKacheong Poon * TCP private kernel statistics declarations. 33721fffe3SKacheong Poon */ 34721fffe3SKacheong Poon 35721fffe3SKacheong Poon #ifdef __cplusplus 36721fffe3SKacheong Poon extern "C" { 37721fffe3SKacheong Poon #endif 38721fffe3SKacheong Poon 39721fffe3SKacheong Poon #ifdef _KERNEL 40721fffe3SKacheong Poon 41721fffe3SKacheong Poon /* 42721fffe3SKacheong Poon * TCP Statistics. 43721fffe3SKacheong Poon * 44721fffe3SKacheong Poon * How TCP statistics work. 45721fffe3SKacheong Poon * 46721fffe3SKacheong Poon * There are two types of statistics invoked by two macros. 47721fffe3SKacheong Poon * 48721fffe3SKacheong Poon * TCP_STAT(name) does non-atomic increment of a named stat counter. It is 49721fffe3SKacheong Poon * supposed to be used in non MT-hot paths of the code. 50721fffe3SKacheong Poon * 51721fffe3SKacheong Poon * TCP_DBGSTAT(name) does atomic increment of a named stat counter. It is 52721fffe3SKacheong Poon * supposed to be used for DEBUG purposes and may be used on a hot path. 53ca3c8f41SDavid Höppner * These counters are only available in a debugged kernel. They are grouped 54721fffe3SKacheong Poon * under the TCP_DEBUG_COUNTER C pre-processor condition. 55721fffe3SKacheong Poon * 56721fffe3SKacheong Poon * Both TCP_STAT and TCP_DBGSTAT counters are available using kstat 57721fffe3SKacheong Poon * (use "kstat tcp" to get them). 58721fffe3SKacheong Poon * 59721fffe3SKacheong Poon * How to add new counters. 60721fffe3SKacheong Poon * 61721fffe3SKacheong Poon * 1) Add a field in the tcp_stat structure describing your counter. 62721fffe3SKacheong Poon * 2) Add a line in the template in tcp_kstat2_init() with the name 63721fffe3SKacheong Poon * of the counter. 64721fffe3SKacheong Poon * 3) Update tcp_clr_stats() and tcp_cp_stats() with the new counters. 65721fffe3SKacheong Poon * IMPORTANT!! - make sure that all the above functions are in sync !! 66721fffe3SKacheong Poon * 4) Use either TCP_STAT or TCP_DBGSTAT with the name. 67721fffe3SKacheong Poon * 68721fffe3SKacheong Poon * Please avoid using private counters which are not kstat-exported. 69721fffe3SKacheong Poon * 70721fffe3SKacheong Poon * Implementation note. 71721fffe3SKacheong Poon * 72721fffe3SKacheong Poon * Both the MIB2 and tcp_stat_t counters are kept per CPU in the array 73721fffe3SKacheong Poon * tcps_sc in tcp_stack_t. Each array element is a pointer to a 74721fffe3SKacheong Poon * tcp_stats_cpu_t struct. Once allocated, the tcp_stats_cpu_t struct is 75721fffe3SKacheong Poon * not freed until the tcp_stack_t is going away. So there is no need to 76721fffe3SKacheong Poon * acquire a lock before accessing the stats counters. 77721fffe3SKacheong Poon */ 78721fffe3SKacheong Poon 79721fffe3SKacheong Poon #ifndef TCP_DEBUG_COUNTER 80721fffe3SKacheong Poon #ifdef DEBUG 81721fffe3SKacheong Poon #define TCP_DEBUG_COUNTER 1 82721fffe3SKacheong Poon #else 83721fffe3SKacheong Poon #define TCP_DEBUG_COUNTER 0 84721fffe3SKacheong Poon #endif 85721fffe3SKacheong Poon #endif 86721fffe3SKacheong Poon 87721fffe3SKacheong Poon /* Kstats */ 88721fffe3SKacheong Poon typedef struct tcp_stat { 89721fffe3SKacheong Poon kstat_named_t tcp_time_wait_syn_success; 90721fffe3SKacheong Poon kstat_named_t tcp_clean_death_nondetached; 91721fffe3SKacheong Poon kstat_named_t tcp_eager_blowoff_q; 92721fffe3SKacheong Poon kstat_named_t tcp_eager_blowoff_q0; 93721fffe3SKacheong Poon kstat_named_t tcp_no_listener; 94721fffe3SKacheong Poon kstat_named_t tcp_listendrop; 95721fffe3SKacheong Poon kstat_named_t tcp_listendropq0; 965dd46ab5SKacheong Poon kstat_named_t tcp_wsrv_called; 975dd46ab5SKacheong Poon kstat_named_t tcp_flwctl_on; 98721fffe3SKacheong Poon kstat_named_t tcp_timer_fire_early; 99721fffe3SKacheong Poon kstat_named_t tcp_timer_fire_miss; 100721fffe3SKacheong Poon kstat_named_t tcp_zcopy_on; 101721fffe3SKacheong Poon kstat_named_t tcp_zcopy_off; 102721fffe3SKacheong Poon kstat_named_t tcp_zcopy_backoff; 103721fffe3SKacheong Poon kstat_named_t tcp_fusion_flowctl; 104721fffe3SKacheong Poon kstat_named_t tcp_fusion_backenabled; 105721fffe3SKacheong Poon kstat_named_t tcp_fusion_urg; 106721fffe3SKacheong Poon kstat_named_t tcp_fusion_putnext; 107721fffe3SKacheong Poon kstat_named_t tcp_fusion_unfusable; 108721fffe3SKacheong Poon kstat_named_t tcp_fusion_aborted; 109721fffe3SKacheong Poon kstat_named_t tcp_fusion_unqualified; 110721fffe3SKacheong Poon kstat_named_t tcp_fusion_rrw_busy; 111721fffe3SKacheong Poon kstat_named_t tcp_fusion_rrw_msgcnt; 112721fffe3SKacheong Poon kstat_named_t tcp_fusion_rrw_plugged; 113721fffe3SKacheong Poon kstat_named_t tcp_in_ack_unsent_drop; 114721fffe3SKacheong Poon kstat_named_t tcp_sock_fallback; 115721fffe3SKacheong Poon kstat_named_t tcp_lso_enabled; 116721fffe3SKacheong Poon kstat_named_t tcp_lso_disabled; 117721fffe3SKacheong Poon kstat_named_t tcp_lso_times; 118721fffe3SKacheong Poon kstat_named_t tcp_lso_pkt_out; 119721fffe3SKacheong Poon kstat_named_t tcp_listen_cnt_drop; 120721fffe3SKacheong Poon kstat_named_t tcp_listen_mem_drop; 121721fffe3SKacheong Poon kstat_named_t tcp_zwin_mem_drop; 122721fffe3SKacheong Poon kstat_named_t tcp_zwin_ack_syn; 123721fffe3SKacheong Poon kstat_named_t tcp_rst_unsent; 124721fffe3SKacheong Poon kstat_named_t tcp_reclaim_cnt; 125721fffe3SKacheong Poon kstat_named_t tcp_reass_timeout; 126*1edba515SAndy Fiddaman kstat_named_t tcp_sig_no_option; 127*1edba515SAndy Fiddaman kstat_named_t tcp_sig_no_space; 128*1edba515SAndy Fiddaman kstat_named_t tcp_sig_match_failed; 129*1edba515SAndy Fiddaman kstat_named_t tcp_sig_verify_failed; 130721fffe3SKacheong Poon #ifdef TCP_DEBUG_COUNTER 131721fffe3SKacheong Poon kstat_named_t tcp_time_wait; 132721fffe3SKacheong Poon kstat_named_t tcp_rput_time_wait; 133721fffe3SKacheong Poon kstat_named_t tcp_detach_time_wait; 134721fffe3SKacheong Poon kstat_named_t tcp_timeout_calls; 135721fffe3SKacheong Poon kstat_named_t tcp_timeout_cached_alloc; 136721fffe3SKacheong Poon kstat_named_t tcp_timeout_cancel_reqs; 137721fffe3SKacheong Poon kstat_named_t tcp_timeout_canceled; 138721fffe3SKacheong Poon kstat_named_t tcp_timermp_freed; 139721fffe3SKacheong Poon kstat_named_t tcp_push_timer_cnt; 140721fffe3SKacheong Poon kstat_named_t tcp_ack_timer_cnt; 141721fffe3SKacheong Poon #endif 142721fffe3SKacheong Poon } tcp_stat_t; 143721fffe3SKacheong Poon 1445dd46ab5SKacheong Poon /* 1455dd46ab5SKacheong Poon * This struct contains only the counter part of tcp_stat_t. It is used 1465dd46ab5SKacheong Poon * in tcp_stats_cpu_t instead of tcp_stat_t to save memory space. 1475dd46ab5SKacheong Poon */ 1485dd46ab5SKacheong Poon typedef struct tcp_stat_counter_s { 1495dd46ab5SKacheong Poon uint64_t tcp_time_wait_syn_success; 1505dd46ab5SKacheong Poon uint64_t tcp_clean_death_nondetached; 1515dd46ab5SKacheong Poon uint64_t tcp_eager_blowoff_q; 1525dd46ab5SKacheong Poon uint64_t tcp_eager_blowoff_q0; 1535dd46ab5SKacheong Poon uint64_t tcp_no_listener; 1545dd46ab5SKacheong Poon uint64_t tcp_listendrop; 1555dd46ab5SKacheong Poon uint64_t tcp_listendropq0; 1565dd46ab5SKacheong Poon uint64_t tcp_wsrv_called; 1575dd46ab5SKacheong Poon uint64_t tcp_flwctl_on; 1585dd46ab5SKacheong Poon uint64_t tcp_timer_fire_early; 1595dd46ab5SKacheong Poon uint64_t tcp_timer_fire_miss; 1605dd46ab5SKacheong Poon uint64_t tcp_zcopy_on; 1615dd46ab5SKacheong Poon uint64_t tcp_zcopy_off; 1625dd46ab5SKacheong Poon uint64_t tcp_zcopy_backoff; 1635dd46ab5SKacheong Poon uint64_t tcp_fusion_flowctl; 1645dd46ab5SKacheong Poon uint64_t tcp_fusion_backenabled; 1655dd46ab5SKacheong Poon uint64_t tcp_fusion_urg; 1665dd46ab5SKacheong Poon uint64_t tcp_fusion_putnext; 1675dd46ab5SKacheong Poon uint64_t tcp_fusion_unfusable; 1685dd46ab5SKacheong Poon uint64_t tcp_fusion_aborted; 1695dd46ab5SKacheong Poon uint64_t tcp_fusion_unqualified; 1705dd46ab5SKacheong Poon uint64_t tcp_fusion_rrw_busy; 1715dd46ab5SKacheong Poon uint64_t tcp_fusion_rrw_msgcnt; 1725dd46ab5SKacheong Poon uint64_t tcp_fusion_rrw_plugged; 1735dd46ab5SKacheong Poon uint64_t tcp_in_ack_unsent_drop; 1745dd46ab5SKacheong Poon uint64_t tcp_sock_fallback; 1755dd46ab5SKacheong Poon uint64_t tcp_lso_enabled; 1765dd46ab5SKacheong Poon uint64_t tcp_lso_disabled; 1775dd46ab5SKacheong Poon uint64_t tcp_lso_times; 1785dd46ab5SKacheong Poon uint64_t tcp_lso_pkt_out; 1795dd46ab5SKacheong Poon uint64_t tcp_listen_cnt_drop; 1805dd46ab5SKacheong Poon uint64_t tcp_listen_mem_drop; 1815dd46ab5SKacheong Poon uint64_t tcp_zwin_mem_drop; 1825dd46ab5SKacheong Poon uint64_t tcp_zwin_ack_syn; 1835dd46ab5SKacheong Poon uint64_t tcp_rst_unsent; 1845dd46ab5SKacheong Poon uint64_t tcp_reclaim_cnt; 1855dd46ab5SKacheong Poon uint64_t tcp_reass_timeout; 186*1edba515SAndy Fiddaman uint64_t tcp_sig_no_option; 187*1edba515SAndy Fiddaman uint64_t tcp_sig_no_space; 188*1edba515SAndy Fiddaman uint64_t tcp_sig_match_failed; 189*1edba515SAndy Fiddaman uint64_t tcp_sig_verify_failed; 1905dd46ab5SKacheong Poon #ifdef TCP_DEBUG_COUNTER 1915dd46ab5SKacheong Poon uint64_t tcp_time_wait; 1925dd46ab5SKacheong Poon uint64_t tcp_rput_time_wait; 1935dd46ab5SKacheong Poon uint64_t tcp_detach_time_wait; 1945dd46ab5SKacheong Poon uint64_t tcp_timeout_calls; 1955dd46ab5SKacheong Poon uint64_t tcp_timeout_cached_alloc; 1965dd46ab5SKacheong Poon uint64_t tcp_timeout_cancel_reqs; 1975dd46ab5SKacheong Poon uint64_t tcp_timeout_canceled; 1985dd46ab5SKacheong Poon uint64_t tcp_timermp_freed; 1995dd46ab5SKacheong Poon uint64_t tcp_push_timer_cnt; 2005dd46ab5SKacheong Poon uint64_t tcp_ack_timer_cnt; 2015dd46ab5SKacheong Poon #endif 2025dd46ab5SKacheong Poon } tcp_stat_counter_t; 2035dd46ab5SKacheong Poon 204721fffe3SKacheong Poon typedef struct tcp_g_stat { 205721fffe3SKacheong Poon kstat_named_t tcp_timermp_alloced; 206721fffe3SKacheong Poon kstat_named_t tcp_timermp_allocfail; 207721fffe3SKacheong Poon kstat_named_t tcp_timermp_allocdblfail; 208721fffe3SKacheong Poon kstat_named_t tcp_freelist_cleanup; 209721fffe3SKacheong Poon } tcp_g_stat_t; 210721fffe3SKacheong Poon 211721fffe3SKacheong Poon /* Per CPU stats: TCP MIB2, TCP kstat and connection counter. */ 212721fffe3SKacheong Poon typedef struct { 2135dd46ab5SKacheong Poon int64_t tcp_sc_conn_cnt; 2145dd46ab5SKacheong Poon mib2_tcp_t tcp_sc_mib; 2155dd46ab5SKacheong Poon tcp_stat_counter_t tcp_sc_stats; 216721fffe3SKacheong Poon } tcp_stats_cpu_t; 217721fffe3SKacheong Poon 218a2f04351SSebastien Roy /* 219a2f04351SSebastien Roy * Per-connection statistics. Some of these are also kept globally in the 220a2f04351SSebastien Roy * per-cpu tcp_sc_mib entry (see tcp_stats_cpu_t above). We need not maintain 221a2f04351SSebastien Roy * per-cpu versions of these stats since a connection is typically processed 222a2f04351SSebastien Roy * on the same CPU. 223a2f04351SSebastien Roy */ 224a2f04351SSebastien Roy typedef struct tcp_conn_stats { 225a2f04351SSebastien Roy uint64_t tcp_in_data_inorder_bytes; 226a2f04351SSebastien Roy uint64_t tcp_in_data_inorder_segs; 227a2f04351SSebastien Roy uint64_t tcp_in_data_unorder_bytes; 228a2f04351SSebastien Roy uint64_t tcp_in_data_unorder_segs; 229a2f04351SSebastien Roy uint64_t tcp_in_zwnd_probes; 230a2f04351SSebastien Roy 231a2f04351SSebastien Roy uint64_t tcp_out_data_bytes; 232a2f04351SSebastien Roy uint64_t tcp_out_data_segs; 233a2f04351SSebastien Roy uint64_t tcp_out_retrans_bytes; 234a2f04351SSebastien Roy uint64_t tcp_out_retrans_segs; 235a2f04351SSebastien Roy uint64_t tcp_out_zwnd_probes; 236a2f04351SSebastien Roy } tcp_conn_stats_t; 237a2f04351SSebastien Roy 238721fffe3SKacheong Poon #define TCPS_BUMP_MIB(tcps, x) \ 239721fffe3SKacheong Poon BUMP_MIB(&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_mib, x) 240721fffe3SKacheong Poon 241721fffe3SKacheong Poon #define TCPS_UPDATE_MIB(tcps, x, y) \ 242721fffe3SKacheong Poon UPDATE_MIB(&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_mib, x, y) 243721fffe3SKacheong Poon 244721fffe3SKacheong Poon #if TCP_DEBUG_COUNTER 245721fffe3SKacheong Poon #define TCP_DBGSTAT(tcps, x) \ 246721fffe3SKacheong Poon atomic_inc_64( \ 2475dd46ab5SKacheong Poon &((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x)) 248721fffe3SKacheong Poon #define TCP_G_DBGSTAT(x) \ 249721fffe3SKacheong Poon atomic_inc_64(&(tcp_g_statistics.x.value.ui64)) 250721fffe3SKacheong Poon #else 251721fffe3SKacheong Poon #define TCP_DBGSTAT(tcps, x) 252721fffe3SKacheong Poon #define TCP_G_DBGSTAT(x) 253721fffe3SKacheong Poon #endif 254721fffe3SKacheong Poon 255721fffe3SKacheong Poon #define TCP_G_STAT(x) (tcp_g_statistics.x.value.ui64++) 256721fffe3SKacheong Poon 257721fffe3SKacheong Poon #define TCP_STAT(tcps, x) \ 2585dd46ab5SKacheong Poon ((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x++) 259721fffe3SKacheong Poon #define TCP_STAT_UPDATE(tcps, x, n) \ 2605dd46ab5SKacheong Poon ((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x += (n)) 261721fffe3SKacheong Poon #define TCP_STAT_SET(tcps, x, n) \ 2625dd46ab5SKacheong Poon ((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x = (n)) 263721fffe3SKacheong Poon 2645dd46ab5SKacheong Poon /* Global TCP stats for all IP stacks. */ 265721fffe3SKacheong Poon extern tcp_g_stat_t tcp_g_statistics; 266721fffe3SKacheong Poon extern kstat_t *tcp_g_kstat; 267721fffe3SKacheong Poon 268721fffe3SKacheong Poon extern void *tcp_g_kstat_init(tcp_g_stat_t *); 269721fffe3SKacheong Poon extern void tcp_g_kstat_fini(kstat_t *); 270721fffe3SKacheong Poon extern void *tcp_kstat_init(netstackid_t); 271721fffe3SKacheong Poon extern void tcp_kstat_fini(netstackid_t, kstat_t *); 272721fffe3SKacheong Poon extern void *tcp_kstat2_init(netstackid_t); 273721fffe3SKacheong Poon extern void tcp_kstat2_fini(netstackid_t, kstat_t *); 274721fffe3SKacheong Poon 275721fffe3SKacheong Poon #endif /* _KERNEL */ 276721fffe3SKacheong Poon 277721fffe3SKacheong Poon #ifdef __cplusplus 278721fffe3SKacheong Poon } 279721fffe3SKacheong Poon #endif 280721fffe3SKacheong Poon 281721fffe3SKacheong Poon #endif /* _INET_TCP_STATS_H */ 282