net/ice: fix memory handling issues
cover net/ice: fix memory handling issues
This patch series addresses two memory handling issues in the ice PMD.
- The first one makes memory allocation and release symmetric. Several buffers obtained through ice_malloc(), ice_calloc() or ice_memdup() were released with rte_free() instead of ice_free(). Both APIs currently map to the same underlying allocator. However, mixing them is inconsistent and would break if the OS abstraction layer ever changes.
- The second one fixes an unchecked allocation in ice_tx_queue_start() which dereferences the Tx time queue context buffer returned by ice_malloc() without NULL check.
On allocation failure, the E830 send-on-timestamp path therefore crashes instead of reporting "No Memory" error, and also the already allocated txq_elem buffer gets leaked.
Anurag Mandal (2):
net/ice: free memory with matching allocator net/ice: fix unchecked Tx time context allocation
drivers/net/intel/ice/ice_acl_filter.c | 10 +++++----- drivers/net/intel/ice/ice_dcf.c | 2 +- drivers/net/intel/ice/ice_dcf_parent.c | 2 +- drivers/net/intel/ice/ice_ethdev.c | 14 +++++++------- drivers/net/intel/ice/ice_fdir_filter.c | 12 ++++++------ drivers/net/intel/ice/ice_rxtx.c | 22 +++++++++++++--------- 6 files changed, 33 insertions(+), 29 deletions(-)
Signature · 1 line
2.34.1
PATCH 1/2 net/ice: free memory with matching allocator
Several buffers allocated with ice_malloc(), ice_calloc() or ice_memdup() were released using rte_free() instead of ice_free(). Both APIs currently map to the same underlying allocator. However, mixing them is inconsistent and could break if the inconsistent and could break if the OS abstraction layer changes.
Use ice_free() for all memory obtained through the ice_malloc() family.
--- drivers/net/intel/ice/ice_acl_filter.c | 10 +++++----- drivers/net/intel/ice/ice_dcf.c | 2 +- drivers/net/intel/ice/ice_dcf_parent.c | 2 +- drivers/net/intel/ice/ice_ethdev.c | 14 +++++++------- drivers/net/intel/ice/ice_fdir_filter.c | 12 ++++++------ drivers/net/intel/ice/ice_rxtx.c | 18 +++++++++--------- 6 files changed, 29 insertions(+), 29 deletions(-)
drivers/net/intel/ice/ice_acl_filter.c +5 -5
@@ -86,11 +86,11 @@ ice_acl_prof_alloc(struct ice_hw *hw) fail_mem:for (fltr_ptype =ICE_FLTR_PTYPE_NONF_NONE +1 ; fltr_ptype < ptype; fltr_ptype++) { -rte_free (hw->acl_prof[fltr_ptype]); +ice_free (hw, hw->acl_prof[fltr_ptype]); hw->acl_prof[fltr_ptype] =NULL ; } -rte_free (hw->acl_prof); +ice_free (hw, hw->acl_prof); hw->acl_prof =NULL ;return -ENOMEM ;
@@ -148,7 +148,7 @@ static void ice_deinit_acl(struct ice_pf *pf)ice_acl_destroy_tbl (hw); -rte_free (hw->acl_tbl); +ice_free (hw, hw->acl_tbl); hw->acl_tbl =NULL ;if (pf->acl.slots) {
@@ -1102,11 +1102,11 @@ ice_acl_prof_free(struct ice_hw *hw)for (ptype =ICE_FLTR_PTYPE_NONF_NONE +1 ; ptype <ICE_FLTR_PTYPE_MAX ; ptype++) { -rte_free (hw->acl_prof[ptype]); +ice_free (hw, hw->acl_prof[ptype]); hw->acl_prof[ptype] =NULL ; } -rte_free (hw->acl_prof); +ice_free (hw, hw->acl_prof); hw->acl_prof =NULL ; }
drivers/net/intel/ice/ice_dcf.c +1 -1
@@ -913,7 +913,7 @@ ice_dcf_uninit_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)rte_free (hw->qos_bw_cfg); hw->qos_bw_cfg =NULL ; -rte_free (hw->ets_config); +ice_free (hw, hw->ets_config); hw->ets_config =NULL ; }
drivers/net/intel/ice/ice_dcf_parent.c +1 -1
@@ -295,7 +295,7 @@ ice_dcf_query_port_ets(struct ice_hw *parent_hw, struct ice_dcf_hw *real_hw) NULL);if (ret) {PMD_DRV_LOG (ERR ,"DCF Query Port ETS failed" ); -rte_free (real_hw->ets_config); +ice_free (real_hw, real_hw->ets_config); real_hw->ets_config =NULL ;return ret; }
drivers/net/intel/ice/ice_ethdev.c +7 -7
@@ -1178,7 +1178,7 @@ ice_add_mac_filter(struct ice_vsi *vsi, struct rte_ether_addr *mac_addr) ret =0 ; DONE: -rte_free (m_list_itr); +ice_free (hw, m_list_itr);return ret; }
@@ -1229,7 +1229,7 @@ ice_remove_mac_filter(struct ice_vsi *vsi, struct rte_ether_addr *mac_addr) ret =0 ; DONE: -rte_free (m_list_itr); +ice_free (hw, m_list_itr);return ret; }
@@ -1314,7 +1314,7 @@ ice_add_vlan_filter(struct ice_vsi *vsi, struct ice_vlan *vlan) ret =0 ; DONE: -rte_free (v_list_itr); +ice_free (hw, v_list_itr);return ret; }
@@ -1372,7 +1372,7 @@ ice_remove_vlan_filter(struct ice_vsi *vsi, struct ice_vlan *vlan) ret =0 ; DONE: -rte_free (v_list_itr); +ice_free (hw, v_list_itr);return ret; }
@@ -2572,7 +2572,7 @@ ice_get_hw_res(struct ice_hw *hw, uint16_t res_type, (*num_prof), ICE_NONDMA_TO_NONDMA); exit: -rte_free (resp_buf); +ice_free (hw, resp_buf);return ret; } static int
@@ -2772,7 +2772,7 @@ ice_dev_init(struct rte_eth_dev *dev) ret =ice_init_hw_tbls (hw);if (ret) {PMD_INIT_LOG (ERR ,"ice_init_hw_tbls failed: %d" , ret); -rte_free (hw->pkg_copy); +ice_free (hw, hw->pkg_copy); } }
@@ -3098,7 +3098,7 @@ ice_dev_close(struct rte_eth_dev *dev)ice_release_vsi (pf->main_vsi);ice_sched_cleanup_all (hw);ice_free_hw_tbls (hw); -rte_free (hw->port_info); +ice_free (hw, hw->port_info); hw->port_info =NULL ;free ((void *)(uintptr_t )ad->devargs.ddp_filename); ad->devargs.ddp_filename =NULL ;
drivers/net/intel/ice/ice_fdir_filter.c +6 -6
@@ -231,11 +231,11 @@ ice_fdir_prof_alloc(struct ice_hw *hw)for (fltr_ptype =ICE_FLTR_PTYPE_NONF_NONE +1 ; fltr_ptype < ptype; fltr_ptype++) { -rte_free (hw->fdir_prof[fltr_ptype]); +ice_free (hw, hw->fdir_prof[fltr_ptype]); hw->fdir_prof[fltr_ptype] =NULL ; } -rte_free (hw->fdir_prof); +ice_free (hw, hw->fdir_prof); hw->fdir_prof =NULL ;return -ENOMEM ;
@@ -608,11 +608,11 @@ ice_fdir_prof_free(struct ice_hw *hw)for (ptype =ICE_FLTR_PTYPE_NONF_NONE +1 ; ptype <ICE_FLTR_PTYPE_MAX ; ptype++) { -rte_free (hw->fdir_prof[ptype]); +ice_free (hw, hw->fdir_prof[ptype]); hw->fdir_prof[ptype] =NULL ; } -rte_free (hw->fdir_prof); +ice_free (hw, hw->fdir_prof); hw->fdir_prof =NULL ; }
@@ -644,7 +644,7 @@ ice_fdir_prof_rm(struct ice_pf *pf, enum ice_fltr_ptype ptype, bool is_tunnel) } }ice_flow_rem_prof (hw,ICE_BLK_FD , prof_id); -rte_free (hw_prof->fdir_seg[is_tunnel]); +ice_free (hw, hw_prof->fdir_seg[is_tunnel]); hw_prof->fdir_seg[is_tunnel] =NULL ;for (i =0 ; i < hw_prof->cnt; i++)
@@ -1350,7 +1350,7 @@ ice_fdir_input_set_conf(struct ice_pf *pf, enum ice_fltr_ptype flow,if (!ret) {return ret; }else if (ret <0 ) { -rte_free (seg_tun); +ice_free (pf->adapter->hw, seg_tun);return (ret == -EEXIST ) ?0 : ret; }else {return ret;
drivers/net/intel/ice/ice_rxtx.c +9 -9
@@ -854,13 +854,13 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) }if (cgd_idx >=ICE_MAX_TRAFFIC_CLASS ) {PMD_DRV_LOG (ERR ,"Bad queue mapping configuration" ); -rte_free (txq_elem); +ice_free (hw, txq_elem);return -EINVAL ; } }else if (pf->dcb_num_tcs >1 ) {/* TM only manages the TC0 scheduler subtree. */ PMD_DRV_LOG (ERR ,"TM hierarchy is not supported together with multi-TC DCB" ); -rte_free (txq_elem); +ice_free (hw, txq_elem);return -EINVAL ; }
@@ -874,7 +874,7 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) txq_elem, buf_len, NULL);if (err) {PMD_DRV_LOG (ERR ,"Failed to add lan txq" ); -rte_free (txq_elem); +ice_free (hw, txq_elem);return -EIO ; }/* store the schedule node id */
@@ -884,7 +884,7 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)if (pf->tm_conf.committed)if (ice_tm_setup_txq_node (pf, hw, tx_queue_id, txq->q_teid) !=0 ) {PMD_DRV_LOG (ERR ,"Failed to set up txq traffic management node" ); -rte_free (txq_elem); +ice_free (hw, txq_elem);return -EIO ; }
@@ -909,10 +909,10 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)ICE_PCI_REG_WRITE (txq->qtx_tail,0 ); err =ice_aq_set_txtimeq (hw, txq->reg_idx,1 , ts_elem, ts_buf_len,NULL ); -rte_free (ts_elem); +ice_free (hw, ts_elem);if (err) {PMD_DRV_LOG (ERR ,"Failed to set Tx Time queue context, error: %d" , err); -rte_free (txq_elem); +ice_free (hw, txq_elem);return err; } }else {
@@ -924,7 +924,7 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) dev->data->tx_queue_state[tx_queue_id] =RTE_ETH_QUEUE_STATE_STARTED ; -rte_free (txq_elem); +ice_free (hw, txq_elem);return 0 ; }
@@ -1096,13 +1096,13 @@ ice_fdir_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) txq_elem, buf_len, NULL);if (err) {PMD_DRV_LOG (ERR ,"Failed to add FDIR txq" ); -rte_free (txq_elem); +ice_free (hw, txq_elem);return -EIO ; }/* store the schedule node id */ txq->q_teid = txq_elem->txqs[0 ].q_teid; -rte_free (txq_elem); +ice_free (hw, txq_elem);return 0 ; }
Signature · 1 line
2.34.1
Re: [PATCH 1/2] net/ice: free memory with matching allocator
Quoted 10 lines · Anurag Mandal
Several buffers allocated with
ice_malloc(),ice_calloc()orice_memdup()were released usingrte_free()instead ofice_free(). Both APIs currently map to the same underlying allocator. However, mixing them is inconsistent and could break if the inconsistent and could break if the OS abstraction layer changes.Use
ice_free()for all memory obtained through theice_malloc()family.Signed-off-by Anurag Mandal <[email protected]>
PATCH 2/2 net/ice: fix unchecked Tx time context allocation
In reply to Anurag Mandalice_tx_queue_start() dereferences the Tx time queue context buffer returned by ice_malloc() without NULL check.
On allocation failure, the E830 send-on-timestamp path therefore crashes instead of reporting "No Memory" error, and also the already allocated txq_elem buffer gets leaked.
Added the necessary allocation failure check and freed txq_elem buffer in case of failure to avoid the memory leak.
--- drivers/net/intel/ice/ice_rxtx.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/intel/ice/ice_rxtx.c +4 -0
@@ -898,6 +898,10 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)u8 ts_buf_len =ice_struct_size (ts_elem, txtimeqs,1 ); ts_elem =ice_malloc (hw, ts_buf_len); +if (!ts_elem) { +ice_free (hw, txq_elem); +return -ENOMEM ; + }ice_setup_txtime_ctx (txq, &txtime_ctx, true); ice_set_ctx(hw, (u8 *)&txtime_ctx, ts_elem->txtimeqs[0].txtime_ctx,
Signature · 1 line
2.34.1
Quoted 20 lines · Anurag Mandal
This patch series addresses two memory handling issues in the ice PMD.
- The first one makes memory allocation and release symmetric. Several buffers obtained through
ice_malloc(),ice_calloc()orice_memdup()were released withrte_free()instead ofice_free(). Both APIs currently map to the same underlying allocator. However, mixing them is inconsistent and would break if the OS abstraction layer ever changes.- The second one fixes an unchecked allocation in
ice_tx_queue_start()which dereferences the Tx time queue context buffer returned byice_malloc()without NULL check.
On allocation failure, the E830 send-on-timestamp path therefore crashes instead of reporting "No Memory" error, and also the already allocatedtxq_elembuffer gets leaked.Anurag Mandal (2):
net/ice: free memory with matching allocator net/ice: fix unchecked Tx time context allocation
Quoted 8 lines
drivers/net/intel/ice/ice_acl_filter.c | 10 +++++----- drivers/net/intel/ice/ice_dcf.c | 2 +- drivers/net/intel/ice/ice_dcf_parent.c | 2 +- drivers/net/intel/ice/ice_ethdev.c | 14 +++++++------- drivers/net/intel/ice/ice_fdir_filter.c | 12 ++++++------ drivers/net/intel/ice/ice_rxtx.c | 22 +++++++++++++--------- 6 files changed, 33 insertions(+), 29 deletions(-)
Patches applied to dpdk-next-net-intel.
Thanks,
/Bruce