All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Josef 'Jeff' Sipek" <jeffpc@optonline.net>
To: linux-kernel@vger.kernel.org
Cc: netdev@oss.sgi.com
Subject: [PATCH 2.6] 64network: 64-bit network statistics
Date: Fri, 03 Sep 2004 13:22:29 -0400	[thread overview]
Message-ID: <200409031322.29981.jeffpc@optonline.net> (raw)
In-Reply-To: <200409031307.01240.jeffpc@optonline.net>

Upon registration of a network device, all the statistics variables are
registered with watch64. Additionally, a new proc file is
created /proc/net/dev64 displays the 64-bit values as supposed
to /proc/net/dev which is left to display the original 32-bit variables for
backward compatibility. The sysfs interface
(/sys/class/net/<interface>/statistics/*) displays the 64-bit values only. On
64-bit systems, all is optimized away through watch64.

Requires: watch64

The following patch can be also pulled from http://jeffpc.bkbits.net/64network-2.6 (includes watch64)

Josef "Jeff" Sipek

Signed-off-by: Josef "Jeff" Sipek <jeffpc@optonline.net>


diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h 2004-09-03 12:22:08 -04:00
+++ b/include/linux/netdevice.h 2004-09-03 12:22:08 -04:00
@@ -14,6 +14,7 @@
  *  Alan Cox, <Alan.Cox@linux.org>
  *  Bjorn Ekwall. <bj0rn@blox.se>
  *              Pekka Riikonen <priikone@poseidon.pspt.fi>
+ *  Josef "Jeff" Sipek <jeffpc@optonline.net>
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
@@ -945,6 +946,10 @@
 #ifdef CONFIG_SYSCTL
 extern char *net_sysctl_strdup(const char *s);
 #endif
+
+/* Register/unregister all the members of struct net_device_stats with watch64 */
+inline void  net_register_stats64(struct net_device_stats* stats);
+inline void  net_unregister_stats64(struct net_device_stats* stats);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c 2004-09-03 12:22:08 -04:00
+++ b/net/core/dev.c 2004-09-03 12:22:08 -04:00
@@ -18,6 +18,7 @@
  *  Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
  *  Adam Sulmicki <adam@cfar.umd.edu>
  *              Pekka Riikonen <priikone@poesidon.pspt.fi>
+ *  Josef "Jeff" Sipek <jeffpc@optonline.net>
  *
  * Changes:
  *              D.J. Barrow     :       Fixed bug where dev->refcnt gets set
@@ -70,6 +71,7 @@
  *                 indefinitely on dev->refcnt
  *   J Hadi Salim : - Backlog queue sampling
  *            - netif_rx() feedback
+ * Josef "Jeff" Sipek : Added watch64 calls for network statistics
  */
 
 #include <asm/uaccess.h>
@@ -108,6 +110,7 @@
 #include <linux/kallsyms.h>
 #include <linux/netpoll.h>
 #include <linux/rcupdate.h>
+#include <linux/watch64.h>
 #ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>  /* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
@@ -2110,6 +2113,49 @@
   seq_printf(seq, "%6s: No statistics available.\n", dev->name);
 }
 
+static void dev_seq_printf_stats64(struct seq_file *seq, struct net_device *dev)
+{
+ if (dev->get_stats) {
+  struct net_device_stats *stats = dev->get_stats(dev);
+
+  seq_printf(seq, "%6s:%8llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
+    "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
+      dev->name, watch64_getval(&stats->rx_bytes,NULL),
+      watch64_getval(&stats->rx_packets,NULL),
+      watch64_getval(&stats->rx_errors,NULL),
+      watch64_getval(&stats->rx_dropped,NULL) +
+        watch64_getval(&stats->rx_missed_errors,NULL),
+      watch64_getval(&stats->rx_fifo_errors,NULL),
+      watch64_getval(&stats->rx_length_errors,NULL) + 
+        watch64_getval(&stats->rx_over_errors,NULL) +
+        watch64_getval(&stats->rx_crc_errors,NULL) +
+        watch64_getval(&stats->rx_frame_errors,NULL),
+      watch64_getval(&stats->rx_compressed,NULL),
+      watch64_getval(&stats->multicast,NULL),
+      watch64_getval(&stats->tx_bytes,NULL),
+      watch64_getval(&stats->tx_packets,NULL),
+      watch64_getval(&stats->tx_errors,NULL),
+      watch64_getval(&stats->tx_dropped,NULL),
+      watch64_getval(&stats->tx_fifo_errors,NULL),
+      watch64_getval(&stats->collisions,NULL),
+      watch64_getval(&stats->tx_carrier_errors,NULL) +
+        watch64_getval(&stats->tx_aborted_errors,NULL) +
+        watch64_getval(&stats->tx_window_errors,NULL) +
+        watch64_getval(&stats->tx_heartbeat_errors,NULL),
+      watch64_getval(&stats->tx_compressed,NULL));
+ } else
+  seq_printf(seq, "%6s: No statistics available.\n", dev->name);
+}
+
+static void dev_seq_show_header(struct seq_file *seq)
+{
+ seq_puts(seq, "Inter-|   Receive                            "
+        "                    |  Transmit\n"
+        " face |bytes    packets errs drop fifo frame "
+        "compressed multicast|bytes    packets errs "
+        "drop fifo colls carrier compressed\n");
+}
+
 /*
  * Called from the PROCfs module. This now uses the new arbitrary sized
  * /proc/net interface to create /proc/net/dev
@@ -2117,16 +2163,21 @@
 static int dev_seq_show(struct seq_file *seq, void *v)
 {
  if (v == SEQ_START_TOKEN)
-  seq_puts(seq, "Inter-|   Receive                            "
-         "                    |  Transmit\n"
-         " face |bytes    packets errs drop fifo frame "
-         "compressed multicast|bytes    packets errs "
-         "drop fifo colls carrier compressed\n");
+  dev_seq_show_header(seq);
  else
   dev_seq_printf_stats(seq, v);
  return 0;
 }
 
+static int dev_seq_show64(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN)
+  dev_seq_show_header(seq);
+ else
+  dev_seq_printf_stats64(seq, v);
+ return 0;
+}
+
 static struct netif_rx_stats *softnet_get_online(loff_t *pos)
 {
  struct netif_rx_stats *rc = NULL;
@@ -2179,11 +2230,23 @@
  .show  = dev_seq_show,
 };
 
+static struct seq_operations dev_seq_ops64 = {
+ .start = dev_seq_start,
+ .next  = dev_seq_next,
+ .stop  = dev_seq_stop,
+ .show  = dev_seq_show64,
+};
+
 static int dev_seq_open(struct inode *inode, struct file *file)
 {
  return seq_open(file, &dev_seq_ops);
 }
 
+static int dev_seq_open64(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &dev_seq_ops64);
+}
+
 static struct file_operations dev_seq_fops = {
  .owner  = THIS_MODULE,
  .open    = dev_seq_open,
@@ -2192,6 +2255,14 @@
  .release = seq_release,
 };
 
+static struct file_operations dev_seq_fops64 = {
+ .owner  = THIS_MODULE,
+ .open    = dev_seq_open64,
+ .read    = seq_read,
+ .llseek  = seq_lseek,
+ .release = seq_release,
+};
+
 static struct seq_operations softnet_seq_ops = {
  .start = softnet_seq_start,
  .next  = softnet_seq_next,
@@ -2224,8 +2295,10 @@
 
  if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops))
   goto out;
- if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
+ if (!proc_net_fops_create("dev64", S_IRUGO, &dev_seq_fops64))
   goto out_dev;
+ if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
+  goto out_dev64;
  if (wireless_proc_init())
   goto out_softnet;
  rc = 0;
@@ -2233,6 +2306,8 @@
  return rc;
 out_softnet:
  proc_net_remove("softnet_stat");
+out_dev64:
+ proc_net_remove("dev64");
 out_dev:
  proc_net_remove("dev");
  goto out;
@@ -2910,6 +2985,9 @@
   * device is present.
   */
 
+ if (dev->get_stats)
+  net_register_stats64(dev->get_stats(dev));
+ 
  set_bit(__LINK_STATE_PRESENT, &dev->state);
 
  dev->next = NULL;
@@ -2922,7 +3000,7 @@
  dev_hold(dev);
  dev->reg_state = NETREG_REGISTERING;
  write_unlock_bh(&dev_base_lock);
-
+ 
  /* Notify protocols, that a new device appeared. */
  notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
 
@@ -3145,6 +3223,9 @@
  /* If device is running, close it first. */
  if (dev->flags & IFF_UP)
   dev_close(dev);
+  
+ if (dev->get_stats)
+  net_unregister_stats64(dev->get_stats(dev));
 
  /* And unlink it from device chain. */
  for (dp = &dev_base; (d = *dp) != NULL; dp = &d->next) {
@@ -3246,6 +3327,98 @@
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
+/*
+ * Register all the members of the net_device_stats structure
+ *
+ */
+ 
+inline void net_register_stats64(struct net_device_stats* stats)
+{
+ if (!stats)
+  return;
+
+ watch64_register(&stats->tx_packets,0);
+ watch64_enable  (&stats->tx_packets,NULL);
+ watch64_register(&stats->rx_packets,0);
+ watch64_enable  (&stats->rx_packets,NULL);
+ watch64_register(&stats->tx_bytes,0);
+ watch64_enable  (&stats->tx_bytes,NULL);
+ watch64_register(&stats->rx_bytes,0);
+ watch64_enable  (&stats->rx_bytes,NULL);
+ watch64_register(&stats->tx_errors,0);
+ watch64_enable  (&stats->tx_errors,NULL);
+ watch64_register(&stats->rx_errors,0);
+ watch64_enable  (&stats->rx_errors,NULL);
+ watch64_register(&stats->tx_dropped,0);
+ watch64_enable  (&stats->tx_dropped,NULL);
+ watch64_register(&stats->rx_dropped,0);
+ watch64_enable  (&stats->rx_dropped,NULL);
+ watch64_register(&stats->multicast,0);
+ watch64_enable  (&stats->multicast,NULL);
+ watch64_register(&stats->collisions,0);
+ watch64_enable  (&stats->collisions,NULL);
+ watch64_register(&stats->rx_length_errors,0);
+ watch64_enable  (&stats->rx_length_errors,NULL);
+ watch64_register(&stats->rx_over_errors,0);
+ watch64_enable  (&stats->rx_over_errors,NULL);
+ watch64_register(&stats->rx_crc_errors,0);
+ watch64_enable  (&stats->rx_crc_errors,NULL);
+ watch64_register(&stats->rx_frame_errors,0);
+ watch64_enable  (&stats->rx_frame_errors,NULL);
+ watch64_register(&stats->rx_fifo_errors,0);
+ watch64_enable  (&stats->rx_fifo_errors,NULL);
+ watch64_register(&stats->rx_missed_errors,0);
+ watch64_enable  (&stats->rx_missed_errors,NULL);
+ watch64_register(&stats->tx_aborted_errors,0);
+ watch64_enable  (&stats->tx_aborted_errors,NULL);
+ watch64_register(&stats->tx_carrier_errors,0);
+ watch64_enable  (&stats->tx_carrier_errors,NULL);
+ watch64_register(&stats->tx_fifo_errors,0);
+ watch64_enable  (&stats->tx_fifo_errors,NULL);
+ watch64_register(&stats->tx_heartbeat_errors,0);
+ watch64_enable  (&stats->tx_heartbeat_errors,NULL);
+ watch64_register(&stats->tx_window_errors,0);
+ watch64_enable  (&stats->tx_window_errors,NULL);
+ watch64_register(&stats->rx_compressed,0);
+ watch64_enable  (&stats->rx_compressed,NULL);
+ watch64_register(&stats->tx_compressed,0);
+ watch64_enable  (&stats->tx_compressed,NULL);
+}
+
+/*
+ * Unregister all the members of the net_device_stats structure
+ *
+ */
+ 
+inline void net_unregister_stats64(struct net_device_stats* stats)
+{
+ if (!stats)
+  return;
+
+ watch64_unregister(&stats->tx_packets,0);
+ watch64_unregister(&stats->rx_packets,0);
+ watch64_unregister(&stats->tx_bytes,0);
+ watch64_unregister(&stats->rx_bytes,0);
+ watch64_unregister(&stats->tx_errors,0);
+ watch64_unregister(&stats->rx_errors,0);
+ watch64_unregister(&stats->tx_dropped,0);
+ watch64_unregister(&stats->rx_dropped,0);
+ watch64_unregister(&stats->multicast,0);
+ watch64_unregister(&stats->collisions,0);
+ watch64_unregister(&stats->rx_length_errors,0);
+ watch64_unregister(&stats->rx_over_errors,0);
+ watch64_unregister(&stats->rx_crc_errors,0);
+ watch64_unregister(&stats->rx_frame_errors,0);
+ watch64_unregister(&stats->rx_fifo_errors,0);
+ watch64_unregister(&stats->rx_missed_errors,0);
+ watch64_unregister(&stats->tx_aborted_errors,0);
+ watch64_unregister(&stats->tx_carrier_errors,0);
+ watch64_unregister(&stats->tx_fifo_errors,0);
+ watch64_unregister(&stats->tx_heartbeat_errors,0);
+ watch64_unregister(&stats->tx_window_errors,0);
+ watch64_unregister(&stats->rx_compressed,0);
+ watch64_unregister(&stats->tx_compressed,0);
+}
 
 /*
  * Initialize the DEV module. At boot time this walks the device list and
diff -Nru a/net/core/net-sysfs.c b/net/core/net-sysfs.c
--- a/net/core/net-sysfs.c 2004-09-03 12:22:08 -04:00
+++ b/net/core/net-sysfs.c 2004-09-03 12:22:08 -04:00
@@ -16,6 +16,7 @@
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <linux/wireless.h>
+#include <linux/watch64.h>
 
 #define to_class_dev(obj) container_of(obj,struct class_device,kobj)
 #define to_net_dev(class) container_of(class, struct net_device, class_dev)
@@ -23,6 +24,7 @@
 static const char fmt_hex[] = "%#x\n";
 static const char fmt_dec[] = "%d\n";
 static const char fmt_ulong[] = "%lu\n";
+static const char fmt_ullong[] = "%llu\n";
 
 static inline int dev_isalive(const struct net_device *dev) 
 {
@@ -204,8 +206,8 @@
  read_lock(&dev_base_lock);
  if (dev_isalive(dev) && dev->get_stats &&
      (stats = (*dev->get_stats)(dev))) 
-  ret = sprintf(buf, fmt_ulong,
-         *(unsigned long *)(((u8 *) stats) + offset));
+  ret = sprintf(buf, fmt_ullong,
+         watch64_getval((unsigned long *)(((u8 *) stats) + offset),NULL));
 
  read_unlock(&dev_base_lock);
  return ret;

  parent reply	other threads:[~2004-09-03 17:27 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-09-03 17:06 [PATCH/RFC 2.6] NET: 64-bit network statistics josef Jeff Sipek
2004-09-03 17:19 ` [PATCH 2.6] watch64: generic variable monitoring system Josef 'Jeff' Sipek
2004-09-03 19:07   ` YOSHIFUJI Hideaki / 吉藤英明
2004-09-03 20:24     ` Jeff Sipek
2004-09-03 19:16   ` Stephen Hemminger
2004-09-03 20:18     ` Jeff Sipek
2004-09-03 20:40       ` Josef 'Jeff' Sipek
2004-09-03 21:44     ` Josef 'Jeff' Sipek
2004-09-04 13:19       ` jamal
2004-09-05 16:19         ` Jeff Sipek
2004-09-07 10:18           ` jamal
2004-09-12 15:53             ` Jeff Sipek
2004-09-03 17:22 ` Josef 'Jeff' Sipek [this message]
2004-09-03 17:24 ` [PATCH/RFC 2.6] NET: 64-bit network statistics Jeff Sipek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200409031322.29981.jeffpc@optonline.net \
    --to=jeffpc@optonline.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.