From patchwork Wed Jun 15 07:53:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xing, Beilei" X-Patchwork-Id: 13778 X-Patchwork-Delegate: bruce.richardson@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 512F3C32C; Wed, 15 Jun 2016 09:54:33 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 991CAC32A for ; Wed, 15 Jun 2016 09:54:31 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 15 Jun 2016 00:54:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,475,1459839600"; d="scan'208";a="976001988" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga001.jf.intel.com with ESMTP; 15 Jun 2016 00:54:30 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id u5F7sQed016185; Wed, 15 Jun 2016 15:54:26 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id u5F7sNBm004141; Wed, 15 Jun 2016 15:54:25 +0800 Received: (from beileixi@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id u5F7sM5Z004137; Wed, 15 Jun 2016 15:54:22 +0800 From: Beilei Xing To: wenzhuo.lu@intel.com Cc: dev@dpdk.org, Beilei Xing Date: Wed, 15 Jun 2016 15:53:29 +0800 Message-Id: <1465977220-3970-20-git-send-email-beilei.xing@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1465977220-3970-1-git-send-email-beilei.xing@intel.com> References: <1465887596-10346-1-git-send-email-beilei.xing@intel.com> <1465977220-3970-1-git-send-email-beilei.xing@intel.com> Subject: [dpdk-dev] [PATCH v3 19/30] ixgbe/base: fix possible race issue X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch fixes possible race issue between ports when issuing host interface command by acquiring/releasing the management host interface semaphore in ixgbe_host_interface_command. Fixes: 36f43e8679ae ("ixgbe/base: refactor manageability block communication") Signed-off-by: Beilei Xing --- drivers/net/ixgbe/base/ixgbe_common.c | 40 ++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/net/ixgbe/base/ixgbe_common.c b/drivers/net/ixgbe/base/ixgbe_common.c index 0a74714..0a708cf 100644 --- a/drivers/net/ixgbe/base/ixgbe_common.c +++ b/drivers/net/ixgbe/base/ixgbe_common.c @@ -4373,8 +4373,9 @@ u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) * So we will leave this up to the caller to read back the data * in these cases. * - * Communicates with the manageability block. On success return IXGBE_SUCCESS - * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. + * Communicates with the manageability block. On success return IXGBE_SUCCESS + * else returns semaphore error when encountering an error acquiring + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. **/ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, u32 length, u32 timeout, bool return_data) @@ -4383,6 +4384,7 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, u32 hdr_size = sizeof(struct ixgbe_hic_hdr); u16 buf_len; u16 dword_len; + s32 status; DEBUGFUNC("ixgbe_host_interface_command"); @@ -4390,6 +4392,11 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, DEBUGOUT1("Buffer length failure buffersize=%d.\n", length); return IXGBE_ERR_HOST_INTERFACE_COMMAND; } + /* Take management host interface semaphore */ + status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); + + if (status) + return status; /* Set bit 9 of FWSTS clearing FW reset indication */ fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS); @@ -4399,13 +4406,15 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, hicr = IXGBE_READ_REG(hw, IXGBE_HICR); if ((hicr & IXGBE_HICR_EN) == 0) { DEBUGOUT("IXGBE_HOST_EN bit disabled.\n"); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + status = IXGBE_ERR_HOST_INTERFACE_COMMAND; + goto rel_out; } /* Calculate length in DWORDs. We must be DWORD aligned */ if ((length % (sizeof(u32))) != 0) { DEBUGOUT("Buffer length failure, not aligned to dword"); - return IXGBE_ERR_INVALID_ARGUMENT; + status = IXGBE_ERR_INVALID_ARGUMENT; + goto rel_out; } dword_len = length >> 2; @@ -4432,11 +4441,12 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) { ERROR_REPORT1(IXGBE_ERROR_CAUTION, "Command has failed with no status valid.\n"); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + status = IXGBE_ERR_HOST_INTERFACE_COMMAND; + goto rel_out; } if (!return_data) - return 0; + goto rel_out; /* Calculate length in DWORDs */ dword_len = hdr_size >> 2; @@ -4450,11 +4460,12 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, /* If there is any thing in data position pull it in */ buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len; if (buf_len == 0) - return 0; + goto rel_out; if (length < buf_len + hdr_size) { DEBUGOUT("Buffer not large enough for reply message.\n"); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + status = IXGBE_ERR_HOST_INTERFACE_COMMAND; + goto rel_out; } /* Calculate length in DWORDs, add 3 for odd lengths */ @@ -4466,7 +4477,10 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, IXGBE_LE32_TO_CPUS(&buffer[bi]); } - return 0; +rel_out: + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); + + return status; } /** @@ -4491,12 +4505,6 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, DEBUGFUNC("ixgbe_set_fw_drv_ver_generic"); - if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM) - != IXGBE_SUCCESS) { - ret_val = IXGBE_ERR_SWFW_SYNC; - goto out; - } - fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN; fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; @@ -4528,8 +4536,6 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, break; } - hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); -out: return ret_val; }