aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bonding/bond_main.c13
-rw-r--r--include/linux/if_link.h3
-rw-r--r--include/linux/netdevice.h91
-rw-r--r--net/8021q/vlanproc.c13
-rw-r--r--net/core/dev.c19
-rw-r--r--net/core/net-sysfs.c12
-rw-r--r--net/core/rtnetlink.c6
7 files changed, 90 insertions, 67 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ac4f94b7da37..a95a41b74b4e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3804,20 +3804,21 @@ static int bond_close(struct net_device *bond_dev)
3804 return 0; 3804 return 0;
3805} 3805}
3806 3806
3807static struct net_device_stats *bond_get_stats(struct net_device *bond_dev) 3807static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev)
3808{ 3808{
3809 struct bonding *bond = netdev_priv(bond_dev); 3809 struct bonding *bond = netdev_priv(bond_dev);
3810 struct net_device_stats *stats = &bond_dev->stats; 3810 struct rtnl_link_stats64 *stats = &bond_dev->stats64;
3811 struct net_device_stats local_stats; 3811 struct rtnl_link_stats64 local_stats;
3812 struct slave *slave; 3812 struct slave *slave;
3813 int i; 3813 int i;
3814 3814
3815 memset(&local_stats, 0, sizeof(struct net_device_stats)); 3815 memset(&local_stats, 0, sizeof(local_stats));
3816 3816
3817 read_lock_bh(&bond->lock); 3817 read_lock_bh(&bond->lock);
3818 3818
3819 bond_for_each_slave(bond, slave, i) { 3819 bond_for_each_slave(bond, slave, i) {
3820 const struct net_device_stats *sstats = dev_get_stats(slave->dev); 3820 const struct rtnl_link_stats64 *sstats =
3821 dev_get_stats(slave->dev);
3821 3822
3822 local_stats.rx_packets += sstats->rx_packets; 3823 local_stats.rx_packets += sstats->rx_packets;
3823 local_stats.rx_bytes += sstats->rx_bytes; 3824 local_stats.rx_bytes += sstats->rx_bytes;
@@ -4569,7 +4570,7 @@ static const struct net_device_ops bond_netdev_ops = {
4569 .ndo_stop = bond_close, 4570 .ndo_stop = bond_close,
4570 .ndo_start_xmit = bond_start_xmit, 4571 .ndo_start_xmit = bond_start_xmit,
4571 .ndo_select_queue = bond_select_queue, 4572 .ndo_select_queue = bond_select_queue,
4572 .ndo_get_stats = bond_get_stats, 4573 .ndo_get_stats64 = bond_get_stats,
4573 .ndo_do_ioctl = bond_do_ioctl, 4574 .ndo_do_ioctl = bond_do_ioctl,
4574 .ndo_set_multicast_list = bond_set_multicast_list, 4575 .ndo_set_multicast_list = bond_set_multicast_list,
4575 .ndo_change_mtu = bond_change_mtu, 4576 .ndo_change_mtu = bond_change_mtu,
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 85c812db5a3f..7fcad2e1be3d 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -4,7 +4,7 @@
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/netlink.h> 5#include <linux/netlink.h>
6 6
7/* The struct should be in sync with struct net_device_stats */ 7/* This struct should be in sync with struct rtnl_link_stats64 */
8struct rtnl_link_stats { 8struct rtnl_link_stats {
9 __u32 rx_packets; /* total packets received */ 9 __u32 rx_packets; /* total packets received */
10 __u32 tx_packets; /* total packets transmitted */ 10 __u32 tx_packets; /* total packets transmitted */
@@ -37,6 +37,7 @@ struct rtnl_link_stats {
37 __u32 tx_compressed; 37 __u32 tx_compressed;
38}; 38};
39 39
40/* The main device statistics structure */
40struct rtnl_link_stats64 { 41struct rtnl_link_stats64 {
41 __u64 rx_packets; /* total packets received */ 42 __u64 rx_packets; /* total packets received */
42 __u64 tx_packets; /* total packets transmitted */ 43 __u64 tx_packets; /* total packets transmitted */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c319f28d699d..4fbccc5f609a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -159,45 +159,49 @@ static inline bool dev_xmit_complete(int rc)
159#define MAX_HEADER (LL_MAX_HEADER + 48) 159#define MAX_HEADER (LL_MAX_HEADER + 48)
160#endif 160#endif
161 161
162#endif /* __KERNEL__ */
163
164/* 162/*
165 * Network device statistics. Akin to the 2.0 ether stats but 163 * Old network device statistics. Fields are native words
166 * with byte counters. 164 * (unsigned long) so they can be read and written atomically.
165 * Each field is padded to 64 bits for compatibility with
166 * rtnl_link_stats64.
167 */ 167 */
168 168
169#if BITS_PER_LONG == 64
170#define NET_DEVICE_STATS_DEFINE(name) unsigned long name
171#elif defined(__LITTLE_ENDIAN)
172#define NET_DEVICE_STATS_DEFINE(name) unsigned long name, pad_ ## name
173#else
174#define NET_DEVICE_STATS_DEFINE(name) unsigned long pad_ ## name, name
175#endif
176
169struct net_device_stats { 177struct net_device_stats {
170 unsigned long rx_packets; /* total packets received */ 178 NET_DEVICE_STATS_DEFINE(rx_packets);
171 unsigned long tx_packets; /* total packets transmitted */ 179 NET_DEVICE_STATS_DEFINE(tx_packets);
172 unsigned long rx_bytes; /* total bytes received */ 180 NET_DEVICE_STATS_DEFINE(rx_bytes);
173 unsigned long tx_bytes; /* total bytes transmitted */ 181 NET_DEVICE_STATS_DEFINE(tx_bytes);
174 unsigned long rx_errors; /* bad packets received */ 182 NET_DEVICE_STATS_DEFINE(rx_errors);
175 unsigned long tx_errors; /* packet transmit problems */ 183 NET_DEVICE_STATS_DEFINE(tx_errors);
176 unsigned long rx_dropped; /* no space in linux buffers */ 184 NET_DEVICE_STATS_DEFINE(rx_dropped);
177 unsigned long tx_dropped; /* no space available in linux */ 185 NET_DEVICE_STATS_DEFINE(tx_dropped);
178 unsigned long multicast; /* multicast packets received */ 186 NET_DEVICE_STATS_DEFINE(multicast);
179 unsigned long collisions; 187 NET_DEVICE_STATS_DEFINE(collisions);
180 188 NET_DEVICE_STATS_DEFINE(rx_length_errors);
181 /* detailed rx_errors: */ 189 NET_DEVICE_STATS_DEFINE(rx_over_errors);
182 unsigned long rx_length_errors; 190 NET_DEVICE_STATS_DEFINE(rx_crc_errors);
183 unsigned long rx_over_errors; /* receiver ring buff overflow */ 191 NET_DEVICE_STATS_DEFINE(rx_frame_errors);
184 unsigned long rx_crc_errors; /* recved pkt with crc error */ 192 NET_DEVICE_STATS_DEFINE(rx_fifo_errors);
185 unsigned long rx_frame_errors; /* recv'd frame alignment error */ 193 NET_DEVICE_STATS_DEFINE(rx_missed_errors);
186 unsigned long rx_fifo_errors; /* recv'r fifo overrun */ 194 NET_DEVICE_STATS_DEFINE(tx_aborted_errors);
187 unsigned long rx_missed_errors; /* receiver missed packet */ 195 NET_DEVICE_STATS_DEFINE(tx_carrier_errors);
188 196 NET_DEVICE_STATS_DEFINE(tx_fifo_errors);
189 /* detailed tx_errors */ 197 NET_DEVICE_STATS_DEFINE(tx_heartbeat_errors);
190 unsigned long tx_aborted_errors; 198 NET_DEVICE_STATS_DEFINE(tx_window_errors);
191 unsigned long tx_carrier_errors; 199 NET_DEVICE_STATS_DEFINE(rx_compressed);
192 unsigned long tx_fifo_errors; 200 NET_DEVICE_STATS_DEFINE(tx_compressed);
193 unsigned long tx_heartbeat_errors;
194 unsigned long tx_window_errors;
195
196 /* for cslip etc */
197 unsigned long rx_compressed;
198 unsigned long tx_compressed;
199}; 201};
200 202
203#endif /* __KERNEL__ */
204
201 205
202/* Media selection options. */ 206/* Media selection options. */
203enum { 207enum {
@@ -662,10 +666,19 @@ struct netdev_rx_queue {
662 * Callback uses when the transmitter has not made any progress 666 * Callback uses when the transmitter has not made any progress
663 * for dev->watchdog ticks. 667 * for dev->watchdog ticks.
664 * 668 *
669 * struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev);
665 * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); 670 * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
666 * Called when a user wants to get the network device usage 671 * Called when a user wants to get the network device usage
667 * statistics. If not defined, the counters in dev->stats will 672 * statistics. Drivers must do one of the following:
668 * be used. 673 * 1. Define @ndo_get_stats64 to update a rtnl_link_stats64 structure
674 * (which should normally be dev->stats64) and return a ponter to
675 * it. The structure must not be changed asynchronously.
676 * 2. Define @ndo_get_stats to update a net_device_stats64 structure
677 * (which should normally be dev->stats) and return a pointer to
678 * it. The structure may be changed asynchronously only if each
679 * field is written atomically.
680 * 3. Update dev->stats asynchronously and atomically, and define
681 * neither operation.
669 * 682 *
670 * void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp); 683 * void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp);
671 * If device support VLAN receive accleration 684 * If device support VLAN receive accleration
@@ -720,6 +733,7 @@ struct net_device_ops {
720 struct neigh_parms *); 733 struct neigh_parms *);
721 void (*ndo_tx_timeout) (struct net_device *dev); 734 void (*ndo_tx_timeout) (struct net_device *dev);
722 735
736 struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev);
723 struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); 737 struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
724 738
725 void (*ndo_vlan_rx_register)(struct net_device *dev, 739 void (*ndo_vlan_rx_register)(struct net_device *dev,
@@ -869,7 +883,10 @@ struct net_device {
869 int ifindex; 883 int ifindex;
870 int iflink; 884 int iflink;
871 885
872 struct net_device_stats stats; 886 union {
887 struct rtnl_link_stats64 stats64;
888 struct net_device_stats stats;
889 };
873 890
874#ifdef CONFIG_WIRELESS_EXT 891#ifdef CONFIG_WIRELESS_EXT
875 /* List of functions to handle Wireless Extensions (instead of ioctl). 892 /* List of functions to handle Wireless Extensions (instead of ioctl).
@@ -2121,7 +2138,7 @@ extern void netdev_features_change(struct net_device *dev);
2121/* Load a device via the kmod */ 2138/* Load a device via the kmod */
2122extern void dev_load(struct net *net, const char *name); 2139extern void dev_load(struct net *net, const char *name);
2123extern void dev_mcast_init(void); 2140extern void dev_mcast_init(void);
2124extern const struct net_device_stats *dev_get_stats(struct net_device *dev); 2141extern const struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev);
2125extern void dev_txq_stats_fold(const struct net_device *dev, struct net_device_stats *stats); 2142extern void dev_txq_stats_fold(const struct net_device *dev, struct net_device_stats *stats);
2126 2143
2127extern int netdev_max_backlog; 2144extern int netdev_max_backlog;
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index afead353e215..df56f5ce887c 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -278,8 +278,9 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
278{ 278{
279 struct net_device *vlandev = (struct net_device *) seq->private; 279 struct net_device *vlandev = (struct net_device *) seq->private;
280 const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); 280 const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
281 const struct net_device_stats *stats; 281 const struct rtnl_link_stats64 *stats;
282 static const char fmt[] = "%30s %12lu\n"; 282 static const char fmt[] = "%30s %12lu\n";
283 static const char fmt64[] = "%30s %12llu\n";
283 int i; 284 int i;
284 285
285 if (!is_vlan_dev(vlandev)) 286 if (!is_vlan_dev(vlandev))
@@ -291,12 +292,12 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
291 vlandev->name, dev_info->vlan_id, 292 vlandev->name, dev_info->vlan_id,
292 (int)(dev_info->flags & 1), vlandev->priv_flags); 293 (int)(dev_info->flags & 1), vlandev->priv_flags);
293 294
294 seq_printf(seq, fmt, "total frames received", stats->rx_packets); 295 seq_printf(seq, fmt64, "total frames received", stats->rx_packets);
295 seq_printf(seq, fmt, "total bytes received", stats->rx_bytes); 296 seq_printf(seq, fmt64, "total bytes received", stats->rx_bytes);
296 seq_printf(seq, fmt, "Broadcast/Multicast Rcvd", stats->multicast); 297 seq_printf(seq, fmt64, "Broadcast/Multicast Rcvd", stats->multicast);
297 seq_puts(seq, "\n"); 298 seq_puts(seq, "\n");
298 seq_printf(seq, fmt, "total frames transmitted", stats->tx_packets); 299 seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets);
299 seq_printf(seq, fmt, "total bytes transmitted", stats->tx_bytes); 300 seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes);
300 seq_printf(seq, fmt, "total headroom inc", 301 seq_printf(seq, fmt, "total headroom inc",
301 dev_info->cnt_inc_headroom_on_tx); 302 dev_info->cnt_inc_headroom_on_tx);
302 seq_printf(seq, fmt, "total encap on xmit", 303 seq_printf(seq, fmt, "total encap on xmit",
diff --git a/net/core/dev.c b/net/core/dev.c
index 277844901ce3..a1abc10db08a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3701,10 +3701,10 @@ void dev_seq_stop(struct seq_file *seq, void *v)
3701 3701
3702static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev) 3702static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
3703{ 3703{
3704 const struct net_device_stats *stats = dev_get_stats(dev); 3704 const struct rtnl_link_stats64 *stats = dev_get_stats(dev);
3705 3705
3706 seq_printf(seq, "%6s: %7lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu " 3706 seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
3707 "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n", 3707 "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
3708 dev->name, stats->rx_bytes, stats->rx_packets, 3708 dev->name, stats->rx_bytes, stats->rx_packets,
3709 stats->rx_errors, 3709 stats->rx_errors,
3710 stats->rx_dropped + stats->rx_missed_errors, 3710 stats->rx_dropped + stats->rx_missed_errors,
@@ -5281,18 +5281,21 @@ EXPORT_SYMBOL(dev_txq_stats_fold);
5281 * @dev: device to get statistics from 5281 * @dev: device to get statistics from
5282 * 5282 *
5283 * Get network statistics from device. The device driver may provide 5283 * Get network statistics from device. The device driver may provide
5284 * its own method by setting dev->netdev_ops->get_stats; otherwise 5284 * its own method by setting dev->netdev_ops->get_stats64 or
5285 * the internal statistics structure is used. 5285 * dev->netdev_ops->get_stats; otherwise the internal statistics
5286 * structure is used.
5286 */ 5287 */
5287const struct net_device_stats *dev_get_stats(struct net_device *dev) 5288const struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev)
5288{ 5289{
5289 const struct net_device_ops *ops = dev->netdev_ops; 5290 const struct net_device_ops *ops = dev->netdev_ops;
5290 5291
5292 if (ops->ndo_get_stats64)
5293 return ops->ndo_get_stats64(dev);
5291 if (ops->ndo_get_stats) 5294 if (ops->ndo_get_stats)
5292 return ops->ndo_get_stats(dev); 5295 return (struct rtnl_link_stats64 *)ops->ndo_get_stats(dev);
5293 5296
5294 dev_txq_stats_fold(dev, &dev->stats); 5297 dev_txq_stats_fold(dev, &dev->stats);
5295 return &dev->stats; 5298 return &dev->stats64;
5296} 5299}
5297EXPORT_SYMBOL(dev_get_stats); 5300EXPORT_SYMBOL(dev_get_stats);
5298 5301
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 99e7052d7323..ea3bb4c3b87d 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -29,6 +29,7 @@ static const char fmt_hex[] = "%#x\n";
29static const char fmt_long_hex[] = "%#lx\n"; 29static const char fmt_long_hex[] = "%#lx\n";
30static const char fmt_dec[] = "%d\n"; 30static const char fmt_dec[] = "%d\n";
31static const char fmt_ulong[] = "%lu\n"; 31static const char fmt_ulong[] = "%lu\n";
32static const char fmt_u64[] = "%llu\n";
32 33
33static inline int dev_isalive(const struct net_device *dev) 34static inline int dev_isalive(const struct net_device *dev)
34{ 35{
@@ -324,14 +325,13 @@ static ssize_t netstat_show(const struct device *d,
324 struct net_device *dev = to_net_dev(d); 325 struct net_device *dev = to_net_dev(d);
325 ssize_t ret = -EINVAL; 326 ssize_t ret = -EINVAL;
326 327
327 WARN_ON(offset > sizeof(struct net_device_stats) || 328 WARN_ON(offset > sizeof(struct rtnl_link_stats64) ||
328 offset % sizeof(unsigned long) != 0); 329 offset % sizeof(u64) != 0);
329 330
330 read_lock(&dev_base_lock); 331 read_lock(&dev_base_lock);
331 if (dev_isalive(dev)) { 332 if (dev_isalive(dev)) {
332 const struct net_device_stats *stats = dev_get_stats(dev); 333 const struct rtnl_link_stats64 *stats = dev_get_stats(dev);
333 ret = sprintf(buf, fmt_ulong, 334 ret = sprintf(buf, fmt_u64, *(u64 *)(((u8 *) stats) + offset));
334 *(unsigned long *)(((u8 *) stats) + offset));
335 } 335 }
336 read_unlock(&dev_base_lock); 336 read_unlock(&dev_base_lock);
337 return ret; 337 return ret;
@@ -343,7 +343,7 @@ static ssize_t show_##name(struct device *d, \
343 struct device_attribute *attr, char *buf) \ 343 struct device_attribute *attr, char *buf) \
344{ \ 344{ \
345 return netstat_show(d, attr, buf, \ 345 return netstat_show(d, attr, buf, \
346 offsetof(struct net_device_stats, name)); \ 346 offsetof(struct rtnl_link_stats64, name)); \
347} \ 347} \
348static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) 348static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
349 349
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 1a2af24e9e3d..e645778e9b7e 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -579,7 +579,7 @@ static unsigned int rtnl_dev_combine_flags(const struct net_device *dev,
579} 579}
580 580
581static void copy_rtnl_link_stats(struct rtnl_link_stats *a, 581static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
582 const struct net_device_stats *b) 582 const struct rtnl_link_stats64 *b)
583{ 583{
584 a->rx_packets = b->rx_packets; 584 a->rx_packets = b->rx_packets;
585 a->tx_packets = b->tx_packets; 585 a->tx_packets = b->tx_packets;
@@ -610,7 +610,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
610 a->tx_compressed = b->tx_compressed; 610 a->tx_compressed = b->tx_compressed;
611} 611}
612 612
613static void copy_rtnl_link_stats64(void *v, const struct net_device_stats *b) 613static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b)
614{ 614{
615 struct rtnl_link_stats64 a; 615 struct rtnl_link_stats64 a;
616 616
@@ -791,7 +791,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
791{ 791{
792 struct ifinfomsg *ifm; 792 struct ifinfomsg *ifm;
793 struct nlmsghdr *nlh; 793 struct nlmsghdr *nlh;
794 const struct net_device_stats *stats; 794 const struct rtnl_link_stats64 *stats;
795 struct nlattr *attr; 795 struct nlattr *attr;
796 796
797 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); 797 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);