* [PATCH] net/iavf: fix no polling mode switch
@ 2023-12-05 10:28 Mingjin Ye
2023-12-14 10:33 ` [PATCH v2] " Mingjin Ye
0 siblings, 1 reply; 3+ messages in thread
From: Mingjin Ye @ 2023-12-05 10:28 UTC (permalink / raw)
To: dev; +Cc: qiming.yang, Mingjin Ye, stable, Jingjing Wu, Beilei Xing
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
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v2] net/iavf: fix no polling mode switch
2023-12-05 10:28 [PATCH] net/iavf: fix no polling mode switch Mingjin Ye
@ 2023-12-14 10:33 ` Mingjin Ye
2024-01-03 10:31 ` Zhang, Qi Z
0 siblings, 1 reply; 3+ messages in thread
From: Mingjin Ye @ 2023-12-14 10:33 UTC (permalink / raw)
To: dev; +Cc: qiming.yang, Mingjin Ye, stable, Jingjing Wu, Beilei Xing
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>
---
v2: Increase reset completion wait count.
---
drivers/net/iavf/iavf.h | 3 ++-
drivers/net/iavf/iavf_ethdev.c | 27 +++++++++++++++++++++++----
drivers/net/iavf/iavf_vchnl.c | 24 ++++++++++--------------
3 files changed, 35 insertions(+), 19 deletions(-)
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 10868f2c30..5bfe85dabd 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -18,7 +18,7 @@
#define IAVF_AQ_LEN 32
#define IAVF_AQ_BUF_SZ 4096
-#define IAVF_RESET_WAIT_CNT 500
+#define IAVF_RESET_WAIT_CNT 2000
#define IAVF_BUF_SIZE_MIN 1024
#define IAVF_FRAME_SIZE_MAX 9728
#define IAVF_QUEUE_BASE_ADDR_UNIT 128
@@ -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
^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: [PATCH v2] net/iavf: fix no polling mode switch
2023-12-14 10:33 ` [PATCH v2] " Mingjin Ye
@ 2024-01-03 10:31 ` Zhang, Qi Z
0 siblings, 0 replies; 3+ messages in thread
From: Zhang, Qi Z @ 2024-01-03 10:31 UTC (permalink / raw)
To: Ye, MingjinX, dev
Cc: Yang, Qiming, Ye, MingjinX, stable, Wu, Jingjing, Xing, Beilei
> -----Original Message-----
> From: Mingjin Ye <mingjinx.ye@intel.com>
> Sent: Thursday, December 14, 2023 6:33 PM
> To: dev@dpdk.org
> Cc: Yang, Qiming <qiming.yang@intel.com>; Ye, MingjinX
> <mingjinx.ye@intel.com>; stable@dpdk.org; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>
> Subject: [PATCH v2] net/iavf: fix no polling mode switch
>
> 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>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
Applied to dpdk-next-net-intel.
Thanks
Qi
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-01-03 10:31 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-05 10:28 [PATCH] net/iavf: fix no polling mode switch Mingjin Ye
2023-12-14 10:33 ` [PATCH v2] " Mingjin Ye
2024-01-03 10:31 ` Zhang, Qi Z
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).