diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2010-06-08 03:19:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-12 18:51:22 -0400 |
commit | be1f3c2c027cc5ad735df6a45a542ed1db7ec48b (patch) | |
tree | c97815a7cf25ea62e8f3a6b3597cfa8957f40b81 /include | |
parent | d19b51499967baddf4f9f12a0067146c2554527a (diff) |
net: Enable 64-bit net device statistics on 32-bit architectures
Use struct rtnl_link_stats64 as the statistics structure.
On 32-bit architectures, insert 32 bits of padding after/before each
field of struct net_device_stats to make its layout compatible with
struct rtnl_link_stats64. Add an anonymous union in net_device; move
stats into the union and add struct rtnl_link_stats64 stats64.
Add net_device_ops::ndo_get_stats64, implementations of which will
return a pointer to struct rtnl_link_stats64. Drivers that implement
this operation must not update the structure asynchronously.
Change dev_get_stats() to call ndo_get_stats64 if available, and to
return a pointer to struct rtnl_link_stats64. Change callers of
dev_get_stats() accordingly.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/if_link.h | 3 | ||||
-rw-r--r-- | include/linux/netdevice.h | 91 |
2 files changed, 56 insertions, 38 deletions
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 */ |
8 | struct rtnl_link_stats { | 8 | struct 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 */ | ||
40 | struct rtnl_link_stats64 { | 41 | struct 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 | |||
169 | struct net_device_stats { | 177 | struct 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. */ |
203 | enum { | 207 | enum { |
@@ -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 */ |
2122 | extern void dev_load(struct net *net, const char *name); | 2139 | extern void dev_load(struct net *net, const char *name); |
2123 | extern void dev_mcast_init(void); | 2140 | extern void dev_mcast_init(void); |
2124 | extern const struct net_device_stats *dev_get_stats(struct net_device *dev); | 2141 | extern const struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev); |
2125 | extern void dev_txq_stats_fold(const struct net_device *dev, struct net_device_stats *stats); | 2142 | extern void dev_txq_stats_fold(const struct net_device *dev, struct net_device_stats *stats); |
2126 | 2143 | ||
2127 | extern int netdev_max_backlog; | 2144 | extern int netdev_max_backlog; |