ice: Fix for memory leaks and modify ICE_FREE_CQ_BUFS
authorSurabhi Boob <surabhi.boob@intel.com>
Sat, 16 May 2020 00:36:43 +0000 (17:36 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 28 May 2020 00:32:50 +0000 (17:32 -0700)
Handle memory leaks during control queue initialization and
buffer allocation failures. The macro ICE_FREE_CQ_BUFS is modified to
re-use for this fix.

Signed-off-by: Surabhi Boob <surabhi.boob@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ice/ice_controlq.c

index 9a865962296d3ebbbfebe2dd2208170bb0cba838..62c2c1e621d26ee9aa4d4a19fd45926193e6a5fa 100644 (file)
@@ -199,7 +199,9 @@ unwind_alloc_rq_bufs:
                cq->rq.r.rq_bi[i].pa = 0;
                cq->rq.r.rq_bi[i].size = 0;
        }
+       cq->rq.r.rq_bi = NULL;
        devm_kfree(ice_hw_to_dev(hw), cq->rq.dma_head);
+       cq->rq.dma_head = NULL;
 
        return ICE_ERR_NO_MEMORY;
 }
@@ -245,7 +247,9 @@ unwind_alloc_sq_bufs:
                cq->sq.r.sq_bi[i].pa = 0;
                cq->sq.r.sq_bi[i].size = 0;
        }
+       cq->sq.r.sq_bi = NULL;
        devm_kfree(ice_hw_to_dev(hw), cq->sq.dma_head);
+       cq->sq.dma_head = NULL;
 
        return ICE_ERR_NO_MEMORY;
 }
@@ -304,6 +308,28 @@ ice_cfg_rq_regs(struct ice_hw *hw, struct ice_ctl_q_info *cq)
        return 0;
 }
 
+#define ICE_FREE_CQ_BUFS(hw, qi, ring)                                 \
+do {                                                                   \
+       int i;                                                          \
+       /* free descriptors */                                          \
+       if ((qi)->ring.r.ring##_bi)                                     \
+               for (i = 0; i < (qi)->num_##ring##_entries; i++)        \
+                       if ((qi)->ring.r.ring##_bi[i].pa) {             \
+                               dmam_free_coherent(ice_hw_to_dev(hw),   \
+                                       (qi)->ring.r.ring##_bi[i].size, \
+                                       (qi)->ring.r.ring##_bi[i].va,   \
+                                       (qi)->ring.r.ring##_bi[i].pa);  \
+                                       (qi)->ring.r.ring##_bi[i].va = NULL;\
+                                       (qi)->ring.r.ring##_bi[i].pa = 0;\
+                                       (qi)->ring.r.ring##_bi[i].size = 0;\
+               }                                                       \
+       /* free the buffer info list */                                 \
+       if ((qi)->ring.cmd_buf)                                         \
+               devm_kfree(ice_hw_to_dev(hw), (qi)->ring.cmd_buf);      \
+       /* free DMA head */                                             \
+       devm_kfree(ice_hw_to_dev(hw), (qi)->ring.dma_head);             \
+} while (0)
+
 /**
  * ice_init_sq - main initialization routine for Control ATQ
  * @hw: pointer to the hardware structure
@@ -357,6 +383,7 @@ static enum ice_status ice_init_sq(struct ice_hw *hw, struct ice_ctl_q_info *cq)
        goto init_ctrlq_exit;
 
 init_ctrlq_free_rings:
+       ICE_FREE_CQ_BUFS(hw, cq, sq);
        ice_free_cq_ring(hw, &cq->sq);
 
 init_ctrlq_exit:
@@ -416,33 +443,13 @@ static enum ice_status ice_init_rq(struct ice_hw *hw, struct ice_ctl_q_info *cq)
        goto init_ctrlq_exit;
 
 init_ctrlq_free_rings:
+       ICE_FREE_CQ_BUFS(hw, cq, rq);
        ice_free_cq_ring(hw, &cq->rq);
 
 init_ctrlq_exit:
        return ret_code;
 }
 
-#define ICE_FREE_CQ_BUFS(hw, qi, ring)                                 \
-do {                                                                   \
-       int i;                                                          \
-       /* free descriptors */                                          \
-       for (i = 0; i < (qi)->num_##ring##_entries; i++)                \
-               if ((qi)->ring.r.ring##_bi[i].pa) {                     \
-                       dmam_free_coherent(ice_hw_to_dev(hw),           \
-                                          (qi)->ring.r.ring##_bi[i].size,\
-                                          (qi)->ring.r.ring##_bi[i].va,\
-                                          (qi)->ring.r.ring##_bi[i].pa);\
-                       (qi)->ring.r.ring##_bi[i].va = NULL;            \
-                       (qi)->ring.r.ring##_bi[i].pa = 0;               \
-                       (qi)->ring.r.ring##_bi[i].size = 0;             \
-               }                                                       \
-       /* free the buffer info list */                                 \
-       if ((qi)->ring.cmd_buf)                                         \
-               devm_kfree(ice_hw_to_dev(hw), (qi)->ring.cmd_buf);      \
-       /* free DMA head */                                             \
-       devm_kfree(ice_hw_to_dev(hw), (qi)->ring.dma_head);             \
-} while (0)
-
 /**
  * ice_shutdown_sq - shutdown the Control ATQ
  * @hw: pointer to the hardware structure