]> www.infradead.org Git - users/hch/misc.git/commitdiff
octeon_ep: update tx/rx stats locally for persistence
authorShinas Rasheed <srasheed@marvell.com>
Fri, 17 Jan 2025 09:46:51 +0000 (01:46 -0800)
committerJakub Kicinski <kuba@kernel.org>
Sun, 19 Jan 2025 01:26:39 +0000 (17:26 -0800)
Update tx/rx stats locally, so that ndo_get_stats64()
can use that and not rely on per queue resources to obtain statistics.
The latter used to cause race conditions when the device stopped.

Signed-off-by: Shinas Rasheed <srasheed@marvell.com>
Link: https://patch.msgid.link/20250117094653.2588578-3-srasheed@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c
drivers/net/ethernet/marvell/octeon_ep/octep_main.c
drivers/net/ethernet/marvell/octeon_ep/octep_main.h
drivers/net/ethernet/marvell/octeon_ep/octep_rx.c
drivers/net/ethernet/marvell/octeon_ep/octep_rx.h
drivers/net/ethernet/marvell/octeon_ep/octep_tx.c
drivers/net/ethernet/marvell/octeon_ep/octep_tx.h

index 4f4d5818911885b6b9f47c9e1a0c10ee734f5ac1..a88c006ea65b7121825021e4be052142f4e2d455 100644 (file)
@@ -150,17 +150,14 @@ octep_get_ethtool_stats(struct net_device *netdev,
                                    iface_rx_stats,
                                    iface_tx_stats);
 
-       for (q = 0; q < oct->num_oqs; q++) {
-               struct octep_iq *iq = oct->iq[q];
-               struct octep_oq *oq = oct->oq[q];
-
-               tx_packets += iq->stats.instr_completed;
-               tx_bytes += iq->stats.bytes_sent;
-               tx_busy_errors += iq->stats.tx_busy;
-
-               rx_packets += oq->stats.packets;
-               rx_bytes += oq->stats.bytes;
-               rx_alloc_errors += oq->stats.alloc_failures;
+       for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
+               tx_packets += oct->stats_iq[q].instr_completed;
+               tx_bytes += oct->stats_iq[q].bytes_sent;
+               tx_busy_errors += oct->stats_iq[q].tx_busy;
+
+               rx_packets += oct->stats_oq[q].packets;
+               rx_bytes += oct->stats_oq[q].bytes;
+               rx_alloc_errors += oct->stats_oq[q].alloc_failures;
        }
        i = 0;
        data[i++] = rx_packets;
@@ -198,22 +195,18 @@ octep_get_ethtool_stats(struct net_device *netdev,
        data[i++] = iface_rx_stats->err_pkts;
 
        /* Per Tx Queue stats */
-       for (q = 0; q < oct->num_iqs; q++) {
-               struct octep_iq *iq = oct->iq[q];
-
-               data[i++] = iq->stats.instr_posted;
-               data[i++] = iq->stats.instr_completed;
-               data[i++] = iq->stats.bytes_sent;
-               data[i++] = iq->stats.tx_busy;
+       for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
+               data[i++] = oct->stats_iq[q].instr_posted;
+               data[i++] = oct->stats_iq[q].instr_completed;
+               data[i++] = oct->stats_iq[q].bytes_sent;
+               data[i++] = oct->stats_iq[q].tx_busy;
        }
 
        /* Per Rx Queue stats */
-       for (q = 0; q < oct->num_oqs; q++) {
-               struct octep_oq *oq = oct->oq[q];
-
-               data[i++] = oq->stats.packets;
-               data[i++] = oq->stats.bytes;
-               data[i++] = oq->stats.alloc_failures;
+       for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
+               data[i++] = oct->stats_oq[q].packets;
+               data[i++] = oct->stats_oq[q].bytes;
+               data[i++] = oct->stats_oq[q].alloc_failures;
        }
 }
 
index 730aa5632cceee6eff388c01f056f6eb67f3de0b..a89f80bac39b8dab7152f08ed866321f52669e08 100644 (file)
@@ -822,7 +822,7 @@ static inline int octep_iq_full_check(struct octep_iq *iq)
        if (unlikely(IQ_INSTR_SPACE(iq) >
                     OCTEP_WAKE_QUEUE_THRESHOLD)) {
                netif_start_subqueue(iq->netdev, iq->q_no);
-               iq->stats.restart_cnt++;
+               iq->stats->restart_cnt++;
                return 0;
        }
 
@@ -960,7 +960,7 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb,
        wmb();
        /* Ring Doorbell to notify the NIC of new packets */
        writel(iq->fill_cnt, iq->doorbell_reg);
-       iq->stats.instr_posted += iq->fill_cnt;
+       iq->stats->instr_posted += iq->fill_cnt;
        iq->fill_cnt = 0;
        return NETDEV_TX_OK;
 
@@ -991,22 +991,19 @@ dma_map_err:
 static void octep_get_stats64(struct net_device *netdev,
                              struct rtnl_link_stats64 *stats)
 {
-       u64 tx_packets, tx_bytes, rx_packets, rx_bytes;
        struct octep_device *oct = netdev_priv(netdev);
+       u64 tx_packets, tx_bytes, rx_packets, rx_bytes;
        int q;
 
        tx_packets = 0;
        tx_bytes = 0;
        rx_packets = 0;
        rx_bytes = 0;
-       for (q = 0; q < oct->num_oqs; q++) {
-               struct octep_iq *iq = oct->iq[q];
-               struct octep_oq *oq = oct->oq[q];
-
-               tx_packets += iq->stats.instr_completed;
-               tx_bytes += iq->stats.bytes_sent;
-               rx_packets += oq->stats.packets;
-               rx_bytes += oq->stats.bytes;
+       for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
+               tx_packets += oct->stats_iq[q].instr_completed;
+               tx_bytes += oct->stats_iq[q].bytes_sent;
+               rx_packets += oct->stats_oq[q].packets;
+               rx_bytes += oct->stats_oq[q].bytes;
        }
        stats->tx_packets = tx_packets;
        stats->tx_bytes = tx_bytes;
index fee59e0e0138feecdab5bf8fecd9334172bd894a..936b786f428168bfccd9479482939fc7892b0786 100644 (file)
@@ -257,11 +257,17 @@ struct octep_device {
        /* Pointers to Octeon Tx queues */
        struct octep_iq *iq[OCTEP_MAX_IQ];
 
+       /* Per iq stats */
+       struct octep_iq_stats stats_iq[OCTEP_MAX_IQ];
+
        /* Rx queues (OQ: Output Queue) */
        u16 num_oqs;
        /* Pointers to Octeon Rx queues */
        struct octep_oq *oq[OCTEP_MAX_OQ];
 
+       /* Per oq stats */
+       struct octep_oq_stats stats_oq[OCTEP_MAX_OQ];
+
        /* Hardware port number of the PCIe interface */
        u16 pcie_port;
 
index 8af75cb37c3ee8e6a0e0d85fde4f9a9dc14442fd..82b6b19e76b47abda14f8ffb9f47ddbfe50feb4b 100644 (file)
@@ -87,7 +87,7 @@ static int octep_oq_refill(struct octep_device *oct, struct octep_oq *oq)
                page = dev_alloc_page();
                if (unlikely(!page)) {
                        dev_err(oq->dev, "refill: rx buffer alloc failed\n");
-                       oq->stats.alloc_failures++;
+                       oq->stats->alloc_failures++;
                        break;
                }
 
@@ -98,7 +98,7 @@ static int octep_oq_refill(struct octep_device *oct, struct octep_oq *oq)
                                "OQ-%d buffer refill: DMA mapping error!\n",
                                oq->q_no);
                        put_page(page);
-                       oq->stats.alloc_failures++;
+                       oq->stats->alloc_failures++;
                        break;
                }
                oq->buff_info[refill_idx].page = page;
@@ -134,6 +134,7 @@ static int octep_setup_oq(struct octep_device *oct, int q_no)
        oq->netdev = oct->netdev;
        oq->dev = &oct->pdev->dev;
        oq->q_no = q_no;
+       oq->stats = &oct->stats_oq[q_no];
        oq->max_count = CFG_GET_OQ_NUM_DESC(oct->conf);
        oq->ring_size_mask = oq->max_count - 1;
        oq->buffer_size = CFG_GET_OQ_BUF_SIZE(oct->conf);
@@ -443,7 +444,7 @@ static int __octep_oq_process_rx(struct octep_device *oct,
                if (!skb) {
                        octep_oq_drop_rx(oq, buff_info,
                                         &read_idx, &desc_used);
-                       oq->stats.alloc_failures++;
+                       oq->stats->alloc_failures++;
                        continue;
                }
                skb_reserve(skb, data_offset);
@@ -494,8 +495,8 @@ static int __octep_oq_process_rx(struct octep_device *oct,
 
        oq->host_read_idx = read_idx;
        oq->refill_count += desc_used;
-       oq->stats.packets += pkt;
-       oq->stats.bytes += rx_bytes;
+       oq->stats->packets += pkt;
+       oq->stats->bytes += rx_bytes;
 
        return pkt;
 }
index 3b08e2d560dc39943bbd8d38f07aa0829bcb512e..b4696c93d0e6a9fa0263d90324ee57e829cfe472 100644 (file)
@@ -186,8 +186,8 @@ struct octep_oq {
         */
        u8 __iomem *pkts_sent_reg;
 
-       /* Statistics for this OQ. */
-       struct octep_oq_stats stats;
+       /* Pointer to statistics for this OQ. */
+       struct octep_oq_stats *stats;
 
        /* Packets pending to be processed */
        u32 pkts_pending;
index 06851b78aa28c8be946cfc847f0d1f16c6e5bc2b..08ee90013fef3bd98ea4089d8f027dd362874180 100644 (file)
@@ -81,9 +81,9 @@ int octep_iq_process_completions(struct octep_iq *iq, u16 budget)
        }
 
        iq->pkts_processed += compl_pkts;
-       iq->stats.instr_completed += compl_pkts;
-       iq->stats.bytes_sent += compl_bytes;
-       iq->stats.sgentry_sent += compl_sg;
+       iq->stats->instr_completed += compl_pkts;
+       iq->stats->bytes_sent += compl_bytes;
+       iq->stats->sgentry_sent += compl_sg;
        iq->flush_index = fi;
 
        netdev_tx_completed_queue(iq->netdev_q, compl_pkts, compl_bytes);
@@ -187,6 +187,7 @@ static int octep_setup_iq(struct octep_device *oct, int q_no)
        iq->netdev = oct->netdev;
        iq->dev = &oct->pdev->dev;
        iq->q_no = q_no;
+       iq->stats = &oct->stats_iq[q_no];
        iq->max_count = CFG_GET_IQ_NUM_DESC(oct->conf);
        iq->ring_size_mask = iq->max_count - 1;
        iq->fill_threshold = CFG_GET_IQ_DB_MIN(oct->conf);
index 875a2c34091ffeaffbf05dbfd4da37723a24d813..58fb39dda977c00f499357ecf6cfc74cac2922a0 100644 (file)
@@ -170,8 +170,8 @@ struct octep_iq {
         */
        u16 flush_index;
 
-       /* Statistics for this input queue. */
-       struct octep_iq_stats stats;
+       /* Pointer to statistics for this input queue. */
+       struct octep_iq_stats *stats;
 
        /* Pointer to the Virtual Base addr of the input ring. */
        struct octep_tx_desc_hw *desc_ring;