svn commit: r296881 - in head: contrib/bsnmp/snmp_mibII sys/netinet

Gleb Smirnoff glebius at FreeBSD.org
Tue Mar 15 00:15:12 UTC 2016


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


More information about the svn-src-all mailing list