summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Mintz <Yuval.Mintz@qlogic.com>2016-06-19 15:18:14 +0300
committerDavid S. Miller <davem@davemloft.net>2016-06-19 10:47:32 -0700
commitdb511c37d4eb2b4e7312791eb8f9b34ed867445e (patch)
tree7355b5deb8c556fd8f5419e3c20e2ba8fe0367a9
parenta0d26d5a4fc8e13993279f788deeb08069e73b69 (diff)
qed: Fix returning unlimited SPQ entries
Driver has 2 sets of entries for handling ramrod configurations toward firmware - a regular pre-allocated set of entires and a possible 'unlimited' list of additional pending entries. In most scenarios the 'unlimited' list would not be used, but when it does the handling of the ramrod completion doesn't properly handle the release of the entry. Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_spq.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c
index acac6626a1b2..67d9893774d8 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_spq.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c
@@ -614,7 +614,9 @@ qed_spq_add_entry(struct qed_hwfn *p_hwfn,
*p_en2 = *p_ent;
- kfree(p_ent);
+ /* EBLOCK responsible to free the allocated p_ent */
+ if (p_ent->comp_mode != QED_SPQ_MODE_EBLOCK)
+ kfree(p_ent);
p_ent = p_en2;
}
@@ -749,6 +751,15 @@ int qed_spq_post(struct qed_hwfn *p_hwfn,
* Thus, after gaining the answer perform the cleanup here.
*/
rc = qed_spq_block(p_hwfn, p_ent, fw_return_code);
+
+ if (p_ent->queue == &p_spq->unlimited_pending) {
+ /* This is an allocated p_ent which does not need to
+ * return to pool.
+ */
+ kfree(p_ent);
+ return rc;
+ }
+
if (rc)
goto spq_post_fail2;
@@ -844,8 +855,12 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn,
found->comp_cb.function(p_hwfn, found->comp_cb.cookie, p_data,
fw_return_code);
- if (found->comp_mode != QED_SPQ_MODE_EBLOCK)
- /* EBLOCK is responsible for freeing its own entry */
+ if ((found->comp_mode != QED_SPQ_MODE_EBLOCK) ||
+ (found->queue == &p_spq->unlimited_pending))
+ /* EBLOCK is responsible for returning its own entry into the
+ * free list, unless it originally added the entry into the
+ * unlimited pending list.
+ */
qed_spq_return_entry(p_hwfn, found);
/* Attempt to post pending requests */