svn commit: r253083 - in head: sys/netinet usr.bin/netstat

Andrey V. Elsukov ae at FreeBSD.org
Tue Jul 9 09:43:05 UTC 2013


Author: ae
Date: Tue Jul  9 09:43:03 2013
New Revision: 253083
URL: http://svnweb.freebsd.org/changeset/base/253083

Log:
  Use new macros to implement ipstat and tcpstat using PCPU counters.
  Change interface of kread_counters() similar ot kread() in the netstat(1).

Modified:
  head/sys/netinet/ip_input.c
  head/sys/netinet/ip_var.h
  head/sys/netinet/tcp_input.c
  head/sys/netinet/tcp_var.h
  head/usr.bin/netstat/inet.c
  head/usr.bin/netstat/main.c
  head/usr.bin/netstat/netstat.h

Modified: head/sys/netinet/ip_input.c
==============================================================================
--- head/sys/netinet/ip_input.c	Tue Jul  9 09:37:21 2013	(r253082)
+++ head/sys/netinet/ip_input.c	Tue Jul  9 09:43:03 2013	(r253083)
@@ -208,73 +208,17 @@ SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, 
 static void	ip_freef(struct ipqhead *, struct ipq *);
 
 /*
- * IP statistics are stored in struct ipstat_p, which is
- * an "array" of counter(9)s.  Although it isn't a real
- * array, we treat it as array to reduce code bloat.
+ * IP statistics are stored in the "array" of counter(9)s.
  */
-VNET_DEFINE(struct ipstat_p, ipstatp);
-
-static void
-vnet_ipstatp_init(const void *unused)
-{
-	counter_u64_t *c;
-	int i;
-
-	for (i = 0, c = (counter_u64_t *)&V_ipstatp;
-	    i < sizeof(V_ipstatp) / sizeof(counter_u64_t);
-	    i++, c++) {
-		*c = counter_u64_alloc(M_WAITOK);
-		counter_u64_zero(*c);
-	}
-}
-VNET_SYSINIT(vnet_ipstatp_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
-            vnet_ipstatp_init, NULL);
+VNET_PCPUSTAT_DEFINE(struct ipstat, ipstat);
+VNET_PCPUSTAT_SYSINIT(ipstat);
+SYSCTL_VNET_PCPUSTAT(_net_inet_ip, IPCTL_STATS, stats, struct ipstat, ipstat,
+    "IP statistics (struct ipstat, netinet/ip_var.h)");
 
 #ifdef VIMAGE
-static void
-vnet_ipstatp_uninit(const void *unused)
-{
-	counter_u64_t *c;
-	int i;
-
-	for (i = 0, c = (counter_u64_t *)&V_ipstatp;
-	    i < sizeof(V_ipstatp) / sizeof(counter_u64_t);
-	    i++, c++)
-		counter_u64_free(*c);
-}
-VNET_SYSUNINIT(vnet_ipstatp_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
-            vnet_ipstatp_uninit, NULL);
+VNET_PCPUSTAT_SYSUNINIT(ipstat);
 #endif /* VIMAGE */
 
-static int
-ipstat_sysctl(SYSCTL_HANDLER_ARGS)
-{
-	struct ipstat ipstat;
-	counter_u64_t *c;
-	uint64_t *v;
-	int i;
-
-	for (i = 0, c = (counter_u64_t *)&V_ipstatp, v = (uint64_t *)&ipstat;
-	    i < sizeof(V_ipstatp) / sizeof(counter_u64_t);
-	    i++, c++, v++) {
-		*v = counter_u64_fetch(*c);
-		/*
-		 * Old interface allowed to rewrite 'struct ipstat', and
-		 * netstat(1) used it to zero the structure. To keep
-		 * compatibility with old netstat(1) we will zero out
-		 * statistics on every write attempt, however we no longer
-		 * support writing arbitrary fake values to the statistics.
-		 */
-		if (req->newptr)
-			counter_u64_zero(*c);
-	}
-
-	return (SYSCTL_OUT(req, &ipstat, sizeof(ipstat)));
-}
-SYSCTL_VNET_PROC(_net_inet_ip, IPCTL_STATS, stats, CTLTYPE_OPAQUE | CTLFLAG_RW,
-    NULL, 0, ipstat_sysctl, "I",
-    "IP statistics (struct ipstat, netinet/ip_var.h)");
-
 /*
  * Kernel module interface for updating ipstat.  The argument is an index
  * into ipstat treated as an array.
@@ -283,14 +227,14 @@ void
 kmod_ipstat_inc(int statnum)
 {
 
-	counter_u64_add(*((counter_u64_t *)&V_ipstatp + statnum), 1);
+	counter_u64_add(VNET(ipstat)[statnum], 1);
 }
 
 void
 kmod_ipstat_dec(int statnum)
 {
 
-	counter_u64_add(*((counter_u64_t *)&V_ipstatp + statnum), -1);
+	counter_u64_add(VNET(ipstat)[statnum], -1);
 }
 
 static int

Modified: head/sys/netinet/ip_var.h
==============================================================================
--- head/sys/netinet/ip_var.h	Tue Jul  9 09:37:21 2013	(r253082)
+++ head/sys/netinet/ip_var.h	Tue Jul  9 09:43:03 2013	(r253083)
@@ -133,46 +133,13 @@ struct	ipstat {
 #include <sys/counter.h>
 #include <net/vnet.h>
 
-/* Should match 'struct ipstat' above. */
-struct ipstat_p {
-	counter_u64_t ips_total;
-	counter_u64_t ips_badsum;
-	counter_u64_t ips_tooshort;
-	counter_u64_t ips_toosmall;
-	counter_u64_t ips_badhlen;
-	counter_u64_t ips_badlen;
-	counter_u64_t ips_fragments;
-	counter_u64_t ips_fragdropped;
-	counter_u64_t ips_fragtimeout;
-	counter_u64_t ips_forward;
-	counter_u64_t ips_fastforward;
-	counter_u64_t ips_cantforward;
-	counter_u64_t ips_redirectsent;
-	counter_u64_t ips_noproto;
-	counter_u64_t ips_delivered;
-	counter_u64_t ips_localout;
-	counter_u64_t ips_odropped;
-	counter_u64_t ips_reassembled;
-	counter_u64_t ips_fragmented;
-	counter_u64_t ips_ofragments;
-	counter_u64_t ips_cantfrag;
-	counter_u64_t ips_badoptions;
-	counter_u64_t ips_noroute;
-	counter_u64_t ips_badvers;
-	counter_u64_t ips_rawout;
-	counter_u64_t ips_toolong;
-	counter_u64_t ips_notmember;
-	counter_u64_t ips_nogif;
-	counter_u64_t ips_badaddr;
-};
-VNET_DECLARE(struct ipstat_p, ipstatp);
-#define	V_ipstatp VNET(ipstatp)
-
+VNET_PCPUSTAT_DECLARE(struct ipstat, ipstat);
 /*
  * In-kernel consumers can use these accessor macros directly to update
  * stats.
  */
-#define	IPSTAT_ADD(name, val)	counter_u64_add(V_ipstatp.name, (val))
+#define	IPSTAT_ADD(name, val)	\
+    VNET_PCPUSTAT_ADD(struct ipstat, ipstat, name, (val))
 #define	IPSTAT_SUB(name, val)	IPSTAT_ADD(name, -(val))
 #define	IPSTAT_INC(name)	IPSTAT_ADD(name, 1)
 #define	IPSTAT_DEC(name)	IPSTAT_SUB(name, 1)
@@ -181,11 +148,11 @@ VNET_DECLARE(struct ipstat_p, ipstatp);
  * Kernel module consumers must use this accessor macro.
  */
 void	kmod_ipstat_inc(int statnum);
-#define	KMOD_IPSTAT_INC(name)						\
-	kmod_ipstat_inc(offsetof(struct ipstat_p, name) / sizeof(counter_u64_t))
+#define	KMOD_IPSTAT_INC(name)	\
+    kmod_ipstat_inc(offsetof(struct ipstat, name) / sizeof(uint64_t))
 void	kmod_ipstat_dec(int statnum);
-#define	KMOD_IPSTAT_DEC(name)						\
-	kmod_ipstat_dec(offsetof(struct ipstat_p, name) / sizeof(counter_u64_t))
+#define	KMOD_IPSTAT_DEC(name)	\
+    kmod_ipstat_dec(offsetof(struct ipstat, name) / sizeof(uint64_t))
 
 /* flags passed to ip_output as last parameter */
 #define	IP_FORWARDING		0x1		/* most of ip header exists */

Modified: head/sys/netinet/tcp_input.c
==============================================================================
--- head/sys/netinet/tcp_input.c	Tue Jul  9 09:37:21 2013	(r253082)
+++ head/sys/netinet/tcp_input.c	Tue Jul  9 09:43:03 2013	(r253083)
@@ -240,67 +240,16 @@ static void inline	hhook_run_tcp_est_in(
 			    struct tcphdr *th, struct tcpopt *to);
 
 /*
- * TCP statistics are stored in struct tcpstat_p, which is
- * an "array" of counter(9)s.  Although it isn't a real
- * array, we treat it as array to reduce code bloat.
+ * TCP statistics are stored in an "array" of counter(9)s.
  */
-VNET_DEFINE(struct tcpstat_p, tcpstatp);
-
-static void
-vnet_tcpstatp_init(const void *unused)
-{
-	counter_u64_t *c;
-	int i;
-
-	for (i = 0, c = (counter_u64_t *)&V_tcpstatp;
-	    i < sizeof(V_tcpstatp) / sizeof(counter_u64_t);
-	    i++, c++) {
-		*c = counter_u64_alloc(M_WAITOK);
-		counter_u64_zero(*c);
-	}
-}
-VNET_SYSINIT(vnet_tcpstatp_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
-	    vnet_tcpstatp_init, NULL);
+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)");
 
 #ifdef VIMAGE
-static void
-vnet_tcpstatp_uninit(const void *unused)
-{
-	counter_u64_t *c;
-	int i;
-
-	for (i = 0, c = (counter_u64_t *)&V_tcpstatp;
-	    i < sizeof(V_tcpstatp) / sizeof(counter_u64_t);
-	    i++, c++)
-		counter_u64_free(*c);
-}
-VNET_SYSUNINIT(vnet_tcpstatp_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
-	    vnet_tcpstatp_uninit, NULL);
+VNET_PCPUSTAT_SYSUNINIT(tcpstat);
 #endif /* VIMAGE */
-
-static int
-tcpstat_sysctl(SYSCTL_HANDLER_ARGS)
-{
-	struct tcpstat tcpstat;
-	counter_u64_t *c;
-	uint64_t *v;
-	int i;
-
-	for (i = 0, c = (counter_u64_t *)&V_tcpstatp, v = (uint64_t *)&tcpstat;
-	    i < sizeof(V_tcpstatp) / sizeof(counter_u64_t);
-	    i++, c++, v++) {
-		*v = counter_u64_fetch(*c);
-		if (req->newptr)
-			counter_u64_zero(*c);
-	}
-
-	return (SYSCTL_OUT(req, &tcpstat, sizeof(tcpstat)));
-}
-
-SYSCTL_VNET_PROC(_net_inet_tcp, TCPCTL_STATS, stats, CTLTYPE_OPAQUE |
-    CTLFLAG_RW, NULL, 0, tcpstat_sysctl, "I", 
-    "TCP statistics (struct tcpstat, netinet/tcp_var.h)");
-
 /*
  * Kernel module interface for updating tcpstat.  The argument is an index
  * into tcpstat treated as an array.
@@ -309,7 +258,7 @@ void
 kmod_tcpstat_inc(int statnum)
 {
 
-	counter_u64_add(*((counter_u64_t *)&V_tcpstatp + statnum), 1);
+	counter_u64_add(VNET(tcpstat)[statnum], 1);
 }
 
 /*

Modified: head/sys/netinet/tcp_var.h
==============================================================================
--- head/sys/netinet/tcp_var.h	Tue Jul  9 09:37:21 2013	(r253082)
+++ head/sys/netinet/tcp_var.h	Tue Jul  9 09:43:03 2013	(r253083)
@@ -514,119 +514,15 @@ struct	tcpstat {
 };
 
 #ifdef _KERNEL
-
 #include <sys/counter.h>
 
-/* Should match 'struct tcpstat' above. */
-struct tcpstat_p {
-	counter_u64_t tcps_connattempt;
-	counter_u64_t tcps_accepts;
-	counter_u64_t tcps_connects;
-	counter_u64_t tcps_drops;
-	counter_u64_t tcps_conndrops;
-	counter_u64_t tcps_minmssdrops;
-	counter_u64_t tcps_closed;
-	counter_u64_t tcps_segstimed;
-	counter_u64_t tcps_rttupdated;
-	counter_u64_t tcps_delack;
-	counter_u64_t tcps_timeoutdrop;
-	counter_u64_t tcps_rexmttimeo;
-	counter_u64_t tcps_persisttimeo;
-	counter_u64_t tcps_keeptimeo;
-	counter_u64_t tcps_keepprobe;
-	counter_u64_t tcps_keepdrops;
-	counter_u64_t tcps_sndtotal;
-	counter_u64_t tcps_sndpack;
-	counter_u64_t tcps_sndbyte;
-	counter_u64_t tcps_sndrexmitpack;
-	counter_u64_t tcps_sndrexmitbyte;
-	counter_u64_t tcps_sndrexmitbad;
-	counter_u64_t tcps_sndacks;
-	counter_u64_t tcps_sndprobe;
-	counter_u64_t tcps_sndurg;
-	counter_u64_t tcps_sndwinup;
-	counter_u64_t tcps_sndctrl;
-	counter_u64_t tcps_rcvtotal;
-	counter_u64_t tcps_rcvpack;
-	counter_u64_t tcps_rcvbyte;
-	counter_u64_t tcps_rcvbadsum;
-	counter_u64_t tcps_rcvbadoff;
-	counter_u64_t tcps_rcvmemdrop;
-	counter_u64_t tcps_rcvshort;
-	counter_u64_t tcps_rcvduppack;
-	counter_u64_t tcps_rcvdupbyte;
-	counter_u64_t tcps_rcvpartduppack;
-	counter_u64_t tcps_rcvpartdupbyte;
-	counter_u64_t tcps_rcvoopack;
-	counter_u64_t tcps_rcvoobyte;
-	counter_u64_t tcps_rcvpackafterwin;
-	counter_u64_t tcps_rcvbyteafterwin;
-	counter_u64_t tcps_rcvafterclose;
-	counter_u64_t tcps_rcvwinprobe;
-	counter_u64_t tcps_rcvdupack;
-	counter_u64_t tcps_rcvacktoomuch;
-	counter_u64_t tcps_rcvackpack;
-	counter_u64_t tcps_rcvackbyte;
-	counter_u64_t tcps_rcvwinupd;
-	counter_u64_t tcps_pawsdrop;
-	counter_u64_t tcps_predack;
-	counter_u64_t tcps_preddat;
-	counter_u64_t tcps_pcbcachemiss;
-	counter_u64_t tcps_cachedrtt;
-	counter_u64_t tcps_cachedrttvar;
-	counter_u64_t tcps_cachedssthresh;
-	counter_u64_t tcps_usedrtt;
-	counter_u64_t tcps_usedrttvar;
-	counter_u64_t tcps_usedssthresh;
-	counter_u64_t tcps_persistdrop;
-	counter_u64_t tcps_badsyn;
-	counter_u64_t tcps_mturesent;
-	counter_u64_t tcps_listendrop;
-	counter_u64_t tcps_badrst;
-	counter_u64_t tcps_sc_added;
-	counter_u64_t tcps_sc_retransmitted;
-	counter_u64_t tcps_sc_dupsyn;
-	counter_u64_t tcps_sc_dropped;
-	counter_u64_t tcps_sc_completed;
-	counter_u64_t tcps_sc_bucketoverflow;
-	counter_u64_t tcps_sc_cacheoverflow;
-	counter_u64_t tcps_sc_reset;
-	counter_u64_t tcps_sc_stale;
-	counter_u64_t tcps_sc_aborted;
-	counter_u64_t tcps_sc_badack;
-	counter_u64_t tcps_sc_unreach;
-	counter_u64_t tcps_sc_zonefail;
-	counter_u64_t tcps_sc_sendcookie;
-	counter_u64_t tcps_sc_recvcookie;
-	counter_u64_t tcps_hc_added;
-	counter_u64_t tcps_hc_bucketoverflow;
-	counter_u64_t tcps_finwait2_drops;
-	counter_u64_t tcps_sack_recovery_episode;
-	counter_u64_t tcps_sack_rexmits;
-	counter_u64_t tcps_sack_rexmit_bytes;
-	counter_u64_t tcps_sack_rcv_blocks;
-	counter_u64_t tcps_sack_send_blocks;
-	counter_u64_t tcps_sack_sboverflow;
-	counter_u64_t tcps_ecn_ce;
-	counter_u64_t tcps_ecn_ect0;
-	counter_u64_t tcps_ecn_ect1;
-	counter_u64_t tcps_ecn_shs;
-	counter_u64_t tcps_ecn_rcwnd;
-	counter_u64_t tcps_sig_rcvgoodsig;
-	counter_u64_t tcps_sig_rcvbadsig;
-	counter_u64_t tcps_sig_err_buildsig;
-	counter_u64_t tcps_sig_err_sigopt;
-	counter_u64_t tcps_sig_err_nosigopt;
-};
-
-VNET_DECLARE(struct tcpstat_p, tcpstatp);	/* tcp statistics */
-#define	V_tcpstatp VNET(tcpstatp)
-
+VNET_PCPUSTAT_DECLARE(struct tcpstat, tcpstat);	/* tcp statistics */
 /*
  * In-kernel consumers can use these accessor macros directly to update
  * stats.
  */
-#define	TCPSTAT_ADD(name, val)	counter_u64_add(V_tcpstatp.name, (val))
+#define	TCPSTAT_ADD(name, val)	\
+    VNET_PCPUSTAT_ADD(struct tcpstat, tcpstat, name, (val))
 #define	TCPSTAT_INC(name)	TCPSTAT_ADD(name, 1)
 
 /*
@@ -634,8 +530,7 @@ VNET_DECLARE(struct tcpstat_p, tcpstatp)
  */
 void	kmod_tcpstat_inc(int statnum);
 #define	KMOD_TCPSTAT_INC(name)						\
-	kmod_tcpstat_inc(offsetof(struct tcpstat_p, name) /		\
-	sizeof(counter_u64_t))
+    kmod_tcpstat_inc(offsetof(struct tcpstat, name) / sizeof(uint64_t))
 
 /*
  * TCP specific helper hook point identifiers.

Modified: head/usr.bin/netstat/inet.c
==============================================================================
--- head/usr.bin/netstat/inet.c	Tue Jul  9 09:37:21 2013	(r253082)
+++ head/usr.bin/netstat/inet.c	Tue Jul  9 09:43:03 2013	(r253083)
@@ -603,13 +603,8 @@ tcp_stats(u_long off, const char *name, 
 			warn("sysctl: net.inet.tcp.stats");
 			return;
 		}
-	} else {
-		u_long tcpstat_p[sizeof(struct tcpstat)/sizeof(uint64_t)];
- 
-		kread(off, &tcpstat_p, sizeof(tcpstat_p));
-		kread_counters(tcpstat_p, (uint64_t *)&tcpstat,
-		    sizeof(struct tcpstat)/sizeof(uint64_t));
-	}
+	} else
+		kread_counters(off, &tcpstat, len);
 
 	printf ("%s:\n", name);
 
@@ -863,13 +858,8 @@ ip_stats(u_long off, const char *name, i
 			warn("sysctl: net.inet.ip.stats");
 			return;
 		}
-	} else {
-		u_long ipstat_p[sizeof(struct ipstat)/sizeof(uint64_t)];
-
-		kread(off, &ipstat_p, sizeof(ipstat_p));
-		kread_counters(ipstat_p, (uint64_t *)&ipstat,
-		    sizeof(struct ipstat)/sizeof(uint64_t));
-	}
+	} else
+		kread_counters(off, &ipstat, len);
 
 	printf("%s:\n", name);
 

Modified: head/usr.bin/netstat/main.c
==============================================================================
--- head/usr.bin/netstat/main.c	Tue Jul  9 09:37:21 2013	(r253082)
+++ head/usr.bin/netstat/main.c	Tue Jul  9 09:43:03 2013	(r253083)
@@ -147,11 +147,11 @@ static struct nlist nl[] = {
 #define	N_IPCOMPSTAT	37
 	{ .n_name = "_ipcompstat" },
 #define	N_TCPSTAT	38
-	{ .n_name = "_tcpstatp" },
+	{ .n_name = "_tcpstat" },
 #define	N_UDPSTAT	39
 	{ .n_name = "_udpstat" },
 #define	N_IPSTAT	40
-	{ .n_name = "_ipstatp" },
+	{ .n_name = "_ipstat" },
 #define	N_ICMPSTAT	41
 	{ .n_name = "_icmpstat" },
 #define	N_IGMPSTAT	42
@@ -753,15 +753,21 @@ kread(u_long addr, void *buf, size_t siz
  * Read an array of N counters in kernel memory into array of N uint64_t's.
  */
 int
-kread_counters(u_long *addr, uint64_t *rval, size_t count)
+kread_counters(u_long addr, void *buf, size_t size)
 {
+	uint64_t *c = buf;
 
 	if (kvmd_init() < 0)
 		return (-1);
 
-	for (u_int i = 0; i < count; i++, addr++, rval++)
-		*rval = kvm_counter_u64_fetch(kvmd, *addr);
+	if (kread(addr, buf, size) < 0)
+		return (-1);
 
+	while (size != 0) {
+		*c = kvm_counter_u64_fetch(kvmd, *c);
+		size -= sizeof(*c);
+		c++;
+	}
 	return (0);
 }
 

Modified: head/usr.bin/netstat/netstat.h
==============================================================================
--- head/usr.bin/netstat/netstat.h	Tue Jul  9 09:37:21 2013	(r253082)
+++ head/usr.bin/netstat/netstat.h	Tue Jul  9 09:43:03 2013	(r253083)
@@ -60,7 +60,7 @@ extern int	af;	/* address family */
 extern int	live;	/* true if we are examining a live system */
 
 int	kread(u_long addr, void *buf, size_t size);
-int	kread_counters(u_long *addr, uint64_t *rval, size_t count);
+int	kread_counters(u_long addr, void *buf, size_t size);
 const char *plural(uintmax_t);
 const char *plurales(uintmax_t);
 const char *pluralies(uintmax_t);


More information about the svn-src-head mailing list