From: Chengwen Feng fengchengwen@huawei.com
Currently, to prevent missing reporting of reset interrupts and quickly identify reset interrupts, the following logic is designed in the FW (firmware) command interface hns3_cmd_send: if an unprocessed interrupt exist (by checking reset registers), related reset task is scheduled.
The secondary process may invoke the hns3_cmd_send interface (e.g. using proc-info query some stats). Unfortunately, the secondary process does not support reset processing, and a segment fault may occur if it schedules reset task.
Fix it by limit the checking and scheduling of reset under only primary process.
Fixes: 2790c6464725 ("net/hns3: support device reset") Cc: stable@dpdk.org
Signed-off-by: Chengwen Feng fengchengwen@huawei.com Signed-off-by: Dongdong Liu liudongdong3@huawei.com --- drivers/net/hns3/hns3_ethdev.c | 10 +++++++++- drivers/net/hns3/hns3_ethdev_vf.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index 401736f5a6..24ee9df332 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -5602,7 +5602,15 @@ hns3_is_reset_pending(struct hns3_adapter *hns) struct hns3_hw *hw = &hns->hw; enum hns3_reset_level reset;
- hns3_check_event_cause(hns, NULL); + /* + * Check the registers to confirm whether there is reset pending. + * Note: This check may lead to schedule reset task, but only primary + * process can process the reset event. Therefore, limit the + * checking under only primary process. + */ + if (rte_eal_process_type() == RTE_PROC_PRIMARY) + hns3_check_event_cause(hns, NULL); + reset = hns3_get_reset_level(hns, &hw->reset.pending); if (reset != HNS3_NONE_RESET && hw->reset.level != HNS3_NONE_RESET && hw->reset.level < reset) { diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c index 0dea63e8be..db2f15abe2 100644 --- a/drivers/net/hns3/hns3_ethdev_vf.c +++ b/drivers/net/hns3/hns3_ethdev_vf.c @@ -1864,8 +1864,15 @@ hns3vf_is_reset_pending(struct hns3_adapter *hns) if (hw->reset.level == HNS3_VF_FULL_RESET) return false;
- /* Check the registers to confirm whether there is reset pending */ - hns3vf_check_event_cause(hns, NULL); + /* + * Check the registers to confirm whether there is reset pending. + * Note: This check may lead to schedule reset task, but only primary + * process can process the reset event. Therefore, limit the + * checking under only primary process. + */ + if (rte_eal_process_type() == RTE_PROC_PRIMARY) + hns3vf_check_event_cause(hns, NULL); + reset = hns3vf_get_reset_level(hw, &hw->reset.pending); if (hw->reset.level != HNS3_NONE_RESET && reset != HNS3_NONE_RESET && hw->reset.level < reset) {