diff options
author | Sagiv Ozeri <sagiv.ozeri@cavium.com> | 2018-11-08 09:46:11 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-11-08 22:38:19 -0500 |
commit | fa5c448d98f0df660bfcad3dd5facc027ef84cd3 (patch) | |
tree | b3302708cdb9cce6cb78aeb27d785ccfd17acd2a /drivers/net | |
parent | fb5e7438e7a3c8966e04ccb0760170e9e06f3699 (diff) |
qed: Fix potential memory corruption
A stuck ramrod should be deleted from the completion_pending list,
otherwise it will be added again in the future and corrupt the list.
Return error value to inform that ramrod is stuck and should be deleted.
Signed-off-by: Sagiv Ozeri <sagiv.ozeri@cavium.com>
Signed-off-by: Denis Bolotin <denis.bolotin@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_spq.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c index c1a81ec0524b..0a9c5bb0fa48 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_spq.c +++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c | |||
@@ -142,6 +142,7 @@ static int qed_spq_block(struct qed_hwfn *p_hwfn, | |||
142 | 142 | ||
143 | DP_INFO(p_hwfn, "Ramrod is stuck, requesting MCP drain\n"); | 143 | DP_INFO(p_hwfn, "Ramrod is stuck, requesting MCP drain\n"); |
144 | rc = qed_mcp_drain(p_hwfn, p_ptt); | 144 | rc = qed_mcp_drain(p_hwfn, p_ptt); |
145 | qed_ptt_release(p_hwfn, p_ptt); | ||
145 | if (rc) { | 146 | if (rc) { |
146 | DP_NOTICE(p_hwfn, "MCP drain failed\n"); | 147 | DP_NOTICE(p_hwfn, "MCP drain failed\n"); |
147 | goto err; | 148 | goto err; |
@@ -150,18 +151,15 @@ static int qed_spq_block(struct qed_hwfn *p_hwfn, | |||
150 | /* Retry after drain */ | 151 | /* Retry after drain */ |
151 | rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, true); | 152 | rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, true); |
152 | if (!rc) | 153 | if (!rc) |
153 | goto out; | 154 | return 0; |
154 | 155 | ||
155 | comp_done = (struct qed_spq_comp_done *)p_ent->comp_cb.cookie; | 156 | comp_done = (struct qed_spq_comp_done *)p_ent->comp_cb.cookie; |
156 | if (comp_done->done == 1) | 157 | if (comp_done->done == 1) { |
157 | if (p_fw_ret) | 158 | if (p_fw_ret) |
158 | *p_fw_ret = comp_done->fw_return_code; | 159 | *p_fw_ret = comp_done->fw_return_code; |
159 | out: | 160 | return 0; |
160 | qed_ptt_release(p_hwfn, p_ptt); | 161 | } |
161 | return 0; | ||
162 | |||
163 | err: | 162 | err: |
164 | qed_ptt_release(p_hwfn, p_ptt); | ||
165 | DP_NOTICE(p_hwfn, | 163 | DP_NOTICE(p_hwfn, |
166 | "Ramrod is stuck [CID %08x cmd %02x protocol %02x echo %04x]\n", | 164 | "Ramrod is stuck [CID %08x cmd %02x protocol %02x echo %04x]\n", |
167 | le32_to_cpu(p_ent->elem.hdr.cid), | 165 | le32_to_cpu(p_ent->elem.hdr.cid), |