[PATCH net-next v6 4/4] net: stmmac: hold RTNL when reading descriptor rings in descriptors_status
Ding Hui
dinghui1111 at 163.com
Sat Oct 24 00:13:18 PDT 2026
From: Ding Hui <dinghui at lixiang.com>
The descriptors_status debugfs entry inspects the descriptor rings
without any synchronization against the control-plane paths that
tear them down (ndo_stop, MTU change, XDP program release, XSK pool
reconfiguration). All of those paths hold RTNL, so take the same
lock around the reader.
Holding RTNL also makes it safe to report queues whose descriptor
rings are not allocated: the interface may be IFF_UP with unallocated
rings when an internal reopen fails (e.g. an MTU change whose
__stmmac_open() call fails), as those paths do not clear IFF_UP.
Skip such queues with a hint instead of dereferencing a NULL pointer
in stmmac_rings_status_show().
Signed-off-by: Ding Hui <dinghui at lixiang.com>
---
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 27 ++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index b093119e752f..0f4af7ec3fc8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -6707,8 +6707,10 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v)
u8 tx_count = priv->plat->tx_queues_to_use;
u8 queue;
+ rtnl_lock();
+
if ((dev->flags & IFF_UP) == 0)
- return 0;
+ goto out;
for (queue = 0; queue < rx_count; queue++) {
struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
@@ -6716,10 +6718,20 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v)
seq_printf(seq, "RX Queue %d:\n", queue);
if (priv->extend_desc) {
+ if (!rx_q->dma_erx) {
+ seq_puts(seq, "Extended descriptor ring not allocated\n");
+ continue;
+ }
+
seq_printf(seq, "Extended descriptor ring:\n");
sysfs_display_ring((void *)rx_q->dma_erx,
priv->dma_conf.dma_rx_size, 1, seq, rx_q->dma_rx_phy);
} else {
+ if (!rx_q->dma_rx) {
+ seq_puts(seq, "Descriptor ring not allocated\n");
+ continue;
+ }
+
seq_printf(seq, "Descriptor ring:\n");
sysfs_display_ring((void *)rx_q->dma_rx,
priv->dma_conf.dma_rx_size, 0, seq, rx_q->dma_rx_phy);
@@ -6732,16 +6744,29 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v)
seq_printf(seq, "TX Queue %d:\n", queue);
if (priv->extend_desc) {
+ if (!tx_q->dma_etx) {
+ seq_puts(seq, "Extended descriptor ring not allocated\n");
+ continue;
+ }
+
seq_printf(seq, "Extended descriptor ring:\n");
sysfs_display_ring((void *)tx_q->dma_etx,
priv->dma_conf.dma_tx_size, 1, seq, tx_q->dma_tx_phy);
} else if (!(tx_q->tbs & STMMAC_TBS_AVAIL)) {
+ if (!tx_q->dma_tx) {
+ seq_puts(seq, "Descriptor ring not allocated\n");
+ continue;
+ }
+
seq_printf(seq, "Descriptor ring:\n");
sysfs_display_ring((void *)tx_q->dma_tx,
priv->dma_conf.dma_tx_size, 0, seq, tx_q->dma_tx_phy);
}
}
+out:
+ rtnl_unlock();
+
return 0;
}
DEFINE_SHOW_ATTRIBUTE(stmmac_rings_status);
--
2.34.1
More information about the linux-arm-kernel
mailing list