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 | |
| 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>
| -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), |
