]> Git Repo - linux.git/commitdiff
qed: Fix returning unlimited SPQ entries
authorYuval Mintz <[email protected]>
Sun, 19 Jun 2016 12:18:14 +0000 (15:18 +0300)
committerDavid S. Miller <[email protected]>
Sun, 19 Jun 2016 17:47:32 +0000 (10:47 -0700)
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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
drivers/net/ethernet/qlogic/qed/qed_spq.c

index acac6626a1b29417eacdbda3751cee4cb241ce9a..67d9893774d822b0123f353a84bc4517adf6cabf 100644 (file)
@@ -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 */
This page took 0.058238 seconds and 4 git commands to generate.