[openwrt/openwrt] realtek: dsa: Refresh link_stats in .get_stats64

LEDE Commits lede-commits at lists.infradead.org
Sat Nov 15 15:18:30 PST 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/e76ed39f3b296562b1490a4793cff4cf4986649d

commit e76ed39f3b296562b1490a4793cff4cf4986649d
Author: Sven Eckelmann <se at simonwunderlich.de>
AuthorDate: Mon Nov 3 18:19:14 2025 +0100

    realtek: dsa: Refresh link_stats in .get_stats64
    
    If an architecture doesn't need to sleep for retrieving the current
    statistics from the HW, it is possible to directly retrieve the last values
    from the HW when .get_stats64 is called. This avoids the stale counters
    with the current refresh interval of 60 seconds.
    
    Signed-off-by: Sven Eckelmann <se at simonwunderlich.de>
    Link: https://github.com/openwrt/openwrt/pull/20631
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c      | 10 ++++++++++
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c  |  1 +
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h  | 15 ++++++++++++++-
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c  |  1 +
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c  |  1 +
 5 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c
index d34dd3b03b..6786abbe74 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c
@@ -1430,6 +1430,13 @@ static void rtldsa_get_rmon_stats(struct dsa_switch *ds, int port,
 	rtldsa_counters_unlock(priv, port);
 }
 
+void rtldsa_update_counters_atomically(struct rtl838x_switch_priv *priv, int port)
+{
+	rtldsa_counters_lock(priv, port);
+	rtldsa_update_port_counters(priv, port);
+	rtldsa_counters_unlock(priv, port);
+}
+
 static void rtldsa_get_stats64(struct dsa_switch *ds, int port,
 			       struct rtnl_link_stats64 *s)
 {
@@ -1444,6 +1451,9 @@ static void rtldsa_get_stats64(struct dsa_switch *ds, int port,
 		return;
 	}
 
+	if (priv->r->stat_update_counters_atomically)
+		priv->r->stat_update_counters_atomically(priv, port);
+
 	/* retrieve prepared return data without potentially sleeping via mutex */
 	spin_lock(&counters->link_stat_lock);
 	memcpy(s, &counters->link_stat, sizeof(*s));
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c
index c57027ed1d..af3e88a632 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c
@@ -1675,6 +1675,7 @@ const struct rtl838x_reg rtl838x_reg = {
 	.stat_port_std_mib = RTL838X_STAT_PORT_STD_MIB,
 	.stat_counters_lock = rtldsa_counters_lock_register,
 	.stat_counters_unlock = rtldsa_counters_unlock_register,
+	.stat_update_counters_atomically = rtldsa_update_counters_atomically,
 	.port_iso_ctrl = rtl838x_port_iso_ctrl,
 	.traffic_enable = rtl838x_traffic_enable,
 	.traffic_disable = rtl838x_traffic_disable,
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
index bca2d8a1f7..267a6b80f7 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
@@ -712,7 +712,7 @@ struct rtldsa_counter {
 struct rtldsa_counter_state {
 	/**
 	 * @lock: protect updates to members of the structure when the
-	 * priv->counters_lock is not used.
+	 * priv->counters_lock is not used. (see rtl931x_reg->stat_update_counters_atomically)
 	 */
 	spinlock_t lock;
 	ktime_t last_update;
@@ -1129,6 +1129,17 @@ struct rtl838x_reg {
 	u64 (*stat_port_table_read)(int port, unsigned int mib_size, unsigned int offset, bool is_pvt);
 	void (*stat_counters_lock)(struct rtl838x_switch_priv *priv, int port);
 	void (*stat_counters_unlock)(struct rtl838x_switch_priv *priv, int port);
+
+	/**
+	 * @stat_update_counters_atomically: When set, the SoC family allows atomically retrieving
+	 * of statistic counters using this function.  This function must not require "might_sleep"
+	 * code.
+	 *
+	 * Any SoC family which requires stat_port_table_read must use the table
+	 * rtldsa_counters_(un)lock_table helpers. They are using a mutex for locking. The counters
+	 * update is therefore not atomic.
+	 */
+	void (*stat_update_counters_atomically)(struct rtl838x_switch_priv *priv, int port);
 	int (*port_iso_ctrl)(int p);
 	void (*traffic_enable)(int source, int dest);
 	void (*traffic_disable)(int source, int dest);
@@ -1300,6 +1311,8 @@ void rtldsa_counters_lock_table(struct rtl838x_switch_priv *priv, int port)
 void rtldsa_counters_unlock_table(struct rtl838x_switch_priv *priv, int port)
 	__releases(&priv->ports[port].counters.lock);
 
+void rtldsa_update_counters_atomically(struct rtl838x_switch_priv *priv, int port);
+
 extern int rtldsa_max_available_queue[];
 extern int rtldsa_default_queue_weights[];
 
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c
index e3adefcd10..c421fb819d 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c
@@ -1649,6 +1649,7 @@ const struct rtl838x_reg rtl839x_reg = {
 	.stat_port_std_mib = RTL839X_STAT_PORT_STD_MIB,
 	.stat_counters_lock = rtldsa_counters_lock_register,
 	.stat_counters_unlock = rtldsa_counters_unlock_register,
+	.stat_update_counters_atomically = rtldsa_update_counters_atomically,
 	.traffic_enable = rtl839x_traffic_enable,
 	.traffic_disable = rtl839x_traffic_disable,
 	.traffic_set = rtl839x_traffic_set,
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c
index f835681541..8f19056072 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c
@@ -2618,6 +2618,7 @@ const struct rtl838x_reg rtl930x_reg = {
 	.stat_port_prv_mib = RTL930X_STAT_PORT_PRVTE_CNTR,
 	.stat_counters_lock = rtldsa_counters_lock_register,
 	.stat_counters_unlock = rtldsa_counters_unlock_register,
+	.stat_update_counters_atomically = rtldsa_update_counters_atomically,
 	.traffic_enable = rtl930x_traffic_enable,
 	.traffic_disable = rtl930x_traffic_disable,
 	.traffic_set = rtl930x_traffic_set,




More information about the lede-commits mailing list