Date: Tue, 15 Mar 2016 00:15:10 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r296881 - in head: contrib/bsnmp/snmp_mibII sys/netinet Message-ID: <201603150015.u2F0FATD089432@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Tue Mar 15 00:15:10 2016 New Revision: 296881 URL: https://svnweb.freebsd.org/changeset/base/296881 Log: Redo r294869. The array of counters for TCP states doesn't belong to struct tcpstat, because the structure can be zeroed out by netstat(1) -z, and of course running connection counts shouldn't be touched. Place running connection counts into separate array, and provide separate read-only sysctl oid for it. Modified: head/contrib/bsnmp/snmp_mibII/mibII_tcp.c head/sys/netinet/tcp_input.c head/sys/netinet/tcp_subr.c head/sys/netinet/tcp_syncache.c head/sys/netinet/tcp_timewait.c head/sys/netinet/tcp_usrreq.c head/sys/netinet/tcp_var.h Modified: head/contrib/bsnmp/snmp_mibII/mibII_tcp.c ============================================================================== --- head/contrib/bsnmp/snmp_mibII/mibII_tcp.c Tue Mar 15 00:05:00 2016 (r296880) +++ head/contrib/bsnmp/snmp_mibII/mibII_tcp.c Tue Mar 15 00:15:10 2016 (r296881) @@ -47,6 +47,7 @@ struct tcp_index { static uint64_t tcp_tick; static uint64_t tcp_stats_tick; static struct tcpstat tcpstat; +static uint64_t tcps_states[TCP_NSTATES]; static struct xinpgen *xinpgen; static size_t xinpgen_len; static u_int tcp_total; @@ -78,6 +79,17 @@ fetch_tcp_stats(void) return (-1); } + len = sizeof(tcps_states); + if (sysctlbyname("net.inet.tcp.states", &tcps_states, &len, NULL, + 0) == -1) { + syslog(LOG_ERR, "net.inet.tcp.states: %m"); + return (-1); + } + if (len != sizeof(tcps_states)) { + syslog(LOG_ERR, "net.inet.tcp.states: wrong size"); + return (-1); + } + tcp_stats_tick = get_ticks(); return (0); @@ -231,8 +243,8 @@ op_tcp(struct snmp_context *ctx __unused break; case LEAF_tcpCurrEstab: - value->v.uint32 = tcpstat.tcps_states[TCPS_ESTABLISHED] + - tcpstat.tcps_states[TCPS_CLOSE_WAIT]; + value->v.uint32 = tcps_states[TCPS_ESTABLISHED] + + tcps_states[TCPS_CLOSE_WAIT]; break; case LEAF_tcpInSegs: Modified: head/sys/netinet/tcp_input.c ============================================================================== --- head/sys/netinet/tcp_input.c Tue Mar 15 00:05:00 2016 (r296880) +++ head/sys/netinet/tcp_input.c Tue Mar 15 00:15:10 2016 (r296881) @@ -235,16 +235,39 @@ VNET_DEFINE(struct inpcbhead, tcb); VNET_DEFINE(struct inpcbinfo, tcbinfo); /* - * TCP statistics are stored in an "array" of counter(9)s. + * TCP statistics are stored in an array of counter(9)s, which size matches + * size of struct tcpstat. TCP running connection count is a regular array. */ VNET_PCPUSTAT_DEFINE(struct tcpstat, tcpstat); -VNET_PCPUSTAT_SYSINIT(tcpstat); SYSCTL_VNET_PCPUSTAT(_net_inet_tcp, TCPCTL_STATS, stats, struct tcpstat, tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)"); +VNET_DEFINE(counter_u64_t, tcps_states[TCP_NSTATES]); +SYSCTL_COUNTER_U64_ARRAY(_net_inet_tcp, TCPCTL_STATES, states, CTLFLAG_RD | + CTLFLAG_VNET, &VNET_NAME(tcps_states), TCP_NSTATES, + "TCP connection counts by TCP state"); + +static void +tcp_vnet_init(const void *unused) +{ + + COUNTER_ARRAY_ALLOC(VNET(tcps_states), TCP_NSTATES, M_WAITOK); + VNET_PCPUSTAT_ALLOC(tcpstat, M_WAITOK); +} +VNET_SYSINIT(tcp_vnet_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, + tcp_vnet_init, NULL); #ifdef VIMAGE -VNET_PCPUSTAT_SYSUNINIT(tcpstat); +static void +tcp_vnet_uninit(const void *unused) +{ + + COUNTER_ARRAY_FREE(VNET(tcps_states), TCP_NSTATES); + VNET_PCPUSTAT_FREE(tcpstat); +} +VNET_SYSUNINIT(tcp_vnet_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, + tcp_vnet_uninit, NULL); #endif /* VIMAGE */ + /* * Kernel module interface for updating tcpstat. The argument is an index * into tcpstat treated as an array. Modified: head/sys/netinet/tcp_subr.c ============================================================================== --- head/sys/netinet/tcp_subr.c Tue Mar 15 00:05:00 2016 (r296880) +++ head/sys/netinet/tcp_subr.c Tue Mar 15 00:15:10 2016 (r296881) @@ -1542,7 +1542,7 @@ tcp_close(struct tcpcb *tp) #endif in_pcbdrop(inp); TCPSTAT_INC(tcps_closed); - TCPSTAT_DEC(tcps_states[tp->t_state]); + TCPSTATES_DEC(tp->t_state); KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL")); so = inp->inp_socket; soisdisconnected(so); @@ -1665,7 +1665,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS) */ if (req->oldptr == NULL) { n = V_tcbinfo.ipi_count + - TCPSTAT_FETCH(tcps_states[TCPS_SYN_RECEIVED]); + counter_u64_fetch(VNET(tcps_states)[TCPS_SYN_RECEIVED]); n += imax(n / 8, 10); req->oldidx = 2 * (sizeof xig) + n * sizeof(struct xtcpcb); return (0); @@ -1682,7 +1682,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS) n = V_tcbinfo.ipi_count; INP_LIST_RUNLOCK(&V_tcbinfo); - m = TCPSTAT_FETCH(tcps_states[TCPS_SYN_RECEIVED]); + m = counter_u64_fetch(VNET(tcps_states)[TCPS_SYN_RECEIVED]); error = sysctl_wire_old_buffer(req, 2 * (sizeof xig) + (n + m) * sizeof(struct xtcpcb)); @@ -2986,8 +2986,8 @@ tcp_state_change(struct tcpcb *tp, int n int pstate = tp->t_state; #endif - TCPSTAT_DEC(tcps_states[tp->t_state]); - TCPSTAT_INC(tcps_states[newstate]); + TCPSTATES_DEC(tp->t_state); + TCPSTATES_INC(newstate); tp->t_state = newstate; TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, pstate); } Modified: head/sys/netinet/tcp_syncache.c ============================================================================== --- head/sys/netinet/tcp_syncache.c Tue Mar 15 00:05:00 2016 (r296880) +++ head/sys/netinet/tcp_syncache.c Tue Mar 15 00:15:10 2016 (r296881) @@ -351,7 +351,7 @@ syncache_insert(struct syncache *sc, str SCH_UNLOCK(sch); - TCPSTAT_INC(tcps_states[TCPS_SYN_RECEIVED]); + TCPSTATES_INC(TCPS_SYN_RECEIVED); TCPSTAT_INC(tcps_sc_added); } @@ -365,7 +365,7 @@ syncache_drop(struct syncache *sc, struc SCH_LOCK_ASSERT(sch); - TCPSTAT_DEC(tcps_states[TCPS_SYN_RECEIVED]); + TCPSTATES_DEC(TCPS_SYN_RECEIVED); TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash); sch->sch_length--; @@ -1003,7 +1003,7 @@ syncache_expand(struct in_conninfo *inc, * sonewconn->tcp_usr_attach in TCPS_CLOSED state, then * syncache_socket() will change it to TCPS_SYN_RECEIVED. */ - TCPSTAT_DEC(tcps_states[TCPS_SYN_RECEIVED]); + TCPSTATES_DEC(TCPS_SYN_RECEIVED); TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash); sch->sch_length--; #ifdef TCP_OFFLOAD Modified: head/sys/netinet/tcp_timewait.c ============================================================================== --- head/sys/netinet/tcp_timewait.c Tue Mar 15 00:05:00 2016 (r296880) +++ head/sys/netinet/tcp_timewait.c Tue Mar 15 00:15:10 2016 (r296881) @@ -660,7 +660,7 @@ tcp_tw_2msl_stop(struct tcptw *tw, int r if (!reuse) uma_zfree(V_tcptw_zone, tw); - TCPSTAT_DEC(tcps_states[TCPS_TIME_WAIT]); + TCPSTATES_DEC(TCPS_TIME_WAIT); } struct tcptw * Modified: head/sys/netinet/tcp_usrreq.c ============================================================================== --- head/sys/netinet/tcp_usrreq.c Tue Mar 15 00:05:00 2016 (r296880) +++ head/sys/netinet/tcp_usrreq.c Tue Mar 15 00:15:10 2016 (r296881) @@ -1883,7 +1883,7 @@ tcp_attach(struct socket *so) tp->t_state = TCPS_CLOSED; INP_WUNLOCK(inp); INP_INFO_RUNLOCK(&V_tcbinfo); - TCPSTAT_INC(tcps_states[TCPS_CLOSED]); + TCPSTATES_INC(TCPS_CLOSED); return (0); } Modified: head/sys/netinet/tcp_var.h ============================================================================== --- head/sys/netinet/tcp_var.h Tue Mar 15 00:05:00 2016 (r296880) +++ head/sys/netinet/tcp_var.h Tue Mar 15 00:15:10 2016 (r296881) @@ -588,9 +588,6 @@ struct tcpstat { uint64_t tcps_sig_err_sigopt; /* No signature expected by socket */ uint64_t tcps_sig_err_nosigopt; /* No signature provided by segment */ - /* Running connection count. */ - uint64_t tcps_states[TCP_NSTATES]; - uint64_t _pad[12]; /* 6 UTO, 6 TBD */ }; @@ -609,9 +606,6 @@ VNET_PCPUSTAT_DECLARE(struct tcpstat, tc #define TCPSTAT_ADD(name, val) \ VNET_PCPUSTAT_ADD(struct tcpstat, tcpstat, name, (val)) #define TCPSTAT_INC(name) TCPSTAT_ADD(name, 1) -#define TCPSTAT_DEC(name) TCPSTAT_ADD(name, -1) -#define TCPSTAT_FETCH(name) VNET_PCPUSTAT_FETCH(struct tcpstat, tcpstat, \ - name) /* * Kernel module consumers must use this accessor macro. @@ -621,6 +615,13 @@ void kmod_tcpstat_inc(int statnum); kmod_tcpstat_inc(offsetof(struct tcpstat, name) / sizeof(uint64_t)) /* + * Running TCP connection count by state. + */ +VNET_DECLARE(counter_u64_t, tcps_states[TCP_NSTATES]); +#define TCPSTATES_INC(state) counter_u64_add(VNET(tcps_states)[state], 1) +#define TCPSTATES_DEC(state) counter_u64_add(VNET(tcps_states)[state], -1) + +/* * TCP specific helper hook point identifiers. */ #define HHOOK_TCP_EST_IN 0 @@ -678,6 +679,7 @@ struct xtcpcb { #define TCPCTL_V6MSSDFLT 13 /* MSS default for IPv6 */ #define TCPCTL_SACK 14 /* Selective Acknowledgement,rfc 2018 */ #define TCPCTL_DROP 15 /* drop tcp connection */ +#define TCPCTL_STATES 16 /* connection counts by TCP state */ #ifdef _KERNEL #ifdef SYSCTL_DECL
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201603150015.u2F0FATD089432>