Commit 4ad3df75 authored by Jijie Shao's avatar Jijie Shao Committed by Jakub Kicinski
Browse files

net: hibmcge: fix the share of irq statistics among different network ports issue



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: 4d089035 ("net: hibmcge: Add interrupt supported in this module")
Signed-off-by: default avatarJijie Shao <shaojijie@huawei.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250410021327.590362-4-shaojijie@huawei.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 9afaaa54
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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;
};

+2 −2
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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;
}
+15 −9
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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++) {