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. 24721fffe3SKacheong Poon */ 25721fffe3SKacheong Poon 26721fffe3SKacheong Poon #ifndef _INET_TCP_STATS_H 27721fffe3SKacheong Poon #define _INET_TCP_STATS_H 28721fffe3SKacheong Poon 29721fffe3SKacheong Poon /* 30721fffe3SKacheong Poon * TCP private kernel statistics declarations. 31721fffe3SKacheong Poon */ 32721fffe3SKacheong Poon 33721fffe3SKacheong Poon #ifdef __cplusplus 34721fffe3SKacheong Poon extern "C" { 35721fffe3SKacheong Poon #endif 36721fffe3SKacheong Poon 37721fffe3SKacheong Poon #ifdef _KERNEL 38721fffe3SKacheong Poon 39721fffe3SKacheong Poon /* 40721fffe3SKacheong Poon * TCP Statistics. 41721fffe3SKacheong Poon * 42721fffe3SKacheong Poon * How TCP statistics work. 43721fffe3SKacheong Poon * 44721fffe3SKacheong Poon * There are two types of statistics invoked by two macros. 45721fffe3SKacheong Poon * 46721fffe3SKacheong Poon * TCP_STAT(name) does non-atomic increment of a named stat counter. It is 47721fffe3SKacheong Poon * supposed to be used in non MT-hot paths of the code. 48721fffe3SKacheong Poon * 49721fffe3SKacheong Poon * TCP_DBGSTAT(name) does atomic increment of a named stat counter. It is 50721fffe3SKacheong Poon * supposed to be used for DEBUG purposes and may be used on a hot path. 51*ca3c8f41SDavid Höppner * These counters are only available in a debugged kernel. They are grouped 52721fffe3SKacheong Poon * under the TCP_DEBUG_COUNTER C pre-processor condition. 53721fffe3SKacheong Poon * 54721fffe3SKacheong Poon * Both TCP_STAT and TCP_DBGSTAT counters are available using kstat 55721fffe3SKacheong Poon * (use "kstat tcp" to get them). 56721fffe3SKacheong Poon * 57721fffe3SKacheong Poon * How to add new counters. 58721fffe3SKacheong Poon * 59721fffe3SKacheong Poon * 1) Add a field in the tcp_stat structure describing your counter. 60721fffe3SKacheong Poon * 2) Add a line in the template in tcp_kstat2_init() with the name 61721fffe3SKacheong Poon * of the counter. 62721fffe3SKacheong Poon * 3) Update tcp_clr_stats() and tcp_cp_stats() with the new counters. 63721fffe3SKacheong Poon * IMPORTANT!! - make sure that all the above functions are in sync !! 64721fffe3SKacheong Poon * 4) Use either TCP_STAT or TCP_DBGSTAT with the name. 65721fffe3SKacheong Poon * 66721fffe3SKacheong Poon * Please avoid using private counters which are not kstat-exported. 67721fffe3SKacheong Poon * 68721fffe3SKacheong Poon * Implementation note. 69721fffe3SKacheong Poon * 70721fffe3SKacheong Poon * Both the MIB2 and tcp_stat_t counters are kept per CPU in the array 71721fffe3SKacheong Poon * tcps_sc in tcp_stack_t. Each array element is a pointer to a 72721fffe3SKacheong Poon * tcp_stats_cpu_t struct. Once allocated, the tcp_stats_cpu_t struct is 73721fffe3SKacheong Poon * not freed until the tcp_stack_t is going away. So there is no need to 74721fffe3SKacheong Poon * acquire a lock before accessing the stats counters. 75721fffe3SKacheong Poon */ 76721fffe3SKacheong Poon 77721fffe3SKacheong Poon #ifndef TCP_DEBUG_COUNTER 78721fffe3SKacheong Poon #ifdef DEBUG 79721fffe3SKacheong Poon #define TCP_DEBUG_COUNTER 1 80721fffe3SKacheong Poon #else 81721fffe3SKacheong Poon #define TCP_DEBUG_COUNTER 0 82721fffe3SKacheong Poon #endif 83721fffe3SKacheong Poon #endif 84721fffe3SKacheong Poon 85721fffe3SKacheong Poon /* Kstats */ 86721fffe3SKacheong Poon typedef struct tcp_stat { 87721fffe3SKacheong Poon kstat_named_t tcp_time_wait_syn_success; 88721fffe3SKacheong Poon kstat_named_t tcp_clean_death_nondetached; 89721fffe3SKacheong Poon kstat_named_t tcp_eager_blowoff_q; 90721fffe3SKacheong Poon kstat_named_t tcp_eager_blowoff_q0; 91721fffe3SKacheong Poon kstat_named_t tcp_no_listener; 92721fffe3SKacheong Poon kstat_named_t tcp_listendrop; 93721fffe3SKacheong Poon kstat_named_t tcp_listendropq0; 94721fffe3SKacheong Poon kstat_named_t tcp_wsrv_called; 95721fffe3SKacheong Poon kstat_named_t tcp_flwctl_on; 96721fffe3SKacheong Poon kstat_named_t tcp_timer_fire_early; 97721fffe3SKacheong Poon kstat_named_t tcp_timer_fire_miss; 98721fffe3SKacheong Poon kstat_named_t tcp_zcopy_on; 99721fffe3SKacheong Poon kstat_named_t tcp_zcopy_off; 100721fffe3SKacheong Poon kstat_named_t tcp_zcopy_backoff; 101721fffe3SKacheong Poon kstat_named_t tcp_fusion_flowctl; 102721fffe3SKacheong Poon kstat_named_t tcp_fusion_backenabled; 103721fffe3SKacheong Poon kstat_named_t tcp_fusion_urg; 104721fffe3SKacheong Poon kstat_named_t tcp_fusion_putnext; 105721fffe3SKacheong Poon kstat_named_t tcp_fusion_unfusable; 106721fffe3SKacheong Poon kstat_named_t tcp_fusion_aborted; 107721fffe3SKacheong Poon kstat_named_t tcp_fusion_unqualified; 108721fffe3SKacheong Poon kstat_named_t tcp_fusion_rrw_busy; 109721fffe3SKacheong Poon kstat_named_t tcp_fusion_rrw_msgcnt; 110721fffe3SKacheong Poon kstat_named_t tcp_fusion_rrw_plugged; 111721fffe3SKacheong Poon kstat_named_t tcp_in_ack_unsent_drop; 112721fffe3SKacheong Poon kstat_named_t tcp_sock_fallback; 113721fffe3SKacheong Poon kstat_named_t tcp_lso_enabled; 114721fffe3SKacheong Poon kstat_named_t tcp_lso_disabled; 115721fffe3SKacheong Poon kstat_named_t tcp_lso_times; 116721fffe3SKacheong Poon kstat_named_t tcp_lso_pkt_out; 117721fffe3SKacheong Poon kstat_named_t tcp_listen_cnt_drop; 118721fffe3SKacheong Poon kstat_named_t tcp_listen_mem_drop; 119721fffe3SKacheong Poon kstat_named_t tcp_zwin_mem_drop; 120721fffe3SKacheong Poon kstat_named_t tcp_zwin_ack_syn; 121721fffe3SKacheong Poon kstat_named_t tcp_rst_unsent; 122721fffe3SKacheong Poon kstat_named_t tcp_reclaim_cnt; 123721fffe3SKacheong Poon kstat_named_t tcp_reass_timeout; 124721fffe3SKacheong Poon #ifdef TCP_DEBUG_COUNTER 125721fffe3SKacheong Poon kstat_named_t tcp_time_wait; 126721fffe3SKacheong Poon kstat_named_t tcp_rput_time_wait; 127721fffe3SKacheong Poon kstat_named_t tcp_detach_time_wait; 128721fffe3SKacheong Poon kstat_named_t tcp_timeout_calls; 129721fffe3SKacheong Poon kstat_named_t tcp_timeout_cached_alloc; 130721fffe3SKacheong Poon kstat_named_t tcp_timeout_cancel_reqs; 131721fffe3SKacheong Poon kstat_named_t tcp_timeout_canceled; 132721fffe3SKacheong Poon kstat_named_t tcp_timermp_freed; 133721fffe3SKacheong Poon kstat_named_t tcp_push_timer_cnt; 134721fffe3SKacheong Poon kstat_named_t tcp_ack_timer_cnt; 135721fffe3SKacheong Poon #endif 136721fffe3SKacheong Poon } tcp_stat_t; 137721fffe3SKacheong Poon 1385dd46ab5SKacheong Poon /* 1395dd46ab5SKacheong Poon * This struct contains only the counter part of tcp_stat_t. It is used 1405dd46ab5SKacheong Poon * in tcp_stats_cpu_t instead of tcp_stat_t to save memory space. 1415dd46ab5SKacheong Poon */ 1425dd46ab5SKacheong Poon typedef struct tcp_stat_counter_s { 1435dd46ab5SKacheong Poon uint64_t tcp_time_wait_syn_success; 1445dd46ab5SKacheong Poon uint64_t tcp_clean_death_nondetached; 1455dd46ab5SKacheong Poon uint64_t tcp_eager_blowoff_q; 1465dd46ab5SKacheong Poon uint64_t tcp_eager_blowoff_q0; 1475dd46ab5SKacheong Poon uint64_t tcp_no_listener; 1485dd46ab5SKacheong Poon uint64_t tcp_listendrop; 1495dd46ab5SKacheong Poon uint64_t tcp_listendropq0; 1505dd46ab5SKacheong Poon uint64_t tcp_wsrv_called; 1515dd46ab5SKacheong Poon uint64_t tcp_flwctl_on; 1525dd46ab5SKacheong Poon uint64_t tcp_timer_fire_early; 1535dd46ab5SKacheong Poon uint64_t tcp_timer_fire_miss; 1545dd46ab5SKacheong Poon uint64_t tcp_zcopy_on; 1555dd46ab5SKacheong Poon uint64_t tcp_zcopy_off; 1565dd46ab5SKacheong Poon uint64_t tcp_zcopy_backoff; 1575dd46ab5SKacheong Poon uint64_t tcp_fusion_flowctl; 1585dd46ab5SKacheong Poon uint64_t tcp_fusion_backenabled; 1595dd46ab5SKacheong Poon uint64_t tcp_fusion_urg; 1605dd46ab5SKacheong Poon uint64_t tcp_fusion_putnext; 1615dd46ab5SKacheong Poon uint64_t tcp_fusion_unfusable; 1625dd46ab5SKacheong Poon uint64_t tcp_fusion_aborted; 1635dd46ab5SKacheong Poon uint64_t tcp_fusion_unqualified; 1645dd46ab5SKacheong Poon uint64_t tcp_fusion_rrw_busy; 1655dd46ab5SKacheong Poon uint64_t tcp_fusion_rrw_msgcnt; 1665dd46ab5SKacheong Poon uint64_t tcp_fusion_rrw_plugged; 1675dd46ab5SKacheong Poon uint64_t tcp_in_ack_unsent_drop; 1685dd46ab5SKacheong Poon uint64_t tcp_sock_fallback; 1695dd46ab5SKacheong Poon uint64_t tcp_lso_enabled; 1705dd46ab5SKacheong Poon uint64_t tcp_lso_disabled; 1715dd46ab5SKacheong Poon uint64_t tcp_lso_times; 1725dd46ab5SKacheong Poon uint64_t tcp_lso_pkt_out; 1735dd46ab5SKacheong Poon uint64_t tcp_listen_cnt_drop; 1745dd46ab5SKacheong Poon uint64_t tcp_listen_mem_drop; 1755dd46ab5SKacheong Poon uint64_t tcp_zwin_mem_drop; 1765dd46ab5SKacheong Poon uint64_t tcp_zwin_ack_syn; 1775dd46ab5SKacheong Poon uint64_t tcp_rst_unsent; 1785dd46ab5SKacheong Poon uint64_t tcp_reclaim_cnt; 1795dd46ab5SKacheong Poon uint64_t tcp_reass_timeout; 1805dd46ab5SKacheong Poon #ifdef TCP_DEBUG_COUNTER 1815dd46ab5SKacheong Poon uint64_t tcp_time_wait; 1825dd46ab5SKacheong Poon uint64_t tcp_rput_time_wait; 1835dd46ab5SKacheong Poon uint64_t tcp_detach_time_wait; 1845dd46ab5SKacheong Poon uint64_t tcp_timeout_calls; 1855dd46ab5SKacheong Poon uint64_t tcp_timeout_cached_alloc; 1865dd46ab5SKacheong Poon uint64_t tcp_timeout_cancel_reqs; 1875dd46ab5SKacheong Poon uint64_t tcp_timeout_canceled; 1885dd46ab5SKacheong Poon uint64_t tcp_timermp_freed; 1895dd46ab5SKacheong Poon uint64_t tcp_push_timer_cnt; 1905dd46ab5SKacheong Poon uint64_t tcp_ack_timer_cnt; 1915dd46ab5SKacheong Poon #endif 1925dd46ab5SKacheong Poon } tcp_stat_counter_t; 1935dd46ab5SKacheong Poon 194721fffe3SKacheong Poon typedef struct tcp_g_stat { 195721fffe3SKacheong Poon kstat_named_t tcp_timermp_alloced; 196721fffe3SKacheong Poon kstat_named_t tcp_timermp_allocfail; 197721fffe3SKacheong Poon kstat_named_t tcp_timermp_allocdblfail; 198721fffe3SKacheong Poon kstat_named_t tcp_freelist_cleanup; 199721fffe3SKacheong Poon } tcp_g_stat_t; 200721fffe3SKacheong Poon 201721fffe3SKacheong Poon /* Per CPU stats: TCP MIB2, TCP kstat and connection counter. */ 202721fffe3SKacheong Poon typedef struct { 203721fffe3SKacheong Poon int64_t tcp_sc_conn_cnt; 204721fffe3SKacheong Poon mib2_tcp_t tcp_sc_mib; 2055dd46ab5SKacheong Poon tcp_stat_counter_t tcp_sc_stats; 206721fffe3SKacheong Poon } tcp_stats_cpu_t; 207721fffe3SKacheong Poon 208721fffe3SKacheong Poon #define TCPS_BUMP_MIB(tcps, x) \ 209721fffe3SKacheong Poon BUMP_MIB(&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_mib, x) 210721fffe3SKacheong Poon 211721fffe3SKacheong Poon #define TCPS_UPDATE_MIB(tcps, x, y) \ 212721fffe3SKacheong Poon UPDATE_MIB(&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_mib, x, y) 213721fffe3SKacheong Poon 214721fffe3SKacheong Poon #if TCP_DEBUG_COUNTER 215721fffe3SKacheong Poon #define TCP_DBGSTAT(tcps, x) \ 216721fffe3SKacheong Poon atomic_inc_64( \ 2175dd46ab5SKacheong Poon &((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x)) 218721fffe3SKacheong Poon #define TCP_G_DBGSTAT(x) \ 219721fffe3SKacheong Poon atomic_inc_64(&(tcp_g_statistics.x.value.ui64)) 220721fffe3SKacheong Poon #else 221721fffe3SKacheong Poon #define TCP_DBGSTAT(tcps, x) 222721fffe3SKacheong Poon #define TCP_G_DBGSTAT(x) 223721fffe3SKacheong Poon #endif 224721fffe3SKacheong Poon 225721fffe3SKacheong Poon #define TCP_G_STAT(x) (tcp_g_statistics.x.value.ui64++) 226721fffe3SKacheong Poon 227721fffe3SKacheong Poon #define TCP_STAT(tcps, x) \ 2285dd46ab5SKacheong Poon ((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x++) 229721fffe3SKacheong Poon #define TCP_STAT_UPDATE(tcps, x, n) \ 2305dd46ab5SKacheong Poon ((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x += (n)) 231721fffe3SKacheong Poon #define TCP_STAT_SET(tcps, x, n) \ 2325dd46ab5SKacheong Poon ((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x = (n)) 233721fffe3SKacheong Poon 2345dd46ab5SKacheong Poon /* Global TCP stats for all IP stacks. */ 235721fffe3SKacheong Poon extern tcp_g_stat_t tcp_g_statistics; 236721fffe3SKacheong Poon extern kstat_t *tcp_g_kstat; 237721fffe3SKacheong Poon 238721fffe3SKacheong Poon extern void *tcp_g_kstat_init(tcp_g_stat_t *); 239721fffe3SKacheong Poon extern void tcp_g_kstat_fini(kstat_t *); 240721fffe3SKacheong Poon extern void *tcp_kstat_init(netstackid_t); 241721fffe3SKacheong Poon extern void tcp_kstat_fini(netstackid_t, kstat_t *); 242721fffe3SKacheong Poon extern void *tcp_kstat2_init(netstackid_t); 243721fffe3SKacheong Poon extern void tcp_kstat2_fini(netstackid_t, kstat_t *); 244721fffe3SKacheong Poon 245721fffe3SKacheong Poon #endif /* _KERNEL */ 246721fffe3SKacheong Poon 247721fffe3SKacheong Poon #ifdef __cplusplus 248721fffe3SKacheong Poon } 249721fffe3SKacheong Poon #endif 250721fffe3SKacheong Poon 251721fffe3SKacheong Poon #endif /* _INET_TCP_STATS_H */ 252