1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _INET_TCP_STATS_H 27 #define _INET_TCP_STATS_H 28 29 /* 30 * TCP private kernel statistics declarations. 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #ifdef _KERNEL 38 39 /* 40 * TCP Statistics. 41 * 42 * How TCP statistics work. 43 * 44 * There are two types of statistics invoked by two macros. 45 * 46 * TCP_STAT(name) does non-atomic increment of a named stat counter. It is 47 * supposed to be used in non MT-hot paths of the code. 48 * 49 * TCP_DBGSTAT(name) does atomic increment of a named stat counter. It is 50 * supposed to be used for DEBUG purposes and may be used on a hot path. 51 * These counters are only available in a debugged kerel. They are grouped 52 * under the TCP_DEBUG_COUNTER C pre-processor condition. 53 * 54 * Both TCP_STAT and TCP_DBGSTAT counters are available using kstat 55 * (use "kstat tcp" to get them). 56 * 57 * How to add new counters. 58 * 59 * 1) Add a field in the tcp_stat structure describing your counter. 60 * 2) Add a line in the template in tcp_kstat2_init() with the name 61 * of the counter. 62 * 3) Update tcp_clr_stats() and tcp_cp_stats() with the new counters. 63 * IMPORTANT!! - make sure that all the above functions are in sync !! 64 * 4) Use either TCP_STAT or TCP_DBGSTAT with the name. 65 * 66 * Please avoid using private counters which are not kstat-exported. 67 * 68 * Implementation note. 69 * 70 * Both the MIB2 and tcp_stat_t counters are kept per CPU in the array 71 * tcps_sc in tcp_stack_t. Each array element is a pointer to a 72 * tcp_stats_cpu_t struct. Once allocated, the tcp_stats_cpu_t struct is 73 * not freed until the tcp_stack_t is going away. So there is no need to 74 * acquire a lock before accessing the stats counters. 75 */ 76 77 #ifndef TCP_DEBUG_COUNTER 78 #ifdef DEBUG 79 #define TCP_DEBUG_COUNTER 1 80 #else 81 #define TCP_DEBUG_COUNTER 0 82 #endif 83 #endif 84 85 /* Kstats */ 86 typedef struct tcp_stat { 87 kstat_named_t tcp_time_wait_syn_success; 88 kstat_named_t tcp_clean_death_nondetached; 89 kstat_named_t tcp_eager_blowoff_q; 90 kstat_named_t tcp_eager_blowoff_q0; 91 kstat_named_t tcp_no_listener; 92 kstat_named_t tcp_listendrop; 93 kstat_named_t tcp_listendropq0; 94 kstat_named_t tcp_wsrv_called; 95 kstat_named_t tcp_flwctl_on; 96 kstat_named_t tcp_timer_fire_early; 97 kstat_named_t tcp_timer_fire_miss; 98 kstat_named_t tcp_zcopy_on; 99 kstat_named_t tcp_zcopy_off; 100 kstat_named_t tcp_zcopy_backoff; 101 kstat_named_t tcp_fusion_flowctl; 102 kstat_named_t tcp_fusion_backenabled; 103 kstat_named_t tcp_fusion_urg; 104 kstat_named_t tcp_fusion_putnext; 105 kstat_named_t tcp_fusion_unfusable; 106 kstat_named_t tcp_fusion_aborted; 107 kstat_named_t tcp_fusion_unqualified; 108 kstat_named_t tcp_fusion_rrw_busy; 109 kstat_named_t tcp_fusion_rrw_msgcnt; 110 kstat_named_t tcp_fusion_rrw_plugged; 111 kstat_named_t tcp_in_ack_unsent_drop; 112 kstat_named_t tcp_sock_fallback; 113 kstat_named_t tcp_lso_enabled; 114 kstat_named_t tcp_lso_disabled; 115 kstat_named_t tcp_lso_times; 116 kstat_named_t tcp_lso_pkt_out; 117 kstat_named_t tcp_listen_cnt_drop; 118 kstat_named_t tcp_listen_mem_drop; 119 kstat_named_t tcp_zwin_mem_drop; 120 kstat_named_t tcp_zwin_ack_syn; 121 kstat_named_t tcp_rst_unsent; 122 kstat_named_t tcp_reclaim_cnt; 123 kstat_named_t tcp_reass_timeout; 124 #ifdef TCP_DEBUG_COUNTER 125 kstat_named_t tcp_time_wait; 126 kstat_named_t tcp_rput_time_wait; 127 kstat_named_t tcp_detach_time_wait; 128 kstat_named_t tcp_timeout_calls; 129 kstat_named_t tcp_timeout_cached_alloc; 130 kstat_named_t tcp_timeout_cancel_reqs; 131 kstat_named_t tcp_timeout_canceled; 132 kstat_named_t tcp_timermp_freed; 133 kstat_named_t tcp_push_timer_cnt; 134 kstat_named_t tcp_ack_timer_cnt; 135 #endif 136 } tcp_stat_t; 137 138 typedef struct tcp_g_stat { 139 kstat_named_t tcp_timermp_alloced; 140 kstat_named_t tcp_timermp_allocfail; 141 kstat_named_t tcp_timermp_allocdblfail; 142 kstat_named_t tcp_freelist_cleanup; 143 } tcp_g_stat_t; 144 145 /* Per CPU stats: TCP MIB2, TCP kstat and connection counter. */ 146 typedef struct { 147 int64_t tcp_sc_conn_cnt; 148 mib2_tcp_t tcp_sc_mib; 149 tcp_stat_t tcp_sc_stats; 150 } tcp_stats_cpu_t; 151 152 #define TCPS_BUMP_MIB(tcps, x) \ 153 BUMP_MIB(&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_mib, x) 154 155 #define TCPS_UPDATE_MIB(tcps, x, y) \ 156 UPDATE_MIB(&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_mib, x, y) 157 158 #if TCP_DEBUG_COUNTER 159 #define TCP_DBGSTAT(tcps, x) \ 160 atomic_inc_64( \ 161 &((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x.value.ui64)) 162 #define TCP_G_DBGSTAT(x) \ 163 atomic_inc_64(&(tcp_g_statistics.x.value.ui64)) 164 #else 165 #define TCP_DBGSTAT(tcps, x) 166 #define TCP_G_DBGSTAT(x) 167 #endif 168 169 #define TCP_G_STAT(x) (tcp_g_statistics.x.value.ui64++) 170 171 #define TCP_STAT(tcps, x) \ 172 ((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x.value.ui64++) 173 #define TCP_STAT_UPDATE(tcps, x, n) \ 174 ((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x.value.ui64 += (n)) 175 #define TCP_STAT_SET(tcps, x, n) \ 176 ((tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_stats.x.value.ui64 = (n)) 177 178 extern tcp_g_stat_t tcp_g_statistics; 179 extern kstat_t *tcp_g_kstat; 180 181 extern void *tcp_g_kstat_init(tcp_g_stat_t *); 182 extern void tcp_g_kstat_fini(kstat_t *); 183 extern void *tcp_kstat_init(netstackid_t); 184 extern void tcp_kstat_fini(netstackid_t, kstat_t *); 185 extern void *tcp_kstat2_init(netstackid_t); 186 extern void tcp_kstat2_fini(netstackid_t, kstat_t *); 187 188 #endif /* _KERNEL */ 189 190 #ifdef __cplusplus 191 } 192 #endif 193 194 #endif /* _INET_TCP_STATS_H */ 195