From: James Cammarata <jimi@sngx.net>
To: linux-kernel@vger.kernel.org
Cc: Linux Netdev List <netdev@vger.kernel.org>
Subject: [PATCH] net: add ability to clear stats via ethtool - e1000/pcnet32
Date: Wed, 28 May 2008 20:45:18 -0500 [thread overview]
Message-ID: <483E0AAE.2020107@sngx.net> (raw)
In-Reply-To: <482FBA09.80201@sngx.net>
I had originally submitted this ability as a patch to procfs, and
general consensus was that it seemed "hackish" to do it that way. It
was suggested that it be implemented as a feature of ethtool, so I
thought I'd take on the challenge and add it that way.
I've laid the groundwork here, and added the ability to two of the
drivers for which I have hardware to test on (e1000 and pcnet32). I
also added the code required to call this functionality to the ethtool
code base, and have been using that to test my changes (using -z as the
flag to ethtool for clearing stats for now).
If this is an acceptable start, I will gladly start working on adding
this to as many drivers as possible (we do have some bnx2 hardware,
though I'm not sure if it's available for testing).
Some other sys-admins have mentioned to me that ethtool doesn't work
sometimes and they fall back to using mii-tool to configure interfaces,
so I'd still like to have the procfs change implemented to accommodate
that hardware, but I agree, this is a better way forward.
Signed-off-by: James Cammarata <jimi@sngx.net>
---
--- linux-2.6.25.4/include/linux/ethtool.h 2008-05-15 10:00:12.000000000 -0500
+++ linux-2.6.25.4-jcammara/include/linux/ethtool.h 2008-05-28 17:45:56.000000000 -0500
@@ -325,6 +325,7 @@ int ethtool_op_set_flags(struct net_devi
* get_strings: Return a set of strings that describe the requested objects
* phys_id: Identify the device
* get_stats: Return statistics about the device
+ * clear_ethtool_stats: Clear device statistics
* get_flags: get 32-bit flags bitmap
* set_flags: set 32-bit flags bitmap
*
@@ -383,6 +384,7 @@ struct ethtool_ops {
void (*get_strings)(struct net_device *, u32 stringset, u8 *);
int (*phys_id)(struct net_device *, u32);
void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
+ int (*clear_ethtool_stats)(struct net_device *);
int (*begin)(struct net_device *);
void (*complete)(struct net_device *);
u32 (*get_ufo)(struct net_device *);
@@ -441,6 +443,7 @@ struct ethtool_ops {
#define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */
#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */
#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */
+#define ETHTOOL_CSTATS 0x00000029 /* Clear NIC statistics */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
--- linux-2.6.25.4/net/core/ethtool.c 2008-05-15 10:00:12.000000000 -0500
+++ linux-2.6.25.4-jcammara/net/core/ethtool.c 2008-05-28 17:48:51.000000000 -0500
@@ -714,6 +714,16 @@ static int ethtool_get_stats(struct net_
return ret;
}
+static int ethtool_clear_stats(struct net_device *dev, void __user *useraddr)
+{
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+
+ if (!ops->clear_ethtool_stats)
+ return -EOPNOTSUPP;
+
+ return ops->clear_ethtool_stats(dev);
+}
+
static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
{
struct ethtool_perm_addr epaddr;
@@ -964,6 +974,9 @@ int dev_ethtool(struct net *net, struct
rc = ethtool_set_value(dev, useraddr,
dev->ethtool_ops->set_priv_flags);
break;
+ case ETHTOOL_CSTATS:
+ rc = ethtool_clear_stats(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
--- linux-2.6.25.4/drivers/net/e1000/e1000_main.c 2008-05-15 10:00:12.000000000 -0500
+++ linux-2.6.25.4-jcammara/drivers/net/e1000/e1000_main.c 2008-05-28 17:51:07.000000000 -0500
@@ -141,6 +141,7 @@ static void e1000_free_tx_resources(stru
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring);
void e1000_update_stats(struct e1000_adapter *adapter);
+void e1000_clear_stats(struct e1000_adapter *adapter);
static int e1000_init_module(void);
static void e1000_exit_module(void);
@@ -3819,6 +3820,31 @@ e1000_update_stats(struct e1000_adapter
spin_unlock_irqrestore(&adapter->stats_lock, flags);
}
+void
+e1000_clear_stats(struct e1000_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ unsigned long flags;
+
+ #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
+
+ /*
+ * Prevent stats update while adapter is being reset, or if the pci
+ * connection is down.
+ */
+ if (adapter->link_speed == 0)
+ return;
+ if (pci_channel_offline(pdev))
+ return;
+
+ spin_lock_irqsave(&adapter->stats_lock, flags);
+
+ memset(&adapter->stats, 0, sizeof(struct e1000_hw_stats));
+ memset(&adapter->net_stats, 0, sizeof(struct net_device_stats));
+
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+}
+
/**
* e1000_intr_msi - Interrupt Handler
* @irq: interrupt number
--- linux-2.6.25.4/drivers/net/e1000/e1000_ethtool.c 2008-05-15 10:00:12.000000000 -0500
+++ linux-2.6.25.4-jcammara/drivers/net/e1000/e1000_ethtool.c 2008-05-28 17:53:28.000000000 -0500
@@ -42,7 +42,7 @@ extern int e1000_setup_all_tx_resources(
extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_update_stats(struct e1000_adapter *adapter);
-
+extern void e1000_clear_stats(struct e1000_adapter *adapter);
struct e1000_stats {
char stat_string[ETH_GSTRING_LEN];
@@ -1940,6 +1940,14 @@ e1000_get_ethtool_stats(struct net_devic
/* BUG_ON(i != E1000_STATS_LEN); */
}
+static int
+e1000_clear_ethtool_stats(struct net_device *netdev)
+{
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ e1000_clear_stats(adapter);
+ return 0;
+}
+
static void
e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
{
@@ -1991,6 +1999,7 @@ static const struct ethtool_ops e1000_et
.get_strings = e1000_get_strings,
.phys_id = e1000_phys_id,
.get_ethtool_stats = e1000_get_ethtool_stats,
+ .clear_ethtool_stats = e1000_clear_ethtool_stats,
.get_sset_count = e1000_get_sset_count,
};
--- linux-2.6.25.4/drivers/net/pcnet32.c 2008-05-15 10:00:12.000000000 -0500
+++ linux-2.6.25.4-jcammara/drivers/net/pcnet32.c 2008-05-28 17:59:42.000000000 -0500
@@ -312,6 +312,7 @@ static void pcnet32_tx_timeout(struct ne
static irqreturn_t pcnet32_interrupt(int, void *);
static int pcnet32_close(struct net_device *);
static struct net_device_stats *pcnet32_get_stats(struct net_device *);
+static int pcnet32_clear_stats(struct net_device *);
static void pcnet32_load_multicast(struct net_device *dev);
static void pcnet32_set_multicast_list(struct net_device *);
static int pcnet32_ioctl(struct net_device *, struct ifreq *, int);
@@ -1532,6 +1533,7 @@ static const struct ethtool_ops pcnet32_
.get_regs_len = pcnet32_get_regs_len,
.get_regs = pcnet32_get_regs,
.get_sset_count = pcnet32_get_sset_count,
+ .clear_ethtool_stats = pcnet32_clear_stats,
};
/* only probes for non-PCI devices, the rest are handled by
@@ -2719,6 +2721,17 @@ static struct net_device_stats *pcnet32_
return &dev->stats;
}
+static int pcnet32_clear_stats(struct net_device *dev)
+{
+ struct pcnet32_private *lp = netdev_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&lp->lock, flags);
+ memset(&dev->stats, 0, sizeof(struct net_device_stats));
+ spin_unlock_irqrestore(&lp->lock, flags);
+ return 0;
+}
+
/* taken from the sunlance driver, which it took from the depca driver */
static void pcnet32_load_multicast(struct net_device *dev)
{
next prev parent reply other threads:[~2008-05-29 1:44 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-16 15:18 [PATCH updated] net: add ability to clear per-interface network statistics via procfs James Cammarata
2008-05-16 16:20 ` Eric Dumazet
2008-05-16 20:03 ` David Miller
2008-05-17 14:54 ` James Cammarata
2008-05-17 21:41 ` Eric Dumazet
2008-05-17 22:49 ` James Cammarata
2008-05-18 0:31 ` Ben Hutchings
2008-05-18 1:43 ` Patrick McHardy
2008-05-18 5:09 ` James Cammarata
2008-05-18 11:27 ` Ben Hutchings
2008-05-29 1:45 ` James Cammarata [this message]
2008-05-29 2:08 ` [PATCH] net: add ability to clear stats via ethtool - e1000/pcnet32 James Cammarata
2008-05-29 5:11 ` Andrew Morton
2008-05-29 12:34 ` James Cammarata
2008-05-29 14:45 ` Alan Cox
2008-05-29 17:15 ` James Cammarata
2008-05-29 20:50 ` David Miller
2008-05-29 21:18 ` James Cammarata
2008-05-30 19:12 ` Bill Fink
2008-05-30 22:14 ` Rick Jones
2008-05-31 1:09 ` Bill Fink
2008-05-31 2:41 ` Stephen Hemminger
2008-05-31 4:47 ` Bill Fink
2008-05-31 12:11 ` Alan Cox
2008-05-31 23:57 ` Bill Fink
2008-06-01 1:46 ` Ben Hutchings
2008-06-01 20:46 ` Bill Fink
2008-06-01 22:29 ` Ben Hutchings
2008-06-02 3:55 ` Bill Fink
2008-06-02 5:39 ` David Miller
2008-06-02 15:41 ` Bill Fink
2008-06-02 4:50 ` Glen Turner
2008-06-02 16:10 ` Bill Fink
2008-06-03 12:28 ` James Cammarata
2008-06-03 12:35 ` Ben Hutchings
2008-06-03 14:46 ` Alan Cox
2008-06-04 3:05 ` James Cammarata
2008-05-29 14:48 ` Chris Friesen
2008-05-16 20:00 ` [PATCH updated] net: add ability to clear per-interface network statistics via procfs David Miller
2008-05-16 20:09 ` Rick Jones
2008-05-17 15:06 ` James Cammarata
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=483E0AAE.2020107@sngx.net \
--to=jimi@sngx.net \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox