From: Mingjin Ye <mingjinx.ye@intel.com>
To: dev@dpdk.org
Cc: qiming.yang@intel.com, Mingjin Ye <mingjinx.ye@intel.com>,
stable@dpdk.org, Jingjing Wu <jingjing.wu@intel.com>,
Beilei Xing <beilei.xing@intel.com>
Subject: [PATCH] net/iavf: fix no polling mode switch
Date: Tue, 5 Dec 2023 10:28:28 +0000 [thread overview]
Message-ID: <20231205102828.1446631-1-mingjinx.ye@intel.com> (raw)
PMD does not switch to no polling mode when the PF triggers a reset event
or the watchdog detects a reset event. In this scenario, data path will
access the freed resources and cause a core dump.
This patch fixes this issue by automatically switching modes on VF reset.
Fixes: 5b3124a0a6ef ("net/iavf: support no polling when link down")
Cc: stable@dpdk.org
Signed-off-by: Mingjin Ye <mingjinx.ye@intel.com>
---
drivers/net/iavf/iavf.h | 1 +
drivers/net/iavf/iavf_ethdev.c | 27 +++++++++++++++++++++++----
drivers/net/iavf/iavf_vchnl.c | 24 ++++++++++--------------
3 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 10868f2c30..18d39ee652 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -512,4 +512,5 @@ int iavf_flow_sub_check(struct iavf_adapter *adapter,
void iavf_dev_watchdog_enable(struct iavf_adapter *adapter);
void iavf_dev_watchdog_disable(struct iavf_adapter *adapter);
int iavf_handle_hw_reset(struct rte_eth_dev *dev);
+void iavf_set_no_poll(struct iavf_adapter *adapter, bool link_change);
#endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index d1edb0dd5c..0952998304 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -296,6 +296,7 @@ iavf_dev_watchdog(void *cb_arg)
PMD_DRV_LOG(INFO, "VF \"%s\" reset has completed",
adapter->vf.eth_dev->data->name);
adapter->vf.vf_reset = false;
+ iavf_set_no_poll(adapter, false);
}
/* If not in reset then poll vfr_inprogress register for VFLR event */
} else {
@@ -308,6 +309,7 @@ iavf_dev_watchdog(void *cb_arg)
/* enter reset state with VFLR event */
adapter->vf.vf_reset = true;
+ iavf_set_no_poll(adapter, false);
adapter->vf.link_up = false;
iavf_dev_event_post(adapter->vf.eth_dev, RTE_ETH_EVENT_INTR_RESET,
@@ -2916,8 +2918,10 @@ iavf_dev_close(struct rte_eth_dev *dev)
* effect.
*/
out:
- if (vf->vf_reset && !rte_pci_set_bus_master(pci_dev, true))
+ if (vf->vf_reset && !rte_pci_set_bus_master(pci_dev, true)) {
vf->vf_reset = false;
+ iavf_set_no_poll(adapter, false);
+ }
/* disable watchdog */
iavf_dev_watchdog_disable(adapter);
@@ -2948,6 +2952,8 @@ static int
iavf_dev_reset(struct rte_eth_dev *dev)
{
int ret;
+ struct iavf_adapter *adapter =
+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2962,6 +2968,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
return ret;
}
vf->vf_reset = false;
+ iavf_set_no_poll(adapter, false);
PMD_DRV_LOG(DEBUG, "Start dev_reset ...\n");
ret = iavf_dev_uninit(dev);
@@ -2977,10 +2984,13 @@ iavf_dev_reset(struct rte_eth_dev *dev)
int
iavf_handle_hw_reset(struct rte_eth_dev *dev)
{
+ struct iavf_adapter *adapter =
+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
int ret;
vf->in_reset_recovery = true;
+ iavf_set_no_poll(adapter, false);
ret = iavf_dev_reset(dev);
if (ret)
@@ -2998,16 +3008,25 @@ iavf_handle_hw_reset(struct rte_eth_dev *dev)
if (ret)
goto error;
dev->data->dev_started = 1;
-
- vf->in_reset_recovery = false;
- return 0;
+ goto exit;
error:
PMD_DRV_LOG(DEBUG, "RESET recover with error code=%d\n", ret);
+exit:
vf->in_reset_recovery = false;
+ iavf_set_no_poll(adapter, false);
return ret;
}
+void
+iavf_set_no_poll(struct iavf_adapter *adapter, bool link_change)
+{
+ struct iavf_info *vf = &adapter->vf;
+
+ adapter->no_poll = (link_change & !vf->link_up) ||
+ vf->vf_reset || vf->in_reset_recovery;
+}
+
static int
iavf_dcf_cap_check_handler(__rte_unused const char *key,
const char *value, __rte_unused void *opaque)
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
index 0a3e1d082c..1111d30f57 100644
--- a/drivers/net/iavf/iavf_vchnl.c
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -273,20 +273,18 @@ iavf_read_msg_from_pf(struct iavf_adapter *adapter, uint16_t buf_len,
iavf_dev_watchdog_enable(adapter);
}
if (adapter->devargs.no_poll_on_link_down) {
- if (vf->link_up && adapter->no_poll) {
- adapter->no_poll = false;
- PMD_DRV_LOG(DEBUG, "VF no poll turned off");
- }
- if (!vf->link_up) {
- adapter->no_poll = true;
+ iavf_set_no_poll(adapter, true);
+ if (adapter->no_poll)
PMD_DRV_LOG(DEBUG, "VF no poll turned on");
- }
+ else
+ PMD_DRV_LOG(DEBUG, "VF no poll turned off");
}
PMD_DRV_LOG(INFO, "Link status update:%s",
vf->link_up ? "up" : "down");
break;
case VIRTCHNL_EVENT_RESET_IMPENDING:
vf->vf_reset = true;
+ iavf_set_no_poll(adapter, false);
PMD_DRV_LOG(INFO, "VF is resetting");
break;
case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
@@ -462,6 +460,7 @@ iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg,
vf->link_up = false;
if (!vf->vf_reset) {
vf->vf_reset = true;
+ iavf_set_no_poll(adapter, false);
iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_RESET,
NULL, 0);
}
@@ -485,14 +484,11 @@ iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg,
iavf_dev_watchdog_enable(adapter);
}
if (adapter->devargs.no_poll_on_link_down) {
- if (vf->link_up && adapter->no_poll) {
- adapter->no_poll = false;
- PMD_DRV_LOG(DEBUG, "VF no poll turned off");
- }
- if (!vf->link_up) {
- adapter->no_poll = true;
+ iavf_set_no_poll(adapter, true);
+ if (adapter->no_poll)
PMD_DRV_LOG(DEBUG, "VF no poll turned on");
- }
+ else
+ PMD_DRV_LOG(DEBUG, "VF no poll turned off");
}
iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_LSC, NULL, 0);
break;
--
2.25.1
next reply other threads:[~2023-12-05 10:43 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-05 10:28 Mingjin Ye [this message]
2023-12-14 10:33 ` [PATCH v2] " Mingjin Ye
2024-01-03 10:31 ` Zhang, Qi Z
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231205102828.1446631-1-mingjinx.ye@intel.com \
--to=mingjinx.ye@intel.com \
--cc=beilei.xing@intel.com \
--cc=dev@dpdk.org \
--cc=jingjing.wu@intel.com \
--cc=qiming.yang@intel.com \
--cc=stable@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).