On iavf TM hierarchy commit, the queue to traffic class mapping is
generated and stored in a pointer from the VF structure. However, that
data is never later freed. The data is also unnecessarily allocated from
hugepage memory.
Fix these issues by replacing rte_zmalloc with calloc, and then
appropriately freeing the memory at a) uninit of the device, b) at
failure of apply of the new settings and c) replacement of old data by
new.
Fixes: 3fd32df381f8 ("net/iavf: check Tx packet with correct UP and queue")
Cc: [email protected]
Signed-off-by: Bruce Richardson <[email protected]>
---
drivers/net/intel/iavf/iavf_ethdev.c | 2 ++
drivers/net/intel/iavf/iavf_tm.c | 11 ++++++++---
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c
b/drivers/net/intel/iavf/iavf_ethdev.c
index 80e740ef29..1cd8c88384 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -2755,6 +2755,8 @@ iavf_uninit_vf(struct rte_eth_dev *dev)
rte_free(vf->qos_cap);
vf->qos_cap = NULL;
+ free(vf->qtc_map);
+ vf->qtc_map = NULL;
rte_free(vf->rss_lut);
vf->rss_lut = NULL;
diff --git a/drivers/net/intel/iavf/iavf_tm.c b/drivers/net/intel/iavf/iavf_tm.c
index cc5c86b4ce..0f39da232d 100644
--- a/drivers/net/intel/iavf/iavf_tm.c
+++ b/drivers/net/intel/iavf/iavf_tm.c
@@ -96,6 +96,9 @@ iavf_tm_conf_uninit(struct rte_eth_dev *dev)
shaper_profile, node);
rte_free(shaper_profile);
}
+
+ free(vf->qtc_map);
+ vf->qtc_map = NULL;
}
static inline struct iavf_tm_node *
@@ -800,7 +803,8 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
struct virtchnl_queues_bw_cfg *q_bw = NULL;
struct iavf_tm_node_list *queue_list = &vf->tm_conf.queue_list;
struct iavf_tm_node *tm_node;
- struct iavf_qtc_map *qtc_map;
+ struct iavf_qtc_map *qtc_map = NULL;
+ struct iavf_qtc_map *old_qtc_map = vf->qtc_map; /* to free memory if
new map assigned */
uint16_t size, size_q;
int index = 0, node_committed = 0;
int i, ret_val = IAVF_SUCCESS;
@@ -888,8 +892,7 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
goto fail_clear;
/* store the queue TC mapping info */
- qtc_map = rte_zmalloc("qtc_map",
- sizeof(struct iavf_qtc_map) * q_tc_mapping->num_tc, 0);
+ qtc_map = calloc(q_tc_mapping->num_tc, sizeof(struct iavf_qtc_map));
if (!qtc_map) {
ret_val = IAVF_ERR_NO_MEMORY;
goto fail_clear;
@@ -909,6 +912,7 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
goto fail_clear;
vf->qtc_map = qtc_map;
+ free(old_qtc_map);
if (adapter->stopped == 1)
vf->tm_conf.committed = true;
free(q_bw);
@@ -924,5 +928,6 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
err:
free(q_bw);
free(q_tc_mapping);
+ free(qtc_map);
return ret_val;
}
--
2.53.0