From: Greg Kroah-Hartman Date: Sat, 10 Jan 2026 13:51:14 +0000 (+0100) Subject: drop queue-6.1/net-stmmac-protect-updates-of-64-bit-statistics-counters.patch X-Git-Tag: v6.1.160~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03e92d49cc8eb2f937b740aec5d6caf2260d0e94;p=thirdparty%2Fkernel%2Fstable-queue.git drop queue-6.1/net-stmmac-protect-updates-of-64-bit-statistics-counters.patch Does not work. --- diff --git a/queue-6.1/net-stmmac-protect-updates-of-64-bit-statistics-counters.patch b/queue-6.1/net-stmmac-protect-updates-of-64-bit-statistics-counters.patch deleted file mode 100644 index e01b0247a7..0000000000 --- a/queue-6.1/net-stmmac-protect-updates-of-64-bit-statistics-counters.patch +++ /dev/null @@ -1,740 +0,0 @@ -From 38cc3c6dcc09dc3a1800b5ec22aef643ca11eab8 Mon Sep 17 00:00:00 2001 -From: Petr Tesarik -Date: Sat, 3 Feb 2024 20:09:27 +0100 -Subject: net: stmmac: protect updates of 64-bit statistics counters - -From: Petr Tesarik - -commit 38cc3c6dcc09dc3a1800b5ec22aef643ca11eab8 upstream. - -As explained by a comment in , write side of struct -u64_stats_sync must ensure mutual exclusion, or one seqcount update could -be lost on 32-bit platforms, thus blocking readers forever. Such lockups -have been observed in real world after stmmac_xmit() on one CPU raced with -stmmac_napi_poll_tx() on another CPU. - -To fix the issue without introducing a new lock, split the statics into -three parts: - -1. fields updated only under the tx queue lock, -2. fields updated only during NAPI poll, -3. fields updated only from interrupt context, - -Updates to fields in the first two groups are already serialized through -other locks. It is sufficient to split the existing struct u64_stats_sync -so that each group has its own. - -Note that tx_set_ic_bit is updated from both contexts. Split this counter -so that each context gets its own, and calculate their sum to get the total -value in stmmac_get_ethtool_stats(). - -For the third group, multiple interrupts may be processed by different CPUs -at the same time, but interrupts on the same CPU will not nest. Move fields -from this group to a newly created per-cpu struct stmmac_pcpu_stats. - -Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary") -Link: https://lore.kernel.org/netdev/Za173PhviYg-1qIn@torres.zugschlus.de/t/ -Cc: stable@vger.kernel.org -Signed-off-by: Petr Tesarik -Reviewed-by: Jisheng Zhang -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/ethernet/stmicro/stmmac/common.h | 56 +++++--- - drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 15 +- - drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 15 +- - drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 15 +- - drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 15 +- - drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 129 ++++++++++++------ - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 133 +++++++++---------- - 7 files changed, 221 insertions(+), 157 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/common.h -+++ b/drivers/net/ethernet/stmicro/stmmac/common.h -@@ -58,28 +58,51 @@ - #undef FRAME_FILTER_DEBUG - /* #define FRAME_FILTER_DEBUG */ - -+struct stmmac_q_tx_stats { -+ u64_stats_t tx_bytes; -+ u64_stats_t tx_set_ic_bit; -+ u64_stats_t tx_tso_frames; -+ u64_stats_t tx_tso_nfrags; -+}; -+ -+struct stmmac_napi_tx_stats { -+ u64_stats_t tx_packets; -+ u64_stats_t tx_pkt_n; -+ u64_stats_t poll; -+ u64_stats_t tx_clean; -+ u64_stats_t tx_set_ic_bit; -+}; -+ - struct stmmac_txq_stats { -- u64 tx_bytes; -- u64 tx_packets; -- u64 tx_pkt_n; -- u64 tx_normal_irq_n; -- u64 napi_poll; -- u64 tx_clean; -- u64 tx_set_ic_bit; -- u64 tx_tso_frames; -- u64 tx_tso_nfrags; -- struct u64_stats_sync syncp; -+ /* Updates protected by tx queue lock. */ -+ struct u64_stats_sync q_syncp; -+ struct stmmac_q_tx_stats q; -+ -+ /* Updates protected by NAPI poll logic. */ -+ struct u64_stats_sync napi_syncp; -+ struct stmmac_napi_tx_stats napi; - } ____cacheline_aligned_in_smp; - -+struct stmmac_napi_rx_stats { -+ u64_stats_t rx_bytes; -+ u64_stats_t rx_packets; -+ u64_stats_t rx_pkt_n; -+ u64_stats_t poll; -+}; -+ - struct stmmac_rxq_stats { -- u64 rx_bytes; -- u64 rx_packets; -- u64 rx_pkt_n; -- u64 rx_normal_irq_n; -- u64 napi_poll; -- struct u64_stats_sync syncp; -+ /* Updates protected by NAPI poll logic. */ -+ struct u64_stats_sync napi_syncp; -+ struct stmmac_napi_rx_stats napi; - } ____cacheline_aligned_in_smp; - -+/* Updates on each CPU protected by not allowing nested irqs. */ -+struct stmmac_pcpu_stats { -+ struct u64_stats_sync syncp; -+ u64_stats_t rx_normal_irq_n[MTL_MAX_TX_QUEUES]; -+ u64_stats_t tx_normal_irq_n[MTL_MAX_RX_QUEUES]; -+}; -+ - /* Extra statistic and debug information exposed by ethtool */ - struct stmmac_extra_stats { - /* Transmit errors */ -@@ -204,6 +227,7 @@ struct stmmac_extra_stats { - /* per queue statistics */ - struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES]; - struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES]; -+ struct stmmac_pcpu_stats __percpu *pcpu_stats; - unsigned long rx_dropped; - unsigned long rx_errors; - unsigned long tx_dropped; ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c -@@ -440,8 +440,7 @@ static int sun8i_dwmac_dma_interrupt(str - struct stmmac_extra_stats *x, u32 chan, - u32 dir) - { -- struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; -- struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; -+ struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats); - int ret = 0; - u32 v; - -@@ -454,9 +453,9 @@ static int sun8i_dwmac_dma_interrupt(str - - if (v & EMAC_TX_INT) { - ret |= handle_tx; -- u64_stats_update_begin(&txq_stats->syncp); -- txq_stats->tx_normal_irq_n++; -- u64_stats_update_end(&txq_stats->syncp); -+ u64_stats_update_begin(&stats->syncp); -+ u64_stats_inc(&stats->tx_normal_irq_n[chan]); -+ u64_stats_update_end(&stats->syncp); - } - - if (v & EMAC_TX_DMA_STOP_INT) -@@ -478,9 +477,9 @@ static int sun8i_dwmac_dma_interrupt(str - - if (v & EMAC_RX_INT) { - ret |= handle_rx; -- u64_stats_update_begin(&rxq_stats->syncp); -- rxq_stats->rx_normal_irq_n++; -- u64_stats_update_end(&rxq_stats->syncp); -+ u64_stats_update_begin(&stats->syncp); -+ u64_stats_inc(&stats->rx_normal_irq_n[chan]); -+ u64_stats_update_end(&stats->syncp); - } - - if (v & EMAC_RX_BUF_UA_INT) ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c -@@ -171,8 +171,7 @@ int dwmac4_dma_interrupt(struct stmmac_p - const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; - u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan)); - u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan)); -- struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; -- struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; -+ struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats); - int ret = 0; - - if (dir == DMA_DIR_RX) -@@ -201,15 +200,15 @@ int dwmac4_dma_interrupt(struct stmmac_p - } - /* TX/RX NORMAL interrupts */ - if (likely(intr_status & DMA_CHAN_STATUS_RI)) { -- u64_stats_update_begin(&rxq_stats->syncp); -- rxq_stats->rx_normal_irq_n++; -- u64_stats_update_end(&rxq_stats->syncp); -+ u64_stats_update_begin(&stats->syncp); -+ u64_stats_inc(&stats->rx_normal_irq_n[chan]); -+ u64_stats_update_end(&stats->syncp); - ret |= handle_rx; - } - if (likely(intr_status & DMA_CHAN_STATUS_TI)) { -- u64_stats_update_begin(&txq_stats->syncp); -- txq_stats->tx_normal_irq_n++; -- u64_stats_update_end(&txq_stats->syncp); -+ u64_stats_update_begin(&stats->syncp); -+ u64_stats_inc(&stats->tx_normal_irq_n[chan]); -+ u64_stats_update_end(&stats->syncp); - ret |= handle_tx; - } - ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c -@@ -162,8 +162,7 @@ static void show_rx_process_state(unsign - int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, - struct stmmac_extra_stats *x, u32 chan, u32 dir) - { -- struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; -- struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; -+ struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats); - int ret = 0; - /* read the status register (CSR5) */ - u32 intr_status = readl(ioaddr + DMA_STATUS); -@@ -215,16 +214,16 @@ int dwmac_dma_interrupt(struct stmmac_pr - u32 value = readl(ioaddr + DMA_INTR_ENA); - /* to schedule NAPI on real RIE event. */ - if (likely(value & DMA_INTR_ENA_RIE)) { -- u64_stats_update_begin(&rxq_stats->syncp); -- rxq_stats->rx_normal_irq_n++; -- u64_stats_update_end(&rxq_stats->syncp); -+ u64_stats_update_begin(&stats->syncp); -+ u64_stats_inc(&stats->rx_normal_irq_n[chan]); -+ u64_stats_update_end(&stats->syncp); - ret |= handle_rx; - } - } - if (likely(intr_status & DMA_STATUS_TI)) { -- u64_stats_update_begin(&txq_stats->syncp); -- txq_stats->tx_normal_irq_n++; -- u64_stats_update_end(&txq_stats->syncp); -+ u64_stats_update_begin(&stats->syncp); -+ u64_stats_inc(&stats->tx_normal_irq_n[chan]); -+ u64_stats_update_end(&stats->syncp); - ret |= handle_tx; - } - if (unlikely(intr_status & DMA_STATUS_ERI)) ---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c -@@ -333,8 +333,7 @@ static int dwxgmac2_dma_interrupt(struct - struct stmmac_extra_stats *x, u32 chan, - u32 dir) - { -- struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; -- struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; -+ struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats); - u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan)); - u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan)); - int ret = 0; -@@ -363,15 +362,15 @@ static int dwxgmac2_dma_interrupt(struct - /* TX/RX NORMAL interrupts */ - if (likely(intr_status & XGMAC_NIS)) { - if (likely(intr_status & XGMAC_RI)) { -- u64_stats_update_begin(&rxq_stats->syncp); -- rxq_stats->rx_normal_irq_n++; -- u64_stats_update_end(&rxq_stats->syncp); -+ u64_stats_update_begin(&stats->syncp); -+ u64_stats_inc(&stats->rx_normal_irq_n[chan]); -+ u64_stats_update_end(&stats->syncp); - ret |= handle_rx; - } - if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) { -- u64_stats_update_begin(&txq_stats->syncp); -- txq_stats->tx_normal_irq_n++; -- u64_stats_update_end(&txq_stats->syncp); -+ u64_stats_update_begin(&stats->syncp); -+ u64_stats_inc(&stats->tx_normal_irq_n[chan]); -+ u64_stats_update_end(&stats->syncp); - ret |= handle_tx; - } - } ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -@@ -546,44 +546,79 @@ stmmac_set_pauseparam(struct net_device - } - } - -+static u64 stmmac_get_rx_normal_irq_n(struct stmmac_priv *priv, int q) -+{ -+ u64 total; -+ int cpu; -+ -+ total = 0; -+ for_each_possible_cpu(cpu) { -+ struct stmmac_pcpu_stats *pcpu; -+ unsigned int start; -+ u64 irq_n; -+ -+ pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu); -+ do { -+ start = u64_stats_fetch_begin(&pcpu->syncp); -+ irq_n = u64_stats_read(&pcpu->rx_normal_irq_n[q]); -+ } while (u64_stats_fetch_retry(&pcpu->syncp, start)); -+ total += irq_n; -+ } -+ return total; -+} -+ -+static u64 stmmac_get_tx_normal_irq_n(struct stmmac_priv *priv, int q) -+{ -+ u64 total; -+ int cpu; -+ -+ total = 0; -+ for_each_possible_cpu(cpu) { -+ struct stmmac_pcpu_stats *pcpu; -+ unsigned int start; -+ u64 irq_n; -+ -+ pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu); -+ do { -+ start = u64_stats_fetch_begin(&pcpu->syncp); -+ irq_n = u64_stats_read(&pcpu->tx_normal_irq_n[q]); -+ } while (u64_stats_fetch_retry(&pcpu->syncp, start)); -+ total += irq_n; -+ } -+ return total; -+} -+ - static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) - { - u32 tx_cnt = priv->plat->tx_queues_to_use; - u32 rx_cnt = priv->plat->rx_queues_to_use; - unsigned int start; -- int q, stat; -- char *p; -+ int q; - - for (q = 0; q < tx_cnt; q++) { - struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q]; -- struct stmmac_txq_stats snapshot; -+ u64 pkt_n; - - do { -- start = u64_stats_fetch_begin(&txq_stats->syncp); -- snapshot = *txq_stats; -- } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); -+ start = u64_stats_fetch_begin(&txq_stats->napi_syncp); -+ pkt_n = u64_stats_read(&txq_stats->napi.tx_pkt_n); -+ } while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start)); - -- p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n); -- for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) { -- *data++ = (*(u64 *)p); -- p += sizeof(u64); -- } -+ *data++ = pkt_n; -+ *data++ = stmmac_get_tx_normal_irq_n(priv, q); - } - - for (q = 0; q < rx_cnt; q++) { - struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q]; -- struct stmmac_rxq_stats snapshot; -+ u64 pkt_n; - - do { -- start = u64_stats_fetch_begin(&rxq_stats->syncp); -- snapshot = *rxq_stats; -- } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); -+ start = u64_stats_fetch_begin(&rxq_stats->napi_syncp); -+ pkt_n = u64_stats_read(&rxq_stats->napi.rx_pkt_n); -+ } while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start)); - -- p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n); -- for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) { -- *data++ = (*(u64 *)p); -- p += sizeof(u64); -- } -+ *data++ = pkt_n; -+ *data++ = stmmac_get_rx_normal_irq_n(priv, q); - } - } - -@@ -642,39 +677,49 @@ static void stmmac_get_ethtool_stats(str - pos = j; - for (i = 0; i < rx_queues_count; i++) { - struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[i]; -- struct stmmac_rxq_stats snapshot; -+ struct stmmac_napi_rx_stats snapshot; -+ u64 n_irq; - - j = pos; - do { -- start = u64_stats_fetch_begin(&rxq_stats->syncp); -- snapshot = *rxq_stats; -- } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); -- -- data[j++] += snapshot.rx_pkt_n; -- data[j++] += snapshot.rx_normal_irq_n; -- normal_irq_n += snapshot.rx_normal_irq_n; -- napi_poll += snapshot.napi_poll; -+ start = u64_stats_fetch_begin(&rxq_stats->napi_syncp); -+ snapshot = rxq_stats->napi; -+ } while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start)); -+ -+ data[j++] += u64_stats_read(&snapshot.rx_pkt_n); -+ n_irq = stmmac_get_rx_normal_irq_n(priv, i); -+ data[j++] += n_irq; -+ normal_irq_n += n_irq; -+ napi_poll += u64_stats_read(&snapshot.poll); - } - - pos = j; - for (i = 0; i < tx_queues_count; i++) { - struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[i]; -- struct stmmac_txq_stats snapshot; -+ struct stmmac_napi_tx_stats napi_snapshot; -+ struct stmmac_q_tx_stats q_snapshot; -+ u64 n_irq; - - j = pos; - do { -- start = u64_stats_fetch_begin(&txq_stats->syncp); -- snapshot = *txq_stats; -- } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); -- -- data[j++] += snapshot.tx_pkt_n; -- data[j++] += snapshot.tx_normal_irq_n; -- normal_irq_n += snapshot.tx_normal_irq_n; -- data[j++] += snapshot.tx_clean; -- data[j++] += snapshot.tx_set_ic_bit; -- data[j++] += snapshot.tx_tso_frames; -- data[j++] += snapshot.tx_tso_nfrags; -- napi_poll += snapshot.napi_poll; -+ start = u64_stats_fetch_begin(&txq_stats->q_syncp); -+ q_snapshot = txq_stats->q; -+ } while (u64_stats_fetch_retry(&txq_stats->q_syncp, start)); -+ do { -+ start = u64_stats_fetch_begin(&txq_stats->napi_syncp); -+ napi_snapshot = txq_stats->napi; -+ } while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start)); -+ -+ data[j++] += u64_stats_read(&napi_snapshot.tx_pkt_n); -+ n_irq = stmmac_get_tx_normal_irq_n(priv, i); -+ data[j++] += n_irq; -+ normal_irq_n += n_irq; -+ data[j++] += u64_stats_read(&napi_snapshot.tx_clean); -+ data[j++] += u64_stats_read(&q_snapshot.tx_set_ic_bit) + -+ u64_stats_read(&napi_snapshot.tx_set_ic_bit); -+ data[j++] += u64_stats_read(&q_snapshot.tx_tso_frames); -+ data[j++] += u64_stats_read(&q_snapshot.tx_tso_nfrags); -+ napi_poll += u64_stats_read(&napi_snapshot.poll); - } - normal_irq_n += priv->xstats.rx_early_irq; - data[j++] = normal_irq_n; ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -2433,7 +2433,6 @@ static bool stmmac_xdp_xmit_zc(struct st - struct xdp_desc xdp_desc; - bool work_done = true; - u32 tx_set_ic_bit = 0; -- unsigned long flags; - - /* Avoids TX time-out as we are sharing with slow path */ - txq_trans_cond_update(nq); -@@ -2506,9 +2505,9 @@ static bool stmmac_xdp_xmit_zc(struct st - tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); - entry = tx_q->cur_tx; - } -- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); -- txq_stats->tx_set_ic_bit += tx_set_ic_bit; -- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); -+ u64_stats_update_begin(&txq_stats->napi_syncp); -+ u64_stats_add(&txq_stats->napi.tx_set_ic_bit, tx_set_ic_bit); -+ u64_stats_update_end(&txq_stats->napi_syncp); - - if (tx_desc) { - stmmac_flush_tx_descriptors(priv, queue); -@@ -2552,7 +2551,6 @@ static int stmmac_tx_clean(struct stmmac - unsigned int bytes_compl = 0, pkts_compl = 0; - unsigned int entry, xmits = 0, count = 0; - u32 tx_packets = 0, tx_errors = 0; -- unsigned long flags; - - __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue)); - -@@ -2708,11 +2706,11 @@ static int stmmac_tx_clean(struct stmmac - if (tx_q->dirty_tx != tx_q->cur_tx) - stmmac_tx_timer_arm(priv, queue); - -- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); -- txq_stats->tx_packets += tx_packets; -- txq_stats->tx_pkt_n += tx_packets; -- txq_stats->tx_clean++; -- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); -+ u64_stats_update_begin(&txq_stats->napi_syncp); -+ u64_stats_add(&txq_stats->napi.tx_packets, tx_packets); -+ u64_stats_add(&txq_stats->napi.tx_pkt_n, tx_packets); -+ u64_stats_inc(&txq_stats->napi.tx_clean); -+ u64_stats_update_end(&txq_stats->napi_syncp); - - priv->xstats.tx_errors += tx_errors; - -@@ -4130,7 +4128,6 @@ static netdev_tx_t stmmac_tso_xmit(struc - struct stmmac_tx_queue *tx_q; - bool has_vlan, set_ic; - u8 proto_hdr_len, hdr; -- unsigned long flags; - u32 pay_len, mss; - dma_addr_t des; - int i; -@@ -4307,13 +4304,13 @@ static netdev_tx_t stmmac_tso_xmit(struc - netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); - } - -- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); -- txq_stats->tx_bytes += skb->len; -- txq_stats->tx_tso_frames++; -- txq_stats->tx_tso_nfrags += nfrags; -+ u64_stats_update_begin(&txq_stats->q_syncp); -+ u64_stats_add(&txq_stats->q.tx_bytes, skb->len); -+ u64_stats_inc(&txq_stats->q.tx_tso_frames); -+ u64_stats_add(&txq_stats->q.tx_tso_nfrags, nfrags); - if (set_ic) -- txq_stats->tx_set_ic_bit++; -- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); -+ u64_stats_inc(&txq_stats->q.tx_set_ic_bit); -+ u64_stats_update_end(&txq_stats->q_syncp); - - if (priv->sarc_type) - stmmac_set_desc_sarc(priv, first, priv->sarc_type); -@@ -4390,7 +4387,6 @@ static netdev_tx_t stmmac_xmit(struct sk - struct stmmac_tx_queue *tx_q; - bool has_vlan, set_ic; - int entry, first_tx; -- unsigned long flags; - dma_addr_t des; - - tx_q = &priv->dma_conf.tx_queue[queue]; -@@ -4546,11 +4542,11 @@ static netdev_tx_t stmmac_xmit(struct sk - netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); - } - -- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); -- txq_stats->tx_bytes += skb->len; -+ u64_stats_update_begin(&txq_stats->q_syncp); -+ u64_stats_add(&txq_stats->q.tx_bytes, skb->len); - if (set_ic) -- txq_stats->tx_set_ic_bit++; -- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); -+ u64_stats_inc(&txq_stats->q.tx_set_ic_bit); -+ u64_stats_update_end(&txq_stats->q_syncp); - - if (priv->sarc_type) - stmmac_set_desc_sarc(priv, first, priv->sarc_type); -@@ -4814,12 +4810,11 @@ static int stmmac_xdp_xmit_xdpf(struct s - set_ic = false; - - if (set_ic) { -- unsigned long flags; - tx_q->tx_count_frames = 0; - stmmac_set_tx_ic(priv, tx_desc); -- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); -- txq_stats->tx_set_ic_bit++; -- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); -+ u64_stats_update_begin(&txq_stats->q_syncp); -+ u64_stats_inc(&txq_stats->q.tx_set_ic_bit); -+ u64_stats_update_end(&txq_stats->q_syncp); - } - - stmmac_enable_dma_transmission(priv, priv->ioaddr); -@@ -4979,7 +4974,6 @@ static void stmmac_dispatch_skb_zc(struc - unsigned int len = xdp->data_end - xdp->data; - enum pkt_hash_types hash_type; - int coe = priv->hw->rx_csum; -- unsigned long flags; - struct sk_buff *skb; - u32 hash; - -@@ -5004,10 +4998,10 @@ static void stmmac_dispatch_skb_zc(struc - skb_record_rx_queue(skb, queue); - napi_gro_receive(&ch->rxtx_napi, skb); - -- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); -- rxq_stats->rx_pkt_n++; -- rxq_stats->rx_bytes += len; -- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); -+ u64_stats_update_begin(&rxq_stats->napi_syncp); -+ u64_stats_inc(&rxq_stats->napi.rx_pkt_n); -+ u64_stats_add(&rxq_stats->napi.rx_bytes, len); -+ u64_stats_update_end(&rxq_stats->napi_syncp); - } - - static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget) -@@ -5079,7 +5073,6 @@ static int stmmac_rx_zc(struct stmmac_pr - unsigned int desc_size; - struct bpf_prog *prog; - bool failure = false; -- unsigned long flags; - int xdp_status = 0; - int status = 0; - -@@ -5230,9 +5223,9 @@ read_again: - - stmmac_finalize_xdp_rx(priv, xdp_status); - -- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); -- rxq_stats->rx_pkt_n += count; -- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); -+ u64_stats_update_begin(&rxq_stats->napi_syncp); -+ u64_stats_add(&rxq_stats->napi.rx_pkt_n, count); -+ u64_stats_update_end(&rxq_stats->napi_syncp); - - priv->xstats.rx_dropped += rx_dropped; - priv->xstats.rx_errors += rx_errors; -@@ -5270,7 +5263,6 @@ static int stmmac_rx(struct stmmac_priv - unsigned int desc_size; - struct sk_buff *skb = NULL; - struct stmmac_xdp_buff ctx; -- unsigned long flags; - int xdp_status = 0; - int buf_sz; - -@@ -5518,11 +5510,11 @@ drain_data: - - stmmac_rx_refill(priv, queue); - -- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); -- rxq_stats->rx_packets += rx_packets; -- rxq_stats->rx_bytes += rx_bytes; -- rxq_stats->rx_pkt_n += count; -- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); -+ u64_stats_update_begin(&rxq_stats->napi_syncp); -+ u64_stats_add(&rxq_stats->napi.rx_packets, rx_packets); -+ u64_stats_add(&rxq_stats->napi.rx_bytes, rx_bytes); -+ u64_stats_add(&rxq_stats->napi.rx_pkt_n, count); -+ u64_stats_update_end(&rxq_stats->napi_syncp); - - priv->xstats.rx_dropped += rx_dropped; - priv->xstats.rx_errors += rx_errors; -@@ -5537,13 +5529,12 @@ static int stmmac_napi_poll_rx(struct na - struct stmmac_priv *priv = ch->priv_data; - struct stmmac_rxq_stats *rxq_stats; - u32 chan = ch->index; -- unsigned long flags; - int work_done; - - rxq_stats = &priv->xstats.rxq_stats[chan]; -- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); -- rxq_stats->napi_poll++; -- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); -+ u64_stats_update_begin(&rxq_stats->napi_syncp); -+ u64_stats_inc(&rxq_stats->napi.poll); -+ u64_stats_update_end(&rxq_stats->napi_syncp); - - work_done = stmmac_rx(priv, budget, chan); - if (work_done < budget && napi_complete_done(napi, work_done)) { -@@ -5564,13 +5555,12 @@ static int stmmac_napi_poll_tx(struct na - struct stmmac_priv *priv = ch->priv_data; - struct stmmac_txq_stats *txq_stats; - u32 chan = ch->index; -- unsigned long flags; - int work_done; - - txq_stats = &priv->xstats.txq_stats[chan]; -- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); -- txq_stats->napi_poll++; -- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); -+ u64_stats_update_begin(&txq_stats->napi_syncp); -+ u64_stats_inc(&txq_stats->napi.poll); -+ u64_stats_update_end(&txq_stats->napi_syncp); - - work_done = stmmac_tx_clean(priv, budget, chan); - work_done = min(work_done, budget); -@@ -5595,17 +5585,16 @@ static int stmmac_napi_poll_rxtx(struct - struct stmmac_rxq_stats *rxq_stats; - struct stmmac_txq_stats *txq_stats; - u32 chan = ch->index; -- unsigned long flags; - - rxq_stats = &priv->xstats.rxq_stats[chan]; -- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); -- rxq_stats->napi_poll++; -- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); -+ u64_stats_update_begin(&rxq_stats->napi_syncp); -+ u64_stats_inc(&rxq_stats->napi.poll); -+ u64_stats_update_end(&rxq_stats->napi_syncp); - - txq_stats = &priv->xstats.txq_stats[chan]; -- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); -- txq_stats->napi_poll++; -- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); -+ u64_stats_update_begin(&txq_stats->napi_syncp); -+ u64_stats_inc(&txq_stats->napi.poll); -+ u64_stats_update_end(&txq_stats->napi_syncp); - - tx_done = stmmac_tx_clean(priv, budget, chan); - tx_done = min(tx_done, budget); -@@ -6857,10 +6846,13 @@ static void stmmac_get_stats64(struct ne - u64 tx_bytes; - - do { -- start = u64_stats_fetch_begin(&txq_stats->syncp); -- tx_packets = txq_stats->tx_packets; -- tx_bytes = txq_stats->tx_bytes; -- } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); -+ start = u64_stats_fetch_begin(&txq_stats->q_syncp); -+ tx_bytes = u64_stats_read(&txq_stats->q.tx_bytes); -+ } while (u64_stats_fetch_retry(&txq_stats->q_syncp, start)); -+ do { -+ start = u64_stats_fetch_begin(&txq_stats->napi_syncp); -+ tx_packets = u64_stats_read(&txq_stats->napi.tx_packets); -+ } while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start)); - - stats->tx_packets += tx_packets; - stats->tx_bytes += tx_bytes; -@@ -6872,10 +6864,10 @@ static void stmmac_get_stats64(struct ne - u64 rx_bytes; - - do { -- start = u64_stats_fetch_begin(&rxq_stats->syncp); -- rx_packets = rxq_stats->rx_packets; -- rx_bytes = rxq_stats->rx_bytes; -- } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); -+ start = u64_stats_fetch_begin(&rxq_stats->napi_syncp); -+ rx_packets = u64_stats_read(&rxq_stats->napi.rx_packets); -+ rx_bytes = u64_stats_read(&rxq_stats->napi.rx_bytes); -+ } while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start)); - - stats->rx_packets += rx_packets; - stats->rx_bytes += rx_bytes; -@@ -7239,9 +7231,16 @@ int stmmac_dvr_probe(struct device *devi - priv->dev = ndev; - - for (i = 0; i < MTL_MAX_RX_QUEUES; i++) -- u64_stats_init(&priv->xstats.rxq_stats[i].syncp); -- for (i = 0; i < MTL_MAX_TX_QUEUES; i++) -- u64_stats_init(&priv->xstats.txq_stats[i].syncp); -+ u64_stats_init(&priv->xstats.rxq_stats[i].napi_syncp); -+ for (i = 0; i < MTL_MAX_TX_QUEUES; i++) { -+ u64_stats_init(&priv->xstats.txq_stats[i].q_syncp); -+ u64_stats_init(&priv->xstats.txq_stats[i].napi_syncp); -+ } -+ -+ priv->xstats.pcpu_stats = -+ devm_netdev_alloc_pcpu_stats(device, struct stmmac_pcpu_stats); -+ if (!priv->xstats.pcpu_stats) -+ return -ENOMEM; - - stmmac_set_ethtool_ops(ndev); - priv->pause = pause; diff --git a/queue-6.1/series b/queue-6.1/series index d348e4ee8f..70e86f939d 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -629,6 +629,5 @@ mm-un-track_pfn_copy-fix-doc-improvements.patch usb-gadget-lpc32xx_udc-fix-clock-imbalance-in-error-path.patch net-stmmac-fix-incorrect-rxq-txq_stats-reference.patch net-stmmac-fix-ethtool-per-queue-statistics.patch -net-stmmac-protect-updates-of-64-bit-statistics-counters.patch wifi-nl80211-fix-puncturing-bitmap-policy.patch wifi-mac80211-fix-switch-count-in-ema-beacons.patch