From: Sasha Levin <Alexander.Levin@microsoft.com>
To: "stable@vger.kernel.org" <stable@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: Tomer Tayar <Tomer.Tayar@cavium.com>,
Ariel Elior <Ariel.Elior@cavium.com>,
"David S . Miller" <davem@davemloft.net>,
Sasha Levin <Alexander.Levin@microsoft.com>
Subject: [PATCH AUTOSEL 4.14 03/25] qed: Prevent a possible deadlock during driver load and unload
Date: Thu, 20 Sep 2018 02:48:16 +0000 [thread overview]
Message-ID: <20180920024810.58594-3-alexander.levin@microsoft.com> (raw)
In-Reply-To: <20180920024810.58594-1-alexander.levin@microsoft.com>
From: Tomer Tayar <Tomer.Tayar@cavium.com>
[ Upstream commit eaa50fc59e5841910987e90b0438b2643041f508 ]
The MFW manages an internal lock to prevent concurrent hardware
(de)initialization of different PFs.
This, together with the busy-waiting for the MFW's responses for commands,
might lead to a deadlock during concurrent load or unload of PFs.
This patch adds the option to sleep within the busy-waiting, and uses it
for the (un)load requests (which are not sent from an interrupt context) to
prevent the possible deadlock.
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
---
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 43 ++++++++++++++++-------
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 21 ++++++-----
2 files changed, 44 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 5748bcb26d40..a1e1092fa3ce 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -47,7 +47,7 @@
#include "qed_reg_addr.h"
#include "qed_sriov.h"
-#define CHIP_MCP_RESP_ITER_US 10
+#define QED_MCP_RESP_ITER_US 10
#define QED_DRV_MB_MAX_RETRIES (500 * 1000) /* Account for 5 sec */
#define QED_MCP_RESET_RETRIES (50 * 1000) /* Account for 500 msec */
@@ -316,7 +316,7 @@ static void qed_mcp_reread_offsets(struct qed_hwfn *p_hwfn,
int qed_mcp_reset(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
- u32 org_mcp_reset_seq, seq, delay = CHIP_MCP_RESP_ITER_US, cnt = 0;
+ u32 org_mcp_reset_seq, seq, delay = QED_MCP_RESP_ITER_US, cnt = 0;
int rc = 0;
/* Ensure that only a single thread is accessing the mailbox */
@@ -448,10 +448,10 @@ static int
_qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
struct qed_mcp_mb_params *p_mb_params,
- u32 max_retries, u32 delay)
+ u32 max_retries, u32 usecs)
{
+ u32 cnt = 0, msecs = DIV_ROUND_UP(usecs, 1000);
struct qed_mcp_cmd_elem *p_cmd_elem;
- u32 cnt = 0;
u16 seq_num;
int rc = 0;
@@ -474,7 +474,11 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
goto err;
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
- udelay(delay);
+
+ if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
+ msleep(msecs);
+ else
+ udelay(usecs);
} while (++cnt < max_retries);
if (cnt >= max_retries) {
@@ -503,7 +507,11 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
* The spinlock stays locked until the list element is removed.
*/
- udelay(delay);
+ if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
+ msleep(msecs);
+ else
+ udelay(usecs);
+
spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
if (p_cmd_elem->b_is_completed)
@@ -538,7 +546,7 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
"MFW mailbox: response 0x%08x param 0x%08x [after %d.%03d ms]\n",
p_mb_params->mcp_resp,
p_mb_params->mcp_param,
- (cnt * delay) / 1000, (cnt * delay) % 1000);
+ (cnt * usecs) / 1000, (cnt * usecs) % 1000);
/* Clear the sequence number from the MFW response */
p_mb_params->mcp_resp &= FW_MSG_CODE_MASK;
@@ -556,7 +564,7 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
{
size_t union_data_size = sizeof(union drv_union_data);
u32 max_retries = QED_DRV_MB_MAX_RETRIES;
- u32 delay = CHIP_MCP_RESP_ITER_US;
+ u32 usecs = QED_MCP_RESP_ITER_US;
/* MCP not initialized */
if (!qed_mcp_is_init(p_hwfn)) {
@@ -573,8 +581,13 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
return -EINVAL;
}
+ if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP)) {
+ max_retries = DIV_ROUND_UP(max_retries, 1000);
+ usecs *= 1000;
+ }
+
return _qed_mcp_cmd_and_union(p_hwfn, p_ptt, p_mb_params, max_retries,
- delay);
+ usecs);
}
int qed_mcp_cmd(struct qed_hwfn *p_hwfn,
@@ -763,6 +776,7 @@ __qed_mcp_load_req(struct qed_hwfn *p_hwfn,
mb_params.data_src_size = sizeof(load_req);
mb_params.p_data_dst = &load_rsp;
mb_params.data_dst_size = sizeof(load_rsp);
+ mb_params.flags = QED_MB_FLAG_CAN_SLEEP;
DP_VERBOSE(p_hwfn, QED_MSG_SP,
"Load Request: param 0x%08x [init_hw %d, drv_type %d, hsi_ver %d, pda 0x%04x]\n",
@@ -984,7 +998,8 @@ int qed_mcp_load_req(struct qed_hwfn *p_hwfn,
int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
- u32 wol_param, mcp_resp, mcp_param;
+ struct qed_mcp_mb_params mb_params;
+ u32 wol_param;
switch (p_hwfn->cdev->wol_config) {
case QED_OV_WOL_DISABLED:
@@ -1002,8 +1017,12 @@ int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
wol_param = DRV_MB_PARAM_UNLOAD_WOL_MCP;
}
- return qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_UNLOAD_REQ, wol_param,
- &mcp_resp, &mcp_param);
+ memset(&mb_params, 0, sizeof(mb_params));
+ mb_params.cmd = DRV_MSG_CODE_UNLOAD_REQ;
+ mb_params.param = wol_param;
+ mb_params.flags = QED_MB_FLAG_CAN_SLEEP;
+
+ return qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
}
int qed_mcp_unload_done(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
index c7ec2395d1ce..e5d0483f3c44 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
@@ -565,14 +565,19 @@ struct qed_mcp_info {
};
struct qed_mcp_mb_params {
- u32 cmd;
- u32 param;
- void *p_data_src;
- u8 data_src_size;
- void *p_data_dst;
- u8 data_dst_size;
- u32 mcp_resp;
- u32 mcp_param;
+ u32 cmd;
+ u32 param;
+ void *p_data_src;
+ void *p_data_dst;
+ u8 data_src_size;
+ u8 data_dst_size;
+ u32 mcp_resp;
+ u32 mcp_param;
+ u32 flags;
+#define QED_MB_FLAG_CAN_SLEEP (0x1 << 0)
+#define QED_MB_FLAGS_IS_SET(params, flag) \
+ ({ typeof(params) __params = (params); \
+ (__params && (__params->flags & QED_MB_FLAG_ ## flag)); })
};
/**
--
2.17.1
next prev parent reply other threads:[~2018-09-20 2:52 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-20 2:48 [PATCH AUTOSEL 4.14 01/25] qed: Wait for ready indication before rereading the shmem Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 02/25] qed: Wait for MCP halt and resume commands to take place Sasha Levin
2018-09-20 2:48 ` Sasha Levin [this message]
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 05/25] thermal: of-thermal: disable passive polling when thermal zone is disabled Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 04/25] qed: Avoid sending mailbox commands when MFW is not responsive Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 06/25] isofs: reject hardware sector size > 2048 bytes Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 07/25] tls: possible hang when do_tcp_sendpages hits sndbuf is full case Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 08/25] bpf: sockmap: write_space events need to be passed to TCP handler Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 09/25] net: hns: fix length and page_offset overflow when CONFIG_ARM64_64K_PAGES Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 10/25] net: hns: fix skb->truesize underestimation Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 11/25] e1000: check on netif_running() before calling e1000_up() Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 12/25] e1000: ensure to free old tx/rx rings in set_ringparam() Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 13/25] crypto: cavium/nitrox - fix for command corruption in queue full case with backlog submissions Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 14/25] hwmon: (ina2xx) fix sysfs shunt resistor read access Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 15/25] hwmon: (adt7475) Make adt7475_read_word() return errors Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 16/25] Revert "ARM: dts: imx7d: Invert legacy PCI irq mapping" Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 17/25] drm/amdgpu: Enable/disable gfx PG feature in rlc safe mode Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 18/25] drm/amdgpu: Update power state at the end of smu hw_init Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 19/25] ata: ftide010: Add a quirk for SQ201 Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 20/25] nvme-fcloop: Fix dropped LS's to removed target port Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 21/25] ARM: dts: omap4-droid4: Fix emmc errors seen on some devices Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 22/25] arm/arm64: smccc-1.1: Make return values unsigned long Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 24/25] i2c: i801: Allow ACPI AML access I/O ports not reserved for SMBus Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 23/25] arm/arm64: smccc-1.1: Handle function result as parameters Sasha Levin
2018-09-20 2:48 ` [PATCH AUTOSEL 4.14 25/25] x86/pti: Fix section mismatch warning/error Sasha Levin
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=20180920024810.58594-3-alexander.levin@microsoft.com \
--to=alexander.levin@microsoft.com \
--cc=Ariel.Elior@cavium.com \
--cc=Tomer.Tayar@cavium.com \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.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).