Skip to content

Commit

Permalink
net/hns3: fix multiple reset detected log
Browse files Browse the repository at this point in the history
[ upstream commit 5be38fc6c0fc7e54d0121bab2fe93a27b8e8f7ab ]

Currently, the driver proactively checks whether interrupt exist
(by checking reset registers), related reset delay task is scheduled.

When a reset whose level is equal to or lower than the current level
is detected, there is unnecessary to add delay task and print logs.

This patch fix it.

Fixes: 2790c64 ("net/hns3: support device reset")

Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
  • Loading branch information
Dengdui Huang authored and kevintraynor committed Nov 15, 2023
1 parent b28a338 commit 0bc0e51
Showing 1 changed file with 37 additions and 27 deletions.
64 changes: 37 additions & 27 deletions drivers/net/hns3/hns3_ethdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,42 +128,29 @@ hns3_pf_enable_irq0(struct hns3_hw *hw)
}

static enum hns3_evt_cause
hns3_proc_imp_reset_event(struct hns3_adapter *hns, bool is_delay,
uint32_t *vec_val)
hns3_proc_imp_reset_event(struct hns3_adapter *hns, uint32_t *vec_val)
{
struct hns3_hw *hw = &hns->hw;

__atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED);
hns3_atomic_set_bit(HNS3_IMP_RESET, &hw->reset.pending);
*vec_val = BIT(HNS3_VECTOR0_IMPRESET_INT_B);
if (!is_delay) {
hw->reset.stats.imp_cnt++;
hns3_warn(hw, "IMP reset detected, clear reset status");
} else {
hns3_schedule_delayed_reset(hns);
hns3_warn(hw, "IMP reset detected, don't clear reset status");
}
hw->reset.stats.imp_cnt++;
hns3_warn(hw, "IMP reset detected, clear reset status");

return HNS3_VECTOR0_EVENT_RST;
}

static enum hns3_evt_cause
hns3_proc_global_reset_event(struct hns3_adapter *hns, bool is_delay,
uint32_t *vec_val)
hns3_proc_global_reset_event(struct hns3_adapter *hns, uint32_t *vec_val)
{
struct hns3_hw *hw = &hns->hw;

__atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED);
hns3_atomic_set_bit(HNS3_GLOBAL_RESET, &hw->reset.pending);
*vec_val = BIT(HNS3_VECTOR0_GLOBALRESET_INT_B);
if (!is_delay) {
hw->reset.stats.global_cnt++;
hns3_warn(hw, "Global reset detected, clear reset status");
} else {
hns3_schedule_delayed_reset(hns);
hns3_warn(hw,
"Global reset detected, don't clear reset status");
}
hw->reset.stats.global_cnt++;
hns3_warn(hw, "Global reset detected, clear reset status");

return HNS3_VECTOR0_EVENT_RST;
}
Expand All @@ -177,14 +164,12 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)
uint32_t hw_err_src_reg;
uint32_t val;
enum hns3_evt_cause ret;
bool is_delay;

/* fetch the events from their corresponding regs */
vector0_int_stats = hns3_read_dev(hw, HNS3_VECTOR0_OTHER_INT_STS_REG);
cmdq_src_val = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG);
hw_err_src_reg = hns3_read_dev(hw, HNS3_RAS_PF_OTHER_INT_STS_REG);

is_delay = clearval == NULL ? true : false;
/*
* Assumption: If by any chance reset and mailbox events are reported
* together then we will only process reset event and defer the
Expand All @@ -193,13 +178,13 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)
* from H/W just for the mailbox.
*/
if (BIT(HNS3_VECTOR0_IMPRESET_INT_B) & vector0_int_stats) { /* IMP */
ret = hns3_proc_imp_reset_event(hns, is_delay, &val);
ret = hns3_proc_imp_reset_event(hns, &val);
goto out;
}

/* Global reset */
if (BIT(HNS3_VECTOR0_GLOBALRESET_INT_B) & vector0_int_stats) {
ret = hns3_proc_global_reset_event(hns, is_delay, &val);
ret = hns3_proc_global_reset_event(hns, &val);
goto out;
}

Expand Down Expand Up @@ -228,10 +213,9 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)

val = vector0_int_stats;
ret = HNS3_VECTOR0_EVENT_OTHER;
out:

if (clearval)
*clearval = val;
out:
*clearval = val;
return ret;
}

Expand Down Expand Up @@ -5565,6 +5549,32 @@ is_pf_reset_done(struct hns3_hw *hw)
return true;
}

static void
hns3_detect_reset_event(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_intr_state;

last_req = hns3_get_reset_level(hns, &hw->reset.pending);
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;
}

if (new_req != HNS3_NONE_RESET && last_req < new_req) {
hns3_schedule_delayed_reset(hns);
hns3_warn(hw, "High level reset detected, delay do reset");
}
}

bool
hns3_is_reset_pending(struct hns3_adapter *hns)
{
Expand All @@ -5578,7 +5588,7 @@ hns3_is_reset_pending(struct hns3_adapter *hns)
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return false;

hns3_check_event_cause(hns, NULL);
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) {
Expand Down

0 comments on commit 0bc0e51

Please sign in to comment.