Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sfc: implement per-queue rx drop and overrun stats

Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Edward Cree and committed by
David S. Miller
07e5fa5b cfa63b90

+31 -2
+13 -2
drivers/net/ethernet/sfc/efx.c
··· 638 638 rx_queue = efx_channel_get_rx_queue(channel); 639 639 /* Count only packets since last time datapath was started */ 640 640 stats->packets = rx_queue->rx_packets - rx_queue->old_rx_packets; 641 + stats->hw_drops = efx_get_queue_stat_rx_hw_drops(channel) - 642 + channel->old_n_rx_hw_drops; 643 + stats->hw_drop_overruns = channel->n_rx_nodesc_trunc - 644 + channel->old_n_rx_hw_drop_overruns; 641 645 } 642 646 643 647 static void efx_get_queue_stats_tx(struct net_device *net_dev, int idx, ··· 672 668 struct efx_channel *channel; 673 669 674 670 rx->packets = 0; 671 + rx->hw_drops = 0; 672 + rx->hw_drop_overruns = 0; 675 673 tx->packets = 0; 676 674 tx->bytes = 0; 677 675 ··· 682 676 */ 683 677 efx_for_each_channel(channel, efx) { 684 678 rx_queue = efx_channel_get_rx_queue(channel); 685 - if (channel->channel >= net_dev->real_num_rx_queues) 679 + if (channel->channel >= net_dev->real_num_rx_queues) { 686 680 rx->packets += rx_queue->rx_packets; 687 - else 681 + rx->hw_drops += efx_get_queue_stat_rx_hw_drops(channel); 682 + rx->hw_drop_overruns += channel->n_rx_nodesc_trunc; 683 + } else { 688 684 rx->packets += rx_queue->old_rx_packets; 685 + rx->hw_drops += channel->old_n_rx_hw_drops; 686 + rx->hw_drop_overruns += channel->old_n_rx_hw_drop_overruns; 687 + } 689 688 efx_for_each_channel_tx_queue(tx_queue, channel) { 690 689 if (channel->channel < efx->tx_channel_offset || 691 690 channel->channel >= efx->tx_channel_offset +
+4
drivers/net/ethernet/sfc/efx_channels.c
··· 1100 1100 atomic_inc(&efx->active_queues); 1101 1101 } 1102 1102 1103 + /* reset per-queue stats */ 1104 + channel->old_n_rx_hw_drops = efx_get_queue_stat_rx_hw_drops(channel); 1105 + channel->old_n_rx_hw_drop_overruns = channel->n_rx_nodesc_trunc; 1106 + 1103 1107 efx_for_each_channel_rx_queue(rx_queue, channel) { 1104 1108 efx_init_rx_queue(rx_queue); 1105 1109 atomic_inc(&efx->active_queues);
+7
drivers/net/ethernet/sfc/efx_channels.h
··· 43 43 void efx_start_channels(struct efx_nic *efx); 44 44 void efx_stop_channels(struct efx_nic *efx); 45 45 46 + static inline u64 efx_get_queue_stat_rx_hw_drops(struct efx_channel *channel) 47 + { 48 + return channel->n_rx_eth_crc_err + channel->n_rx_frm_trunc + 49 + channel->n_rx_overlength + channel->n_rx_nodesc_trunc + 50 + channel->n_rx_mport_bad; 51 + } 52 + 46 53 void efx_init_napi_channel(struct efx_channel *channel); 47 54 void efx_init_napi(struct efx_nic *efx); 48 55 void efx_fini_napi_channel(struct efx_channel *channel);
+7
drivers/net/ethernet/sfc/net_driver.h
··· 494 494 * @n_rx_xdp_redirect: Count of RX packets redirected to a different NIC by XDP 495 495 * @n_rx_mport_bad: Count of RX packets dropped because their ingress mport was 496 496 * not recognised 497 + * @old_n_rx_hw_drops: Count of all RX packets dropped for any reason as of last 498 + * efx_start_channels() 499 + * @old_n_rx_hw_drop_overruns: Value of @n_rx_nodesc_trunc as of last 500 + * efx_start_channels() 497 501 * @rx_pkt_n_frags: Number of fragments in next packet to be delivered by 498 502 * __efx_rx_packet(), or zero if there is none 499 503 * @rx_pkt_index: Ring index of first buffer for next packet to be delivered ··· 559 555 unsigned int n_rx_xdp_tx; 560 556 unsigned int n_rx_xdp_redirect; 561 557 unsigned int n_rx_mport_bad; 558 + 559 + unsigned int old_n_rx_hw_drops; 560 + unsigned int old_n_rx_hw_drop_overruns; 562 561 563 562 unsigned int rx_pkt_n_frags; 564 563 unsigned int rx_pkt_index;