diff options
author | Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru> | 2014-07-17 07:10:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-17 19:48:36 -0400 |
commit | 8ccf3800dbdeaf26bcdefa471c9c8e0da7e6ec7a (patch) | |
tree | e88c2ea06aaed738991c1f3336c088f1eb9181c2 | |
parent | 87b200e11bb50e90471a69fe1af01e8fce8995aa (diff) |
sfc: Add per-queue statistics in ethtool
Implement per channel software TX and RX packet counters
accessed as ethtool statistics.
This allows confirmation with MAC statistics.
Signed-off-by: Shradha Shah <sshah@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/sfc/ethtool.c | 58 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/rx.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/tx.c | 4 |
4 files changed, 66 insertions, 2 deletions
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 03fe4e715024..cad258a78708 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c | |||
@@ -359,6 +359,37 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, | |||
359 | return n; | 359 | return n; |
360 | } | 360 | } |
361 | 361 | ||
362 | static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings) | ||
363 | { | ||
364 | size_t n_stats = 0; | ||
365 | struct efx_channel *channel; | ||
366 | |||
367 | efx_for_each_channel(channel, efx) { | ||
368 | if (efx_channel_has_tx_queues(channel)) { | ||
369 | n_stats++; | ||
370 | if (strings != NULL) { | ||
371 | snprintf(strings, ETH_GSTRING_LEN, | ||
372 | "tx-%u.tx_packets", | ||
373 | channel->tx_queue[0].queue / | ||
374 | EFX_TXQ_TYPES); | ||
375 | |||
376 | strings += ETH_GSTRING_LEN; | ||
377 | } | ||
378 | } | ||
379 | } | ||
380 | efx_for_each_channel(channel, efx) { | ||
381 | if (efx_channel_has_rx_queue(channel)) { | ||
382 | n_stats++; | ||
383 | if (strings != NULL) { | ||
384 | snprintf(strings, ETH_GSTRING_LEN, | ||
385 | "rx-%d.rx_packets", channel->channel); | ||
386 | strings += ETH_GSTRING_LEN; | ||
387 | } | ||
388 | } | ||
389 | } | ||
390 | return n_stats; | ||
391 | } | ||
392 | |||
362 | static int efx_ethtool_get_sset_count(struct net_device *net_dev, | 393 | static int efx_ethtool_get_sset_count(struct net_device *net_dev, |
363 | int string_set) | 394 | int string_set) |
364 | { | 395 | { |
@@ -367,8 +398,9 @@ static int efx_ethtool_get_sset_count(struct net_device *net_dev, | |||
367 | switch (string_set) { | 398 | switch (string_set) { |
368 | case ETH_SS_STATS: | 399 | case ETH_SS_STATS: |
369 | return efx->type->describe_stats(efx, NULL) + | 400 | return efx->type->describe_stats(efx, NULL) + |
370 | EFX_ETHTOOL_SW_STAT_COUNT + | 401 | EFX_ETHTOOL_SW_STAT_COUNT + |
371 | efx_ptp_describe_stats(efx, NULL); | 402 | efx_describe_per_queue_stats(efx, NULL) + |
403 | efx_ptp_describe_stats(efx, NULL); | ||
372 | case ETH_SS_TEST: | 404 | case ETH_SS_TEST: |
373 | return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL); | 405 | return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL); |
374 | default: | 406 | default: |
@@ -390,6 +422,8 @@ static void efx_ethtool_get_strings(struct net_device *net_dev, | |||
390 | strlcpy(strings + i * ETH_GSTRING_LEN, | 422 | strlcpy(strings + i * ETH_GSTRING_LEN, |
391 | efx_sw_stat_desc[i].name, ETH_GSTRING_LEN); | 423 | efx_sw_stat_desc[i].name, ETH_GSTRING_LEN); |
392 | strings += EFX_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN; | 424 | strings += EFX_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN; |
425 | strings += (efx_describe_per_queue_stats(efx, strings) * | ||
426 | ETH_GSTRING_LEN); | ||
393 | efx_ptp_describe_stats(efx, strings); | 427 | efx_ptp_describe_stats(efx, strings); |
394 | break; | 428 | break; |
395 | case ETH_SS_TEST: | 429 | case ETH_SS_TEST: |
@@ -409,6 +443,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, | |||
409 | const struct efx_sw_stat_desc *stat; | 443 | const struct efx_sw_stat_desc *stat; |
410 | struct efx_channel *channel; | 444 | struct efx_channel *channel; |
411 | struct efx_tx_queue *tx_queue; | 445 | struct efx_tx_queue *tx_queue; |
446 | struct efx_rx_queue *rx_queue; | ||
412 | int i; | 447 | int i; |
413 | 448 | ||
414 | spin_lock_bh(&efx->stats_lock); | 449 | spin_lock_bh(&efx->stats_lock); |
@@ -444,6 +479,25 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, | |||
444 | 479 | ||
445 | spin_unlock_bh(&efx->stats_lock); | 480 | spin_unlock_bh(&efx->stats_lock); |
446 | 481 | ||
482 | efx_for_each_channel(channel, efx) { | ||
483 | if (efx_channel_has_tx_queues(channel)) { | ||
484 | *data = 0; | ||
485 | efx_for_each_channel_tx_queue(tx_queue, channel) { | ||
486 | *data += tx_queue->tx_packets; | ||
487 | } | ||
488 | data++; | ||
489 | } | ||
490 | } | ||
491 | efx_for_each_channel(channel, efx) { | ||
492 | if (efx_channel_has_rx_queue(channel)) { | ||
493 | *data = 0; | ||
494 | efx_for_each_channel_rx_queue(rx_queue, channel) { | ||
495 | *data += rx_queue->rx_packets; | ||
496 | } | ||
497 | data++; | ||
498 | } | ||
499 | } | ||
500 | |||
447 | efx_ptp_update_stats(efx, data); | 501 | efx_ptp_update_stats(efx, data); |
448 | } | 502 | } |
449 | 503 | ||
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 8a02d45ed667..fb2e3bfeb2c2 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -249,6 +249,8 @@ struct efx_tx_queue { | |||
249 | unsigned int tso_packets; | 249 | unsigned int tso_packets; |
250 | unsigned int pushes; | 250 | unsigned int pushes; |
251 | unsigned int pio_packets; | 251 | unsigned int pio_packets; |
252 | /* Statistics to supplement MAC stats */ | ||
253 | unsigned long tx_packets; | ||
252 | 254 | ||
253 | /* Members shared between paths and sometimes updated */ | 255 | /* Members shared between paths and sometimes updated */ |
254 | unsigned int empty_read_count ____cacheline_aligned_in_smp; | 256 | unsigned int empty_read_count ____cacheline_aligned_in_smp; |
@@ -358,6 +360,8 @@ struct efx_rx_queue { | |||
358 | unsigned int recycle_count; | 360 | unsigned int recycle_count; |
359 | struct timer_list slow_fill; | 361 | struct timer_list slow_fill; |
360 | unsigned int slow_fill_count; | 362 | unsigned int slow_fill_count; |
363 | /* Statistics to supplement MAC stats */ | ||
364 | unsigned long rx_packets; | ||
361 | }; | 365 | }; |
362 | 366 | ||
363 | enum efx_sync_events_state { | 367 | enum efx_sync_events_state { |
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index bf537a2a901f..a7bb63a7a521 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c | |||
@@ -530,6 +530,8 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, | |||
530 | struct efx_channel *channel = efx_rx_queue_channel(rx_queue); | 530 | struct efx_channel *channel = efx_rx_queue_channel(rx_queue); |
531 | struct efx_rx_buffer *rx_buf; | 531 | struct efx_rx_buffer *rx_buf; |
532 | 532 | ||
533 | rx_queue->rx_packets++; | ||
534 | |||
533 | rx_buf = efx_rx_buffer(rx_queue, index); | 535 | rx_buf = efx_rx_buffer(rx_queue, index); |
534 | rx_buf->flags |= flags; | 536 | rx_buf->flags |= flags; |
535 | 537 | ||
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index ede8dcca0ff3..283e5f87b09f 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c | |||
@@ -452,6 +452,8 @@ finish_packet: | |||
452 | /* Pass off to hardware */ | 452 | /* Pass off to hardware */ |
453 | efx_nic_push_buffers(tx_queue); | 453 | efx_nic_push_buffers(tx_queue); |
454 | 454 | ||
455 | tx_queue->tx_packets++; | ||
456 | |||
455 | efx_tx_maybe_stop_queue(tx_queue); | 457 | efx_tx_maybe_stop_queue(tx_queue); |
456 | 458 | ||
457 | return NETDEV_TX_OK; | 459 | return NETDEV_TX_OK; |
@@ -1245,6 +1247,8 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue, | |||
1245 | 1247 | ||
1246 | ++tx_queue->tso_packets; | 1248 | ++tx_queue->tso_packets; |
1247 | 1249 | ||
1250 | ++tx_queue->tx_packets; | ||
1251 | |||
1248 | return 0; | 1252 | return 0; |
1249 | } | 1253 | } |
1250 | 1254 | ||