patches for DPDK stable branches
 help / color / mirror / Atom feed
* [PATCH 21.11] net/hns3: fix IMP or global reset
@ 2023-11-23  1:19 Dengdui Huang
  2023-11-23 10:52 ` Kevin Traynor
  0 siblings, 1 reply; 2+ messages in thread
From: Dengdui Huang @ 2023-11-23  1:19 UTC (permalink / raw)
  To: stable; +Cc: liuyonglong

[ upstream commit 1eee1ea75c0eadaea6dde368b289cf0acf6a1190 ]

Currently, when the IMP or Global reset detected, the vector0
interrupt is enabled before the reset process is completed.
At this moment, if the initialization of IMP is not completed,
and the vector0 interrupt may continue to be reported. In this
scenario, the IMP/global reset being performed by the driver
does not need to be interrupted. Therefore, for IMP and global
resets, the driver has to enable the interrupt after the end
of reset.

The RAS interrupt is also shared with the vector0 interrupt.
When the interrupt is disabled, the RAS interrupt can still be
reported to the driver and the driver interrupt processing
function is also called. In this case, the interrupt status of
the IMP/global may still exist. Therefore, this patch also has
to the check of the new reset level based on the priority of
reset level in the interrupt handler.

Fixes: 2790c6464725 ("net/hns3: support device reset")
Fixes: 3988ab0eee52 ("net/hns3: add abnormal interrupt process")
Cc: stable@dpdk.org

Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 88 ++++++++++++++++++++++++++++------
 drivers/net/hns3/hns3_ethdev.h |  1 +
 drivers/net/hns3/hns3_intr.c   |  2 +
 3 files changed, 77 insertions(+), 14 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 352e7f277b..db14c35a32 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -228,6 +228,30 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)
 	return ret;
 }
 
+void
+hns3_clear_reset_event(struct hns3_hw *hw)
+{
+	uint32_t clearval = 0;
+
+	switch (hw->reset.level) {
+	case HNS3_IMP_RESET:
+		clearval = BIT(HNS3_VECTOR0_IMPRESET_INT_B);
+		break;
+	case HNS3_GLOBAL_RESET:
+		clearval = BIT(HNS3_VECTOR0_GLOBALRESET_INT_B);
+		break;
+	default:
+		break;
+	}
+
+	if (clearval == 0)
+		return;
+
+	hns3_write_dev(hw, HNS3_MISC_RESET_STS_REG, clearval);
+
+	hns3_pf_enable_irq0(hw);
+}
+
 static void
 hns3_clear_event_cause(struct hns3_hw *hw, uint32_t event_type, uint32_t regclr)
 {
@@ -300,6 +324,34 @@ hns3_delay_before_clear_event_cause(struct hns3_hw *hw, uint32_t event_type, uin
 	}
 }
 
+static bool
+hns3_reset_event_valid(struct hns3_hw *hw)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	enum hns3_reset_level new_req = HNS3_NONE_RESET;
+	enum hns3_reset_level last_req;
+	uint32_t vector0_int;
+
+	vector0_int = hns3_read_dev(hw, HNS3_VECTOR0_OTHER_INT_STS_REG);
+	if (BIT(HNS3_VECTOR0_IMPRESET_INT_B) & vector0_int)
+		new_req = HNS3_IMP_RESET;
+	else if (BIT(HNS3_VECTOR0_GLOBALRESET_INT_B) & vector0_int)
+		new_req = HNS3_GLOBAL_RESET;
+	if (new_req == HNS3_NONE_RESET)
+		return true;
+
+	last_req = hns3_get_reset_level(hns, &hw->reset.pending);
+	if (last_req == HNS3_NONE_RESET)
+		return true;
+
+	if (new_req > last_req)
+		return true;
+
+	hns3_warn(hw, "last_req (%u) less than or equal to new_req (%u) ignore",
+		  last_req, new_req);
+	return false;
+}
+
 static void
 hns3_interrupt_handler(void *param)
 {
@@ -310,6 +362,9 @@ hns3_interrupt_handler(void *param)
 	struct hns3_intr_state state;
 	uint32_t clearval = 0;
 
+	if (!hns3_reset_event_valid(hw))
+		return;
+
 	/* Disable interrupt */
 	hns3_pf_disable_irq0(hw);
 
@@ -338,7 +393,11 @@ hns3_interrupt_handler(void *param)
 	}
 
 	/* Enable interrupt if it is not cause by reset */
-	hns3_pf_enable_irq0(hw);
+	if (event_cause == HNS3_VECTOR0_EVENT_ERR ||
+	    event_cause == HNS3_VECTOR0_EVENT_MBX ||
+	    event_cause == HNS3_VECTOR0_EVENT_PTP ||
+	    event_cause == HNS3_VECTOR0_EVENT_OTHER)
+		hns3_pf_enable_irq0(hw);
 }
 
 static int
@@ -5556,7 +5615,7 @@ is_pf_reset_done(struct hns3_hw *hw)
 		return true;
 }
 
-static void
+static enum hns3_reset_level
 hns3_detect_reset_event(struct hns3_hw *hw)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
@@ -5568,11 +5627,9 @@ hns3_detect_reset_event(struct hns3_hw *hw)
 	vector0_intr_state = hns3_read_dev(hw, HNS3_VECTOR0_OTHER_INT_STS_REG);
 	if (BIT(HNS3_VECTOR0_IMPRESET_INT_B) & vector0_intr_state) {
 		__atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED);
-		hns3_atomic_set_bit(HNS3_IMP_RESET, &hw->reset.pending);
 		new_req = HNS3_IMP_RESET;
 	} else if (BIT(HNS3_VECTOR0_GLOBALRESET_INT_B) & vector0_intr_state) {
 		__atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED);
-		hns3_atomic_set_bit(HNS3_GLOBAL_RESET, &hw->reset.pending);
 		new_req = HNS3_GLOBAL_RESET;
 	}
 
@@ -5580,13 +5637,16 @@ hns3_detect_reset_event(struct hns3_hw *hw)
 		hns3_schedule_delayed_reset(hns);
 		hns3_warn(hw, "High level reset detected, delay do reset");
 	}
+
+	return new_req;
 }
 
 bool
 hns3_is_reset_pending(struct hns3_adapter *hns)
 {
+	enum hns3_reset_level new_req;
 	struct hns3_hw *hw = &hns->hw;
-	enum hns3_reset_level reset;
+	enum hns3_reset_level last_req;
 
 	/*
 	 * Only primary can process can process the reset event,
@@ -5595,17 +5655,17 @@ hns3_is_reset_pending(struct hns3_adapter *hns)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return false;
 
-	hns3_detect_reset_event(hw);
-	reset = hns3_get_reset_level(hns, &hw->reset.pending);
-	if (reset != HNS3_NONE_RESET && hw->reset.level != HNS3_NONE_RESET &&
-	    hw->reset.level < reset) {
-		hns3_warn(hw, "High level reset %d is pending", reset);
+	new_req = hns3_detect_reset_event(hw);
+	last_req = hns3_get_reset_level(hns, &hw->reset.pending);
+	if (last_req != HNS3_NONE_RESET && new_req != HNS3_NONE_RESET &&
+	    new_req < last_req) {
+		hns3_warn(hw, "High level reset %d is pending", last_req);
 		return true;
 	}
-	reset = hns3_get_reset_level(hns, &hw->reset.request);
-	if (reset != HNS3_NONE_RESET && hw->reset.level != HNS3_NONE_RESET &&
-	    hw->reset.level < reset) {
-		hns3_warn(hw, "High level reset %d is request", reset);
+	last_req = hns3_get_reset_level(hns, &hw->reset.request);
+	if (last_req != HNS3_NONE_RESET && hw->reset.level != HNS3_NONE_RESET &&
+	    hw->reset.level < last_req) {
+		hns3_warn(hw, "High level reset %d is request", last_req);
 		return true;
 	}
 	return false;
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 3496be6f73..840db01bcd 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -1034,6 +1034,7 @@ void hns3_update_linkstatus_and_event(struct hns3_hw *hw, bool query);
 void hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status,
 			  uint32_t link_speed, uint8_t link_duplex);
 void hns3vf_update_push_lsc_cap(struct hns3_hw *hw, bool supported);
+void hns3_clear_reset_event(struct hns3_hw *hw);
 
 static inline bool
 is_reset_pending(struct hns3_adapter *hns)
diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c
index 67a4b9b221..a2c7a90e41 100644
--- a/drivers/net/hns3/hns3_intr.c
+++ b/drivers/net/hns3/hns3_intr.c
@@ -2730,6 +2730,7 @@ hns3_reset_post(struct hns3_adapter *hns)
 		/* IMP will wait ready flag before reset */
 		hns3_notify_reset_ready(hw, false);
 		hns3_clear_reset_level(hw, &hw->reset.pending);
+		hns3_clear_reset_event(hw);
 		__atomic_store_n(&hns->hw.reset.resetting, 0, __ATOMIC_RELAXED);
 		hw->reset.attempts = 0;
 		hw->reset.stats.success_cnt++;
@@ -2844,6 +2845,7 @@ hns3_reset_process(struct hns3_adapter *hns, enum hns3_reset_level new_level)
 		return ret;
 err:
 	hns3_clear_reset_level(hw, &hw->reset.pending);
+	hns3_clear_reset_event(hw);
 	if (hns3_reset_err_handle(hns)) {
 		hw->reset.stage = RESET_STAGE_PREWAIT;
 		hns3_schedule_reset(hns);
-- 
2.33.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH 21.11] net/hns3: fix IMP or global reset
  2023-11-23  1:19 [PATCH 21.11] net/hns3: fix IMP or global reset Dengdui Huang
@ 2023-11-23 10:52 ` Kevin Traynor
  0 siblings, 0 replies; 2+ messages in thread
From: Kevin Traynor @ 2023-11-23 10:52 UTC (permalink / raw)
  To: Dengdui Huang, stable; +Cc: liuyonglong

On 23/11/2023 01:19, Dengdui Huang wrote:
> [ upstream commit 1eee1ea75c0eadaea6dde368b289cf0acf6a1190 ]
> 
> Currently, when the IMP or Global reset detected, the vector0
> interrupt is enabled before the reset process is completed.
> At this moment, if the initialization of IMP is not completed,
> and the vector0 interrupt may continue to be reported. In this
> scenario, the IMP/global reset being performed by the driver
> does not need to be interrupted. Therefore, for IMP and global
> resets, the driver has to enable the interrupt after the end
> of reset.
> 
> The RAS interrupt is also shared with the vector0 interrupt.
> When the interrupt is disabled, the RAS interrupt can still be
> reported to the driver and the driver interrupt processing
> function is also called. In this case, the interrupt status of
> the IMP/global may still exist. Therefore, this patch also has
> to the check of the new reset level based on the priority of
> reset level in the interrupt handler.
> 
> Fixes: 2790c6464725 ("net/hns3: support device reset")
> Fixes: 3988ab0eee52 ("net/hns3: add abnormal interrupt process")
> Cc:stable@dpdk.org
> 
> Signed-off-by: Dengdui Huang<huangdengdui@huawei.com>
> ---
>   drivers/net/hns3/hns3_ethdev.c | 88 ++++++++++++++++++++++++++++------
>   drivers/net/hns3/hns3_ethdev.h |  1 +
>   drivers/net/hns3/hns3_intr.c   |  2 +
>   3 files changed, 77 insertions(+), 14 deletions(-)

Applied to 21.11 branch. Thanks for backporting.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-11-23 10:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-23  1:19 [PATCH 21.11] net/hns3: fix IMP or global reset Dengdui Huang
2023-11-23 10:52 ` Kevin Traynor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).