[openwrt/openwrt] realtek: dsa: rtl931x: Reduce HW counters polling interval

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


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

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

    realtek: dsa: rtl931x: Reduce HW counters polling interval
    
    Some SoC families require table access to get the HW counters. A mutex is
    required for this access - which will potentially cause a sleep in the
    current context. This is not always possible with .get_stats64 because it
    is also called in atomic contexts.
    
    For these SoCs, the retrieval of the current counters in .get_stats64 is
    skipped and the counters are simply retrieved a lot more often from the HW.
    
    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  | 12 ++----------
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c      |  1 +
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h      | 19 +++++++++++++++++++
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c      |  1 +
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c      |  1 +
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c      |  1 +
 6 files changed, 25 insertions(+), 10 deletions(-)

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 6786abbe74..0c20f626a7 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
@@ -16,14 +16,6 @@ static const u8 ipv6_all_hosts_mcast_addr_base[ETH_ALEN] =
 static const u8 ipv6_all_hosts_mcast_addr_mask[ETH_ALEN] =
 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
-/* This interval needs to be short enough to prevent an undetected counter
- * overflow. The octet counters don't need to be considered for this, because
- * they are 64 bits on all platforms. Based on the possible packets per second
- * at the highest supported speeds, an interval of a minute is probably a safe
- * choice for the other counters.
- */
-#define RTLDSA_COUNTERS_POLL_INTERVAL	(60 * HZ)
-
 extern struct rtl83xx_soc_info soc_info;
 
 static void rtldsa_init_counters(struct rtl838x_switch_priv *priv);
@@ -1213,7 +1205,7 @@ static void rtldsa_poll_counters(struct work_struct *work)
 	}
 
 	queue_delayed_work(priv->wq, &priv->counters_work,
-			   RTLDSA_COUNTERS_POLL_INTERVAL);
+			   priv->r->stat_counter_poll_interval);
 }
 
 static void rtldsa_init_counters(struct rtl838x_switch_priv *priv)
@@ -1233,7 +1225,7 @@ static void rtldsa_init_counters(struct rtl838x_switch_priv *priv)
 
 	INIT_DELAYED_WORK(&priv->counters_work, rtldsa_poll_counters);
 	queue_delayed_work(priv->wq, &priv->counters_work,
-			   RTLDSA_COUNTERS_POLL_INTERVAL);
+			   priv->r->stat_counter_poll_interval);
 }
 
 static void rtldsa_get_strings(struct dsa_switch *ds,
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 af3e88a632..7fbd561c3f 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
@@ -1676,6 +1676,7 @@ const struct rtl838x_reg rtl838x_reg = {
 	.stat_counters_lock = rtldsa_counters_lock_register,
 	.stat_counters_unlock = rtldsa_counters_unlock_register,
 	.stat_update_counters_atomically = rtldsa_update_counters_atomically,
+	.stat_counter_poll_interval = RTLDSA_COUNTERS_POLL_INTERVAL,
 	.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 267a6b80f7..b0cfa21d76 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
@@ -684,6 +684,24 @@ typedef enum {
 #define MAX_SMACS 64
 #define DSCP_MAP_MAX 64
 
+/* This interval needs to be short enough to prevent an undetected counter
+ * overflow. The octet counters don't need to be considered for this, because
+ * they are 64 bits on all platforms. Based on the possible packets per second
+ * at the highest supported speeds, an interval of a minute is probably a safe
+ * choice for the other counters.
+ */
+#define RTLDSA_COUNTERS_POLL_INTERVAL	(60 * HZ)
+
+/* Some SoC families require table access to get the HW counters. A mutex is
+ * required for this access - which will potentially cause a sleep in the
+ * current context. This is not always possible with .get_stats64 because it
+ * is also called in atomic contexts.
+ *
+ * For these SoCs, the retrieval of the current counters in .get_stats64 is
+ * skipped and the counters are simply retrieved a lot more often from the HW.
+ */
+#define RTLDSA_COUNTERS_FAST_POLL_INTERVAL	(3 * HZ)
+
 enum phy_type {
 	PHY_NONE = 0,
 	PHY_RTL838X_SDS = 1,
@@ -1140,6 +1158,7 @@ struct rtl838x_reg {
 	 * update is therefore not atomic.
 	 */
 	void (*stat_update_counters_atomically)(struct rtl838x_switch_priv *priv, int port);
+	unsigned long stat_counter_poll_interval;
 	int (*port_iso_ctrl)(int p);
 	void (*traffic_enable)(int source, int dest);
 	void (*traffic_disable)(int source, int dest);
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 c421fb819d..9acb277de8 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
@@ -1650,6 +1650,7 @@ const struct rtl838x_reg rtl839x_reg = {
 	.stat_counters_lock = rtldsa_counters_lock_register,
 	.stat_counters_unlock = rtldsa_counters_unlock_register,
 	.stat_update_counters_atomically = rtldsa_update_counters_atomically,
+	.stat_counter_poll_interval = RTLDSA_COUNTERS_POLL_INTERVAL,
 	.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 8f19056072..bad4b30ce2 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
@@ -2619,6 +2619,7 @@ const struct rtl838x_reg rtl930x_reg = {
 	.stat_counters_lock = rtldsa_counters_lock_register,
 	.stat_counters_unlock = rtldsa_counters_unlock_register,
 	.stat_update_counters_atomically = rtldsa_update_counters_atomically,
+	.stat_counter_poll_interval = RTLDSA_COUNTERS_POLL_INTERVAL,
 	.traffic_enable = rtl930x_traffic_enable,
 	.traffic_disable = rtl930x_traffic_disable,
 	.traffic_set = rtl930x_traffic_set,
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
index f0817e7f45..6bc3db84d8 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
@@ -1777,6 +1777,7 @@ const struct rtl838x_reg rtl931x_reg = {
 	.stat_port_table_read = rtldsa_931x_stat_port_table_read,
 	.stat_counters_lock = rtldsa_counters_lock_table,
 	.stat_counters_unlock = rtldsa_counters_unlock_table,
+	.stat_counter_poll_interval = RTLDSA_COUNTERS_FAST_POLL_INTERVAL,
 	.traffic_enable = rtl931x_traffic_enable,
 	.traffic_disable = rtl931x_traffic_disable,
 	.traffic_set = rtl931x_traffic_set,




More information about the lede-commits mailing list