From patchwork Thu Dec 14 10:33:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mingjin Ye X-Patchwork-Id: 135193 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9CD9A436EE; Thu, 14 Dec 2023 11:49:13 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F08A942FFD; Thu, 14 Dec 2023 11:49:12 +0100 (CET) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by mails.dpdk.org (Postfix) with ESMTP id 28223402E6; Thu, 14 Dec 2023 11:49:09 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1702550950; x=1734086950; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9l+Hslw0h5rydVjXj3mptUaVchR1ZLAZLD33VrUEFFg=; b=grwc1G++GzmfH+6rGyFnaNRfw1XvYmWRLIA24APz1dyAabow36Nb01aQ dsmIuUDGisFa41Qys4AOv5rWpx6HBqLtm3mH4JbxsI2gR0ngl8Uih6A/L 5Ma9FMAEWkXewU8q2knXl8N9aknv4EKbHcYAXdF3sNODAfp3XBPUdm/4U M76QU1BsJXnsy1vBbLiKRL0e5N8IyY8ESNNa7uGygx1UwJwEFAOVOm7ft gR+Nndf2HAmZe/v5Dr6T5QBrtpRxcw3glDTEbgd34crw3DBWGGiekRswG /wTeC4AMM1wAEZ9zggxRbk74rxMFbvH+vCNHrVcCjAjd90s1Ex7P507V2 w==; X-IronPort-AV: E=McAfee;i="6600,9927,10923"; a="392276552" X-IronPort-AV: E=Sophos;i="6.04,275,1695711600"; d="scan'208";a="392276552" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2023 02:49:08 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.04,275,1695711600"; d="scan'208";a="22354001" Received: from unknown (HELO localhost.localdomain) ([10.239.252.253]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2023 02:49:07 -0800 From: Mingjin Ye To: dev@dpdk.org Cc: qiming.yang@intel.com, Mingjin Ye , stable@dpdk.org, Jingjing Wu , Beilei Xing Subject: [PATCH v2] net/iavf: fix no polling mode switch Date: Thu, 14 Dec 2023 10:33:02 +0000 Message-Id: <20231214103302.900680-1-mingjinx.ye@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231205102828.1446631-1-mingjinx.ye@intel.com> References: <20231205102828.1446631-1-mingjinx.ye@intel.com> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org 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 Acked-by: Qi Zhang --- 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;