ice_dcf_hierarchy_commit() keeps a copy of the bandwidth config
of each VF, and of the TC nodes, in qos_bw_cfg[] to replay it
after a VF reset.
Each commit allocates new copies without freeing the old ones,
and ice_dcf_uninit_hw() frees the array but not the copies, so
they also leak on close and reset.

Free the old copy before allocating a new one, and free all copies
in ice_dcf_uninit_hw().

Fixes: 931ee54072b1 ("net/ice: support QoS bandwidth config after VF reset in 
DCF")
Fixes: 775a25a372f5 ("net/ice: clear QoS bandwidth on DCF close")
Cc: [email protected]

Signed-off-by: Anurag Mandal <[email protected]>
---
 drivers/net/intel/ice/ice_dcf.c       | 6 ++++++
 drivers/net/intel/ice/ice_dcf_sched.c | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/intel/ice/ice_dcf.c b/drivers/net/intel/ice/ice_dcf.c
index 09fcf6454f..c2b557d0da 100644
--- a/drivers/net/intel/ice/ice_dcf.c
+++ b/drivers/net/intel/ice/ice_dcf.c
@@ -884,6 +884,7 @@ ice_dcf_uninit_hw(struct rte_eth_dev *eth_dev, struct 
ice_dcf_hw *hw)
 {
        struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, 
*pci_dev);
        struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+       uint16_t i;
 
        if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS)
                if (hw->tm_conf.committed) {
@@ -919,6 +920,11 @@ ice_dcf_uninit_hw(struct rte_eth_dev *eth_dev, struct 
ice_dcf_hw *hw)
        rte_free(hw->rss_key);
        hw->rss_key = NULL;
 
+       if (hw->qos_bw_cfg != NULL) {
+               for (i = 0; i < hw->num_vfs; i++)
+                       rte_free(hw->qos_bw_cfg[i]);
+       }
+
        rte_free(hw->qos_bw_cfg);
        hw->qos_bw_cfg = NULL;
 
diff --git a/drivers/net/intel/ice/ice_dcf_sched.c 
b/drivers/net/intel/ice/ice_dcf_sched.c
index de28019c5b..f8755c7dcb 100644
--- a/drivers/net/intel/ice/ice_dcf_sched.c
+++ b/drivers/net/intel/ice/ice_dcf_sched.c
@@ -813,6 +813,7 @@ static int ice_dcf_hierarchy_commit(struct rte_eth_dev *dev,
                if (ret_val)
                        goto fail_clear;
 
+               rte_free(hw->qos_bw_cfg[vf_id]);
                hw->qos_bw_cfg[vf_id] = rte_zmalloc("vf_bw_cfg", size, 0);
                if (!hw->qos_bw_cfg[vf_id]) {
                        ret_val = ICE_ERR_NO_MEMORY;
@@ -840,6 +841,7 @@ static int ice_dcf_hierarchy_commit(struct rte_eth_dev *dev,
                goto fail_clear;
 
        /* store TC node bw configuration */
+       rte_free(hw->qos_bw_cfg[ICE_DCF_VFID]);
        hw->qos_bw_cfg[ICE_DCF_VFID] = rte_zmalloc("tc_bw_cfg", size, 0);
        if (!hw->qos_bw_cfg[ICE_DCF_VFID]) {
                ret_val = ICE_ERR_NO_MEMORY;
-- 
2.25.1

Reply via email to