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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to