]> www.infradead.org Git - users/hch/misc.git/commitdiff
net: hibmcge: fix the share of irq statistics among different network ports issue
authorJijie Shao <shaojijie@huawei.com>
Thu, 10 Apr 2025 02:13:23 +0000 (10:13 +0800)
committerJakub Kicinski <kuba@kernel.org>
Sat, 12 Apr 2025 03:17:36 +0000 (20:17 -0700)
hbg_irqs is a global array which contains irq statistics.
However, the irq statistics of different network ports
point to the same global array. As a result, the statistics are incorrect.

This patch allocates a statistics array for each network port
to prevent the statistics of different network ports
from affecting each other.

irq statistics are removed from hbg_irq_info. Therefore,
all data in hbg_irq_info remains unchanged. Therefore,
the input parameter of some functions is changed to const.

Fixes: 4d089035fa19 ("net: hibmcge: Add interrupt supported in this module")
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250410021327.590362-4-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
drivers/net/ethernet/hisilicon/hibmcge/hbg_debugfs.c
drivers/net/ethernet/hisilicon/hibmcge/hbg_diagnose.c
drivers/net/ethernet/hisilicon/hibmcge/hbg_irq.c
drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c

index f8cdab62bf85cabeb48fdda866c7c866f545fc96..7725cb0c5c8a44fdc956e88e598e2dceb3378aaa 100644 (file)
@@ -108,14 +108,16 @@ struct hbg_irq_info {
        bool re_enable;
        bool need_print;
        bool need_reset;
-       u64 count;
 
-       void (*irq_handle)(struct hbg_priv *priv, struct hbg_irq_info *info);
+       void (*irq_handle)(struct hbg_priv *priv,
+                          const struct hbg_irq_info *info);
 };
 
 struct hbg_vector {
        char name[HBG_VECTOR_NUM][32];
-       struct hbg_irq_info *info_array;
+
+       u64 *stats_array;
+       const struct hbg_irq_info *info_array;
        u32 info_array_len;
 };
 
index 5e0ba4d5b08d28d472ed3a4a8bc47dd6e15f700d..9c09e48359907df54b03177dd7304c56cb4855c2 100644 (file)
@@ -61,7 +61,7 @@ static int hbg_dbg_irq_info(struct seq_file *s, void *unused)
 {
        struct net_device *netdev = dev_get_drvdata(s->private);
        struct hbg_priv *priv = netdev_priv(netdev);
-       struct hbg_irq_info *info;
+       const struct hbg_irq_info *info;
        u32 i;
 
        for (i = 0; i < priv->vectors.info_array_len; i++) {
@@ -73,7 +73,7 @@ static int hbg_dbg_irq_info(struct seq_file *s, void *unused)
                                                                info->mask)),
                           str_true_false(info->need_reset),
                           str_true_false(info->need_print),
-                          info->count);
+                          priv->vectors.stats_array[i]);
        }
 
        return 0;
index d61c03f34ff0570628ec199c463ffb4819cba691..f23fb5920c3cca352976d0becda76c3fecb0f9b0 100644 (file)
@@ -234,7 +234,7 @@ static u64 hbg_get_irq_stats(struct hbg_vector *vectors, u32 mask)
 
        for (i = 0; i < vectors->info_array_len; i++)
                if (vectors->info_array[i].mask == mask)
-                       return vectors->info_array[i].count;
+                       return vectors->stats_array[i];
 
        return 0;
 }
index e79e9ab3e5308e6241d342fb517e68023c72f926..8af0bc4cca21664bbfa34ab7483a534d305855b9 100644 (file)
@@ -6,7 +6,7 @@
 #include "hbg_hw.h"
 
 static void hbg_irq_handle_err(struct hbg_priv *priv,
-                              struct hbg_irq_info *irq_info)
+                              const struct hbg_irq_info *irq_info)
 {
        if (irq_info->need_print)
                dev_err(&priv->pdev->dev,
@@ -17,30 +17,30 @@ static void hbg_irq_handle_err(struct hbg_priv *priv,
 }
 
 static void hbg_irq_handle_tx(struct hbg_priv *priv,
-                             struct hbg_irq_info *irq_info)
+                             const struct hbg_irq_info *irq_info)
 {
        napi_schedule(&priv->tx_ring.napi);
 }
 
 static void hbg_irq_handle_rx(struct hbg_priv *priv,
-                             struct hbg_irq_info *irq_info)
+                             const struct hbg_irq_info *irq_info)
 {
        napi_schedule(&priv->rx_ring.napi);
 }
 
 static void hbg_irq_handle_rx_buf_val(struct hbg_priv *priv,
-                                     struct hbg_irq_info *irq_info)
+                                     const struct hbg_irq_info *irq_info)
 {
        priv->stats.rx_fifo_less_empty_thrsld_cnt++;
 }
 
 #define HBG_IRQ_I(name, handle) \
-       {#name, HBG_INT_MSK_##name##_B, false, false, false, 0, handle}
+       {#name, HBG_INT_MSK_##name##_B, false, false, false, handle}
 #define HBG_ERR_IRQ_I(name, need_print, ndde_reset) \
        {#name, HBG_INT_MSK_##name##_B, true, need_print, \
-       ndde_reset, 0, hbg_irq_handle_err}
+       ndde_reset, hbg_irq_handle_err}
 
-static struct hbg_irq_info hbg_irqs[] = {
+static const struct hbg_irq_info hbg_irqs[] = {
        HBG_IRQ_I(RX, hbg_irq_handle_rx),
        HBG_IRQ_I(TX, hbg_irq_handle_tx),
        HBG_ERR_IRQ_I(TX_PKT_CPL, true, true),
@@ -64,7 +64,7 @@ static struct hbg_irq_info hbg_irqs[] = {
 
 static irqreturn_t hbg_irq_handle(int irq_num, void *p)
 {
-       struct hbg_irq_info *info;
+       const struct hbg_irq_info *info;
        struct hbg_priv *priv = p;
        u32 status;
        u32 i;
@@ -79,7 +79,7 @@ static irqreturn_t hbg_irq_handle(int irq_num, void *p)
                        hbg_hw_irq_enable(priv, info->mask, false);
                        hbg_hw_irq_clear(priv, info->mask);
 
-                       info->count++;
+                       priv->vectors.stats_array[i]++;
                        if (info->irq_handle)
                                info->irq_handle(priv, info);
 
@@ -132,6 +132,12 @@ int hbg_irq_init(struct hbg_priv *priv)
                                             irq_names_map[i]);
        }
 
+       vectors->stats_array = devm_kcalloc(&priv->pdev->dev,
+                                           ARRAY_SIZE(hbg_irqs),
+                                           sizeof(u64), GFP_KERNEL);
+       if (!vectors->stats_array)
+               return -ENOMEM;
+
        vectors->info_array = hbg_irqs;
        vectors->info_array_len = ARRAY_SIZE(hbg_irqs);
        return 0;
index 2ac5454338e4de860a676d103a9a68236400e939..e5c961ad4b9b80000f5d3e44223f39d368712b7b 100644 (file)
@@ -21,7 +21,7 @@
 
 static void hbg_all_irq_enable(struct hbg_priv *priv, bool enabled)
 {
-       struct hbg_irq_info *info;
+       const struct hbg_irq_info *info;
        u32 i;
 
        for (i = 0; i < priv->vectors.info_array_len; i++) {