net/i40e: optimize flow director memory management
[dpdk.git] / drivers / net / i40e / i40e_ethdev.c
index dca84a1..6901643 100644 (file)
@@ -1051,6 +1051,10 @@ i40e_init_fdir_filter_list(struct rte_eth_dev *dev)
        char fdir_hash_name[RTE_HASH_NAMESIZE];
        uint32_t alloc = hw->func_caps.fd_filters_guaranteed;
        uint32_t best = hw->func_caps.fd_filters_best_effort;
+       struct rte_bitmap *bmp = NULL;
+       uint32_t bmp_size;
+       void *mem = NULL;
+       uint32_t i = 0;
        int ret;
 
        struct rte_hash_parameters fdir_hash_params = {
@@ -1083,6 +1087,18 @@ i40e_init_fdir_filter_list(struct rte_eth_dev *dev)
                goto err_fdir_hash_map_alloc;
        }
 
+       fdir_info->fdir_filter_array = rte_zmalloc("fdir_filter",
+                       sizeof(struct i40e_fdir_filter) *
+                       I40E_MAX_FDIR_FILTER_NUM,
+                       0);
+
+       if (!fdir_info->fdir_filter_array) {
+               PMD_INIT_LOG(ERR,
+                            "Failed to allocate memory for fdir filter array!");
+               ret = -ENOMEM;
+               goto err_fdir_filter_array_alloc;
+       }
+
        fdir_info->fdir_space_size = alloc + best;
        fdir_info->fdir_actual_cnt = 0;
        fdir_info->fdir_guarantee_total_space = alloc;
@@ -1091,8 +1107,53 @@ i40e_init_fdir_filter_list(struct rte_eth_dev *dev)
 
        PMD_DRV_LOG(INFO, "FDIR guarantee space: %u, best_effort space %u.", alloc, best);
 
+       fdir_info->fdir_flow_pool.pool =
+                       rte_zmalloc("i40e_fdir_entry",
+                               sizeof(struct i40e_fdir_entry) *
+                               fdir_info->fdir_space_size,
+                               0);
+
+       if (!fdir_info->fdir_flow_pool.pool) {
+               PMD_INIT_LOG(ERR,
+                            "Failed to allocate memory for bitmap flow!");
+               ret = -ENOMEM;
+               goto err_fdir_bitmap_flow_alloc;
+       }
+
+       for (i = 0; i < fdir_info->fdir_space_size; i++)
+               fdir_info->fdir_flow_pool.pool[i].idx = i;
+
+       bmp_size =
+               rte_bitmap_get_memory_footprint(fdir_info->fdir_space_size);
+       mem = rte_zmalloc("fdir_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
+       if (mem == NULL) {
+               PMD_INIT_LOG(ERR,
+                            "Failed to allocate memory for fdir bitmap!");
+               ret = -ENOMEM;
+               goto err_fdir_mem_alloc;
+       }
+       bmp = rte_bitmap_init(fdir_info->fdir_space_size, mem, bmp_size);
+       if (bmp == NULL) {
+               PMD_INIT_LOG(ERR,
+                            "Failed to initialization fdir bitmap!");
+               ret = -ENOMEM;
+               goto err_fdir_bmp_alloc;
+       }
+       for (i = 0; i < fdir_info->fdir_space_size; i++)
+               rte_bitmap_set(bmp, i);
+
+       fdir_info->fdir_flow_pool.bitmap = bmp;
+
        return 0;
 
+err_fdir_bmp_alloc:
+       rte_free(mem);
+err_fdir_mem_alloc:
+       rte_free(fdir_info->fdir_flow_pool.pool);
+err_fdir_bitmap_flow_alloc:
+       rte_free(fdir_info->fdir_filter_array);
+err_fdir_filter_array_alloc:
+       rte_free(fdir_info->hash_map);
 err_fdir_hash_map_alloc:
        rte_hash_free(fdir_info->hash_table);
 
@@ -1790,16 +1851,30 @@ i40e_rm_fdir_filter_list(struct i40e_pf *pf)
        struct i40e_fdir_info *fdir_info;
 
        fdir_info = &pf->fdir;
-       /* Remove all flow director rules and hash */
+
+       /* Remove all flow director rules */
+       while ((p_fdir = TAILQ_FIRST(&fdir_info->fdir_list)))
+               TAILQ_REMOVE(&fdir_info->fdir_list, p_fdir, rules);
+}
+
+static void
+i40e_fdir_memory_cleanup(struct i40e_pf *pf)
+{
+       struct i40e_fdir_info *fdir_info;
+
+       fdir_info = &pf->fdir;
+
+       /* flow director memory cleanup */
        if (fdir_info->hash_map)
                rte_free(fdir_info->hash_map);
        if (fdir_info->hash_table)
                rte_hash_free(fdir_info->hash_table);
-
-       while ((p_fdir = TAILQ_FIRST(&fdir_info->fdir_list))) {
-               TAILQ_REMOVE(&fdir_info->fdir_list, p_fdir, rules);
-               rte_free(p_fdir);
-       }
+       if (fdir_info->fdir_flow_pool.bitmap)
+               rte_bitmap_free(fdir_info->fdir_flow_pool.bitmap);
+       if (fdir_info->fdir_flow_pool.pool)
+               rte_free(fdir_info->fdir_flow_pool.pool);
+       if (fdir_info->fdir_filter_array)
+               rte_free(fdir_info->fdir_filter_array);
 }
 
 void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
@@ -2659,9 +2734,14 @@ i40e_dev_close(struct rte_eth_dev *dev)
        /* Remove all flows */
        while ((p_flow = TAILQ_FIRST(&pf->flow_list))) {
                TAILQ_REMOVE(&pf->flow_list, p_flow, node);
-               rte_free(p_flow);
+               /* Do not free FDIR flows since they are static allocated */
+               if (p_flow->filter_type != RTE_ETH_FILTER_FDIR)
+                       rte_free(p_flow);
        }
 
+       /* release the fdir static allocated memory */
+       i40e_fdir_memory_cleanup(pf);
+
        /* Remove all Traffic Manager configuration */
        i40e_tm_conf_uninit(dev);