From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D0A7DA0613 for ; Tue, 24 Sep 2019 16:09:24 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 018FC1BE98; Tue, 24 Sep 2019 16:08:38 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 1DBD41BE97 for ; Tue, 24 Sep 2019 16:08:35 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 24 Sep 2019 07:08:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,544,1559545200"; d="scan'208";a="182926887" Received: from dpdk-yahui-skylake.sh.intel.com ([10.67.119.16]) by orsmga008.jf.intel.com with ESMTP; 24 Sep 2019 07:08:34 -0700 From: Yahui Cao To: Qiming Yang , Wenzhuo Lu Cc: dev@dpdk.org, Qi Zhang , Xiaolong Ye , Beilei Xing , Yahui Cao Date: Wed, 25 Sep 2019 05:52:42 +0800 Message-Id: <20190924215243.81474-8-yahui.cao@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190924215243.81474-1-yahui.cao@intel.com> References: <20190924215243.81474-1-yahui.cao@intel.com> Subject: [dpdk-dev] [PATCH v3 7/8] net/ice: reject duplicate flow for FDIR X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Enable duplication lookup for existing flow director rule entry. Signed-off-by: Yahui Cao --- drivers/net/ice/ice_ethdev.h | 17 +++ drivers/net/ice/ice_fdir_filter.c | 186 ++++++++++++++++++++++++++++-- 2 files changed, 196 insertions(+), 7 deletions(-) diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index 89eefe4b1..f54dac513 100644 --- a/drivers/net/ice/ice_ethdev.h +++ b/drivers/net/ice/ice_ethdev.h @@ -256,6 +256,20 @@ struct ice_fdir_filter_conf { uint64_t input_set; }; +#define ICE_MAX_FDIR_FILTER_NUM (1024 * 16) + +struct ice_fdir_fltr_pattern { + enum ice_fltr_ptype flow_type; + + union { + struct ice_fdir_v4 v4; + struct ice_fdir_v6 v6; + } ip, mask; + + struct ice_fdir_extra ext_data; + struct ice_fdir_extra ext_mask; +}; + #define ICE_FDIR_COUNTER_DEFAULT_POOL_SIZE 1 #define ICE_FDIR_COUNTER_MAX_POOL_SIZE 32 #define ICE_FDIR_COUNTERS_PER_BLOCK 256 @@ -301,6 +315,9 @@ struct ice_fdir_info { uint64_t dma_addr; /* physic address of packet memory*/ struct ice_fdir_filter_conf conf; + struct ice_fdir_filter_conf **hash_map; + struct rte_hash *hash_table; + struct ice_fdir_counter_pool_container counter; }; diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c index 4c822789e..9f2d9b2dd 100644 --- a/drivers/net/ice/ice_fdir_filter.c +++ b/drivers/net/ice/ice_fdir_filter.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include "base/ice_fdir.h" #include "base/ice_flow.h" #include "base/ice_type.h" @@ -272,6 +274,60 @@ ice_fdir_counter_free(__rte_unused struct ice_pf *pf, } } +static int +ice_fdir_init_filter_list(struct ice_pf *pf) +{ + struct rte_eth_dev *dev = pf->adapter->eth_dev; + struct ice_fdir_info *fdir_info = &pf->fdir; + char fdir_hash_name[RTE_HASH_NAMESIZE]; + int ret; + + struct rte_hash_parameters fdir_hash_params = { + .name = fdir_hash_name, + .entries = ICE_MAX_FDIR_FILTER_NUM, + .key_len = sizeof(struct ice_fdir_fltr_pattern), + .hash_func = rte_hash_crc, + .hash_func_init_val = 0, + .socket_id = rte_socket_id(), + }; + + /* Initialize hash */ + snprintf(fdir_hash_name, RTE_HASH_NAMESIZE, + "fdir_%s", dev->device->name); + fdir_info->hash_table = rte_hash_create(&fdir_hash_params); + if (!fdir_info->hash_table) { + PMD_INIT_LOG(ERR, "Failed to create fdir hash table!"); + return -EINVAL; + } + fdir_info->hash_map = rte_zmalloc("ice_fdir_hash_map", + sizeof(*fdir_info->hash_map) * + ICE_MAX_FDIR_FILTER_NUM, + 0); + if (!fdir_info->hash_map) { + PMD_INIT_LOG(ERR, + "Failed to allocate memory for fdir hash map!"); + ret = -ENOMEM; + goto err_fdir_hash_map_alloc; + } + return 0; + +err_fdir_hash_map_alloc: + rte_hash_free(fdir_info->hash_table); + + return ret; +} + +static void +ice_fdir_release_filter_list(struct ice_pf *pf) +{ + struct ice_fdir_info *fdir_info = &pf->fdir; + + if (fdir_info->hash_map) + rte_free(fdir_info->hash_map); + if (fdir_info->hash_table) + rte_hash_free(fdir_info->hash_table); +} + /* * ice_fdir_setup - reserve and initialize the Flow Director resources * @pf: board private structure @@ -309,6 +365,12 @@ ice_fdir_setup(struct ice_pf *pf) } pf->fdir.fdir_vsi = vsi; + err = ice_fdir_init_filter_list(pf); + if (err) { + PMD_DRV_LOG(ERR, "Failed to init FDIR filter list."); + return -EINVAL; + } + err = ice_fdir_counter_init(pf); if (err) { PMD_DRV_LOG(ERR, "Failed to init FDIR counter."); @@ -420,6 +482,8 @@ ice_fdir_teardown(struct ice_pf *pf) if (err) PMD_DRV_LOG(ERR, "Failed to release FDIR counter resource."); + ice_fdir_release_filter_list(pf); + ice_tx_queue_release(pf->fdir.txq); pf->fdir.txq = NULL; ice_rx_queue_release(pf->fdir.rxq); @@ -723,6 +787,74 @@ ice_add_del_fdir_filter(struct ice_pf *pf, return ice_fdir_programming(pf, &desc); } +static void +ice_fdir_extract_fltr_key(struct ice_fdir_fltr_pattern *key, + struct ice_fdir_filter_conf *filter) +{ + struct ice_fdir_fltr *input = &filter->input; + memset(key, 0, sizeof(*key)); + + key->flow_type = input->flow_type; + rte_memcpy(&key->ip, &input->ip, sizeof(key->ip)); + rte_memcpy(&key->mask, &input->mask, sizeof(key->mask)); + rte_memcpy(&key->ext_data, &input->ext_data, sizeof(key->ext_data)); + rte_memcpy(&key->ext_mask, &input->ext_mask, sizeof(key->ext_mask)); +} + +/* Check if there exists the flow director filter */ +static struct ice_fdir_filter_conf * +ice_fdir_entry_lookup(struct ice_fdir_info *fdir_info, + const struct ice_fdir_fltr_pattern *key) +{ + int ret; + + ret = rte_hash_lookup(fdir_info->hash_table, key); + if (ret < 0) + return NULL; + + return fdir_info->hash_map[ret]; +} + +/* Add a flow director entry into the SW list */ +static int +ice_fdir_entry_insert(struct ice_pf *pf, + struct ice_fdir_filter_conf *entry, + struct ice_fdir_fltr_pattern *key) +{ + struct ice_fdir_info *fdir_info = &pf->fdir; + int ret; + + ret = rte_hash_add_key(fdir_info->hash_table, key); + if (ret < 0) { + PMD_DRV_LOG(ERR, + "Failed to insert fdir entry to hash table %d!", + ret); + return ret; + } + fdir_info->hash_map[ret] = entry; + + return 0; +} + +/* Delete a flow director entry from the SW list */ +static int +ice_fdir_entry_del(struct ice_pf *pf, struct ice_fdir_fltr_pattern *key) +{ + struct ice_fdir_info *fdir_info = &pf->fdir; + int ret; + + ret = rte_hash_del_key(fdir_info->hash_table, key); + if (ret < 0) { + PMD_DRV_LOG(ERR, + "Failed to delete fdir filter to hash table %d!", + ret); + return ret; + } + fdir_info->hash_map[ret] = NULL; + + return 0; +} + static int ice_fdir_create_filter(struct ice_adapter *ad, struct rte_flow *flow, @@ -732,11 +864,22 @@ ice_fdir_create_filter(struct ice_adapter *ad, struct ice_pf *pf = &ad->pf; struct ice_hw *hw = ICE_PF_TO_HW(pf); struct ice_fdir_filter_conf *filter = meta; - struct ice_fdir_filter_conf *rule; + struct ice_fdir_info *fdir_info = &pf->fdir; + struct ice_fdir_filter_conf *entry, *node; + struct ice_fdir_fltr_pattern key; int ret; - rule = rte_zmalloc("fdir_entry", sizeof(*rule), 0); - if (!rule) { + ice_fdir_extract_fltr_key(&key, filter); + node = ice_fdir_entry_lookup(fdir_info, &key); + if (node) { + rte_flow_error_set(error, EEXIST, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Rule already exists!"); + return -rte_errno; + } + + entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0); + if (!entry) { rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Failed to allocate memory"); @@ -776,9 +919,18 @@ ice_fdir_create_filter(struct ice_adapter *ad, goto free_counter; } - rte_memcpy(rule, filter, sizeof(*rule)); - flow->rule = rule; + rte_memcpy(entry, filter, sizeof(*entry)); + ret = ice_fdir_entry_insert(pf, entry, &key); + if (ret) { + rte_flow_error_set(error, -ret, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Insert entry to table failed."); + goto free_entry; + } + + flow->rule = entry; ice_fdir_update_cntrs(hw, filter->input.flow_type, true); + return 0; free_counter: @@ -788,7 +940,7 @@ ice_fdir_create_filter(struct ice_adapter *ad, } free_entry: - rte_free(rule); + rte_free(entry); return -rte_errno; } @@ -798,7 +950,9 @@ ice_fdir_destroy_filter(struct ice_adapter *ad, struct rte_flow_error *error) { struct ice_pf *pf = &ad->pf; - struct ice_fdir_filter_conf *filter; + struct ice_fdir_info *fdir_info = &pf->fdir; + struct ice_fdir_filter_conf *filter, *entry; + struct ice_fdir_fltr_pattern key; int ret; filter = (struct ice_fdir_filter_conf *)flow->rule; @@ -808,6 +962,15 @@ ice_fdir_destroy_filter(struct ice_adapter *ad, filter->counter = NULL; } + ice_fdir_extract_fltr_key(&key, filter); + entry = ice_fdir_entry_lookup(fdir_info, &key); + if (!entry) { + rte_flow_error_set(error, ENOENT, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Can't find entry."); + return -rte_errno; + } + ret = ice_add_del_fdir_filter(pf, filter, false); if (ret) { rte_flow_error_set(error, -ret, @@ -816,7 +979,16 @@ ice_fdir_destroy_filter(struct ice_adapter *ad, return -rte_errno; } + ret = ice_fdir_entry_del(pf, &key); + if (ret) { + rte_flow_error_set(error, -ret, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Remove entry from table failed."); + return -rte_errno; + } + rte_free(filter); + flow->rule = NULL; return 0; } -- 2.17.1