Skip to content

Commit d81db24

Browse files
Netanel Belgazaldavem330
authored andcommitted
net/ena: refactor ena_get_stats64 to be atomic context safe
ndo_get_stat64() can be called from atomic context, but the current implementation sends an admin command to retrieve the statistics from the device. This admin command can sleep. This patch re-factors the implementation of ena_get_stats64() to use the {rx,tx}bytes/count from the driver's inner counters, and to obtain the rx drop counter from the asynchronous keep alive (heart bit) event. Signed-off-by: Netanel Belgazal <netanel@annapurnalabs.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 22b331c commit d81db24

File tree

3 files changed

+42
-15
lines changed

3 files changed

+42
-15
lines changed

drivers/net/ethernet/amazon/ena/ena_admin_defs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,14 @@ struct ena_admin_aenq_link_change_desc {
873873
u32 flags;
874874
};
875875

876+
struct ena_admin_aenq_keep_alive_desc {
877+
struct ena_admin_aenq_common_desc aenq_common_desc;
878+
879+
u32 rx_drops_low;
880+
881+
u32 rx_drops_high;
882+
};
883+
876884
struct ena_admin_ena_mmio_req_read_less_resp {
877885
u16 req_id;
878886

drivers/net/ethernet/amazon/ena/ena_netdev.c

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,28 +2169,46 @@ static void ena_get_stats64(struct net_device *netdev,
21692169
struct rtnl_link_stats64 *stats)
21702170
{
21712171
struct ena_adapter *adapter = netdev_priv(netdev);
2172-
struct ena_admin_basic_stats ena_stats;
2173-
int rc;
2172+
struct ena_ring *rx_ring, *tx_ring;
2173+
unsigned int start;
2174+
u64 rx_drops;
2175+
int i;
21742176

21752177
if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
21762178
return;
21772179

2178-
rc = ena_com_get_dev_basic_stats(adapter->ena_dev, &ena_stats);
2179-
if (rc)
2180-
return;
2180+
for (i = 0; i < adapter->num_queues; i++) {
2181+
u64 bytes, packets;
2182+
2183+
tx_ring = &adapter->tx_ring[i];
21812184

2182-
stats->tx_bytes = ((u64)ena_stats.tx_bytes_high << 32) |
2183-
ena_stats.tx_bytes_low;
2184-
stats->rx_bytes = ((u64)ena_stats.rx_bytes_high << 32) |
2185-
ena_stats.rx_bytes_low;
2185+
do {
2186+
start = u64_stats_fetch_begin_irq(&tx_ring->syncp);
2187+
packets = tx_ring->tx_stats.cnt;
2188+
bytes = tx_ring->tx_stats.bytes;
2189+
} while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
21862190

2187-
stats->rx_packets = ((u64)ena_stats.rx_pkts_high << 32) |
2188-
ena_stats.rx_pkts_low;
2189-
stats->tx_packets = ((u64)ena_stats.tx_pkts_high << 32) |
2190-
ena_stats.tx_pkts_low;
2191+
stats->tx_packets += packets;
2192+
stats->tx_bytes += bytes;
2193+
2194+
rx_ring = &adapter->rx_ring[i];
2195+
2196+
do {
2197+
start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
2198+
packets = rx_ring->rx_stats.cnt;
2199+
bytes = rx_ring->rx_stats.bytes;
2200+
} while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
2201+
2202+
stats->rx_packets += packets;
2203+
stats->rx_bytes += bytes;
2204+
}
2205+
2206+
do {
2207+
start = u64_stats_fetch_begin_irq(&adapter->syncp);
2208+
rx_drops = adapter->dev_stats.rx_drops;
2209+
} while (u64_stats_fetch_retry_irq(&adapter->syncp, start));
21912210

2192-
stats->rx_dropped = ((u64)ena_stats.rx_drops_high << 32) |
2193-
ena_stats.rx_drops_low;
2211+
stats->rx_dropped = rx_drops;
21942212

21952213
stats->multicast = 0;
21962214
stats->collisions = 0;

drivers/net/ethernet/amazon/ena/ena_netdev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ struct ena_stats_dev {
241241
u64 interface_up;
242242
u64 interface_down;
243243
u64 admin_q_pause;
244+
u64 rx_drops;
244245
};
245246

246247
enum ena_flags_t {

0 commit comments

Comments
 (0)