From patchwork Fri Oct 18 11:16:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cao, Yahui" X-Patchwork-Id: 61454 X-Patchwork-Delegate: xiaolong.ye@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 035A01E88C; Fri, 18 Oct 2019 05:34:04 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 9FE521E874 for ; Fri, 18 Oct 2019 05:33:52 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Oct 2019 20:33:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,310,1566889200"; d="scan'208";a="202577942" Received: from dpdk-yahui-skylake.sh.intel.com ([10.67.119.16]) by FMSMGA003.fm.intel.com with ESMTP; 17 Oct 2019 20:33:50 -0700 From: Yahui Cao To: Qiming Yang , Wenzhuo Lu Cc: dev@dpdk.org, Qi Zhang , Xiaolong Ye , Beilei Xing , Yahui Cao Date: Fri, 18 Oct 2019 19:16:00 +0800 Message-Id: <20191018111602.26742-8-yahui.cao@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191018111602.26742-1-yahui.cao@intel.com> References: <20191017160454.14518-1-yahui.cao@intel.com> <20191018111602.26742-1-yahui.cao@intel.com> Subject: [dpdk-dev] [PATCH v7 7/9] 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 Acked-by: Qi Zhang --- drivers/net/ice/Makefile | 2 +- drivers/net/ice/ice_ethdev.h | 17 +++ drivers/net/ice/ice_fdir_filter.c | 185 ++++++++++++++++++++++++++++-- 3 files changed, 196 insertions(+), 8 deletions(-) diff --git a/drivers/net/ice/Makefile b/drivers/net/ice/Makefile index f7e185288..884fc4075 100644 --- a/drivers/net/ice/Makefile +++ b/drivers/net/ice/Makefile @@ -13,7 +13,7 @@ CFLAGS += $(WERROR_FLAGS) CFLAGS += -DALLOW_EXPERIMENTAL_API LDLIBS += -lrte_eal -lrte_mbuf -lrte_ethdev -lrte_kvargs -LDLIBS += -lrte_bus_pci -lrte_mempool +LDLIBS += -lrte_bus_pci -lrte_mempool -lrte_hash EXPORT_MAP := rte_pmd_ice_version.map diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index 5129b3b67..ab8b452e4 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 b327ead80..1b6101ec6 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."); @@ -470,6 +532,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); @@ -752,6 +816,74 @@ ice_fdir_add_del_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, @@ -760,11 +892,22 @@ ice_fdir_create_filter(struct ice_adapter *ad, { struct ice_pf *pf = &ad->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"); @@ -804,9 +947,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_cnt_update(pf, filter->input.flow_type, false, true); + return 0; free_counter: @@ -816,7 +968,7 @@ ice_fdir_create_filter(struct ice_adapter *ad, } free_entry: - rte_free(rule); + rte_free(entry); return -rte_errno; } @@ -826,7 +978,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; @@ -836,6 +990,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_fdir_add_del_filter(pf, filter, false); if (ret) { rte_flow_error_set(error, -ret, @@ -844,6 +1007,14 @@ 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; + } + ice_fdir_cnt_update(pf, filter->input.flow_type, false, false); flow->rule = NULL;