lkml.org 
[lkml]   [2004]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 2.6] 64network: 64-bit network statistics
    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;
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-03-22 14:05    [W:3.782 / U:1.368 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site