From: Shay Agroskin <shayagr@xxxxxxxxxx> Date: Mon, 29 Nov 2021 15:34:19 +0200 > Alexander Lobakin <alexandr.lobakin@xxxxxxxxx> writes: > > > ena driver has 6 XDP counters collected per-channel. Add > > callbacks > > for getting the number of channels and those counters using > > generic > > XDP stats infra. > > > > Signed-off-by: Alexander Lobakin <alexandr.lobakin@xxxxxxxxx> > > Reviewed-by: Jesse Brandeburg <jesse.brandeburg@xxxxxxxxx> > > --- > > drivers/net/ethernet/amazon/ena/ena_netdev.c | 53 > > ++++++++++++++++++++ > > 1 file changed, 53 insertions(+) > > > > diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c > > b/drivers/net/ethernet/amazon/ena/ena_netdev.c > > index 7d5d885d85d5..83e9b85cc998 100644 > > --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c > > +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c > > @@ -3313,12 +3313,65 @@ static void ena_get_stats64(struct > > net_device *netdev, > > stats->tx_errors = 0; > > } > > > > +static int ena_get_xdp_stats_nch(const struct net_device > > *netdev, u32 attr_id) > > +{ > > + const struct ena_adapter *adapter = netdev_priv(netdev); > > + > > + switch (attr_id) { > > + case IFLA_XDP_XSTATS_TYPE_XDP: > > + return adapter->num_io_queues; > > + default: > > + return -EOPNOTSUPP; > > + } > > +} > > + > > +static int ena_get_xdp_stats(const struct net_device *netdev, > > u32 attr_id, > > + void *attr_data) > > +{ > > + const struct ena_adapter *adapter = netdev_priv(netdev); > > + struct ifla_xdp_stats *xdp_stats = attr_data; > > + u32 i; > > + > > + switch (attr_id) { > > + case IFLA_XDP_XSTATS_TYPE_XDP: > > + break; > > + default: > > + return -EOPNOTSUPP; > > + } > > + > > + for (i = 0; i < adapter->num_io_queues; i++) { > > + const struct u64_stats_sync *syncp; > > + const struct ena_stats_rx *stats; > > + u32 start; > > + > > + stats = &adapter->rx_ring[i].rx_stats; > > + syncp = &adapter->rx_ring[i].syncp; > > + > > + do { > > + start = u64_stats_fetch_begin_irq(syncp); > > + > > + xdp_stats->drop = stats->xdp_drop; > > + xdp_stats->pass = stats->xdp_pass; > > + xdp_stats->tx = stats->xdp_tx; > > + xdp_stats->redirect = stats->xdp_redirect; > > + xdp_stats->aborted = stats->xdp_aborted; > > + xdp_stats->invalid = stats->xdp_invalid; > > + } while (u64_stats_fetch_retry_irq(syncp, start)); > > + > > + xdp_stats++; > > + } > > + > > + return 0; > > +} > > + > > Hi, > thank you for the time you took in adding ENA support, this code > doesn't update the XDP TX queues (which only available when an XDP > program is loaded). > > In theory the following patch should fix it, but I was unable to > compile your version of iproute2 and test the patch properly. Can > you please let me know if I need to do anything special to bring > up your version of iproute2 and test this patch? Did you clone 'xdp_stats' branch? I've just rechecked on a freshly cloned copy, works for me. > diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c > b/drivers/net/ethernet/amazon/ena/ena_netdev.c > index 7d5d885d8..4e89a7d60 100644 > --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c > +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c > @@ -3313,12 +3313,85 @@ static void ena_get_stats64(struct > net_device *netdev, > stats->tx_errors = 0; > } > > +static int ena_get_xdp_stats_nch(const struct net_device *netdev, > u32 attr_id) > +{ > + const struct ena_adapter *adapter = netdev_priv(netdev); > + > + switch (attr_id) { > + case IFLA_XDP_XSTATS_TYPE_XDP: > + return adapter->num_io_queues; > + default: > + return -EOPNOTSUPP; > + } > +} > + > +static int ena_get_xdp_stats(const struct net_device *netdev, u32 > attr_id, > + void *attr_data) > +{ > + const struct ena_adapter *adapter = netdev_priv(netdev); > + struct ifla_xdp_stats *xdp_stats = attr_data; > + const struct u64_stats_sync *syncp; > + u32 start; > + u32 i; > + > + switch (attr_id) { > + case IFLA_XDP_XSTATS_TYPE_XDP: > + break; > + default: > + return -EOPNOTSUPP; > + } > + > + for (i = 0; i < adapter->num_io_queues; i++) { > + const struct ena_stats_rx *rx_stats; > + > + rx_stats = &adapter->rx_ring[i].rx_stats; > + syncp = &adapter->rx_ring[i].syncp; > + > + do { > + start = u64_stats_fetch_begin_irq(syncp); > + > + xdp_stats->drop = rx_stats->xdp_drop; > + xdp_stats->pass = rx_stats->xdp_pass; > + xdp_stats->tx = rx_stats->xdp_tx; > + xdp_stats->redirect = > rx_stats->xdp_redirect; > + xdp_stats->aborted = > rx_stats->xdp_aborted; > + xdp_stats->invalid = > rx_stats->xdp_invalid; > + } while (u64_stats_fetch_retry_irq(syncp, start)); > + > + xdp_stats++; > + } > + > + xdp_stats = attr_data; > + /* xdp_num_queues can be 0 if an XDP program isn't loaded > */ > + for (i = 0; i < adapter->xdp_num_queues; i++) { > + const struct ena_stats_tx *tx_stats; > + > + tx_stats = > &adapter->rx_ring[i].xdp_ring->tx_stats; > + syncp = &adapter->rx_ring[i].xdp_ring->syncp; > + > + do { > + start = u64_stats_fetch_begin_irq(syncp); > + > + xdp_stats->xmit_packets = tx_stats->cnt; > + xdp_stats->xmit_bytes = tx_stats->bytes; > + xdp_stats->xmit_errors = > tx_stats->dma_mapping_err + > + > tx_stats->prepare_ctx_err; > + } while (u64_stats_fetch_retry_irq(syncp, start)); > + > + xdp_stats++; > + } > + > + return 0; > +} > + > static const struct net_device_ops ena_netdev_ops = { > .ndo_open = ena_open, > .ndo_stop = ena_close, > .ndo_start_xmit = ena_start_xmit, > .ndo_select_queue = ena_select_queue, > .ndo_get_stats64 = ena_get_stats64, > + .ndo_get_xdp_stats_nch = ena_get_xdp_stats_nch, > + .ndo_get_xdp_stats = ena_get_xdp_stats, > .ndo_tx_timeout = ena_tx_timeout, > .ndo_change_mtu = ena_change_mtu, > .ndo_set_mac_address = NULL, I'll update it in v3 and mention you, thanks! Al