diff options
author | Tomer Tayar <Tomer.Tayar@cavium.com> | 2018-08-20 00:01:44 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-08-20 11:34:39 -0700 |
commit | eaa50fc59e5841910987e90b0438b2643041f508 (patch) | |
tree | c30440909fcbfd1a3712ebcfb18946867cd50423 /drivers/net/ethernet/qlogic/qed/qed_mcp.h | |
parent | 76271809f49056f079e202bf6513d17b0d6dd34d (diff) | |
download | linux-eaa50fc59e5841910987e90b0438b2643041f508.tar.gz linux-eaa50fc59e5841910987e90b0438b2643041f508.tar.bz2 linux-eaa50fc59e5841910987e90b0438b2643041f508.zip |
qed: Prevent a possible deadlock during driver load and unload
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>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qed/qed_mcp.h')
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_mcp.h | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h index 047976d5c6e9..b9d3ecf7aad6 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h @@ -660,14 +660,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)); }) }; struct qed_drv_tlv_hdr { |