diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-15 13:27:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-18 10:54:29 -0400 |
commit | 12dcd86b75d571772512676ab301279952efc0b0 (patch) | |
tree | 8214cabf20bfcba9fb58c642f5d1d2b544f4966e /drivers/net/igb/igb.h | |
parent | dce87b960cf4794141f067d8c8180ccc6716513f (diff) |
igb: fix stats handling
There are currently some problems with igb.
- On 32bit arches, maintaining 64bit counters without proper
synchronization between writers and readers.
- Stats updated every two seconds, as reported by Jesper.
(Jesper provided a patch for this)
- Potential problem between worker thread and ethtool -S
This patch uses u64_stats_sync, and convert everything to be 64bit safe,
SMP safe, even on 32bit arches. It integrates Jesper idea of providing
accurate stats at the time user reads them.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Tested-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb/igb.h')
-rw-r--r-- | drivers/net/igb/igb.h | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 44e0ff1494e0..edab9c442399 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h | |||
@@ -159,6 +159,7 @@ struct igb_tx_queue_stats { | |||
159 | u64 packets; | 159 | u64 packets; |
160 | u64 bytes; | 160 | u64 bytes; |
161 | u64 restart_queue; | 161 | u64 restart_queue; |
162 | u64 restart_queue2; | ||
162 | }; | 163 | }; |
163 | 164 | ||
164 | struct igb_rx_queue_stats { | 165 | struct igb_rx_queue_stats { |
@@ -210,11 +211,14 @@ struct igb_ring { | |||
210 | /* TX */ | 211 | /* TX */ |
211 | struct { | 212 | struct { |
212 | struct igb_tx_queue_stats tx_stats; | 213 | struct igb_tx_queue_stats tx_stats; |
214 | struct u64_stats_sync tx_syncp; | ||
215 | struct u64_stats_sync tx_syncp2; | ||
213 | bool detect_tx_hung; | 216 | bool detect_tx_hung; |
214 | }; | 217 | }; |
215 | /* RX */ | 218 | /* RX */ |
216 | struct { | 219 | struct { |
217 | struct igb_rx_queue_stats rx_stats; | 220 | struct igb_rx_queue_stats rx_stats; |
221 | struct u64_stats_sync rx_syncp; | ||
218 | u32 rx_buffer_len; | 222 | u32 rx_buffer_len; |
219 | }; | 223 | }; |
220 | }; | 224 | }; |
@@ -288,6 +292,9 @@ struct igb_adapter { | |||
288 | struct timecompare compare; | 292 | struct timecompare compare; |
289 | struct hwtstamp_config hwtstamp_config; | 293 | struct hwtstamp_config hwtstamp_config; |
290 | 294 | ||
295 | spinlock_t stats64_lock; | ||
296 | struct rtnl_link_stats64 stats64; | ||
297 | |||
291 | /* structs defined in e1000_hw.h */ | 298 | /* structs defined in e1000_hw.h */ |
292 | struct e1000_hw hw; | 299 | struct e1000_hw hw; |
293 | struct e1000_hw_stats stats; | 300 | struct e1000_hw_stats stats; |
@@ -357,7 +364,7 @@ extern netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *, struct igb_ring *); | |||
357 | extern void igb_unmap_and_free_tx_resource(struct igb_ring *, | 364 | extern void igb_unmap_and_free_tx_resource(struct igb_ring *, |
358 | struct igb_buffer *); | 365 | struct igb_buffer *); |
359 | extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int); | 366 | extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int); |
360 | extern void igb_update_stats(struct igb_adapter *); | 367 | extern void igb_update_stats(struct igb_adapter *, struct rtnl_link_stats64 *); |
361 | extern bool igb_has_link(struct igb_adapter *adapter); | 368 | extern bool igb_has_link(struct igb_adapter *adapter); |
362 | extern void igb_set_ethtool_ops(struct net_device *); | 369 | extern void igb_set_ethtool_ops(struct net_device *); |
363 | extern void igb_power_up_link(struct igb_adapter *); | 370 | extern void igb_power_up_link(struct igb_adapter *); |