From patchwork Fri Sep 6 12:00:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cao, Yahui" X-Patchwork-Id: 58717 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 E39621F119; Fri, 6 Sep 2019 06:16:32 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 2B1D21F0FA for ; Fri, 6 Sep 2019 06:16:24 +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 orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Sep 2019 21:16:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,472,1559545200"; d="scan'208";a="190709720" Received: from dpdk-yahui-skylake.sh.intel.com ([10.67.119.16]) by FMSMGA003.fm.intel.com with ESMTP; 05 Sep 2019 21:16:22 -0700 From: Yahui Cao To: Qiming Yang , Wenzhuo Lu Cc: dev@dpdk.org, Qi Zhang , Xiaolong Ye , Beilei Xing , Yahui Cao Date: Fri, 6 Sep 2019 20:00:52 +0800 Message-Id: <20190906120058.108073-7-yahui.cao@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190906120058.108073-1-yahui.cao@intel.com> References: <20190906120058.108073-1-yahui.cao@intel.com> Subject: [dpdk-dev] [dpdk-dev 06/12] net/ice: add hash table 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 quick 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 bb821bc41..30ab518cd 100644 --- a/drivers/net/ice/ice_ethdev.h +++ b/drivers/net/ice/ice_ethdev.h @@ -254,6 +254,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; +}; + /** * A structure used to define fields of a FDIR related info. */ @@ -264,6 +278,9 @@ struct ice_fdir_info { void *prg_pkt; /* memory for fdir program packet */ 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_pf { diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c index 294678075..df4d0329c 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" @@ -69,6 +71,60 @@ ice_memzone_reserve(const char *name, uint32_t len, int socket_id) #define ICE_FDIR_MZ_NAME "FDIR_MEMZONE" +static int +ice_init_fdir_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_release_fdir_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 @@ -106,6 +162,12 @@ ice_fdir_setup(struct ice_pf *pf) } pf->fdir.fdir_vsi = vsi; + err = ice_init_fdir_filter_list(pf); + if (err) { + PMD_DRV_LOG(ERR, "Failed to init FDIR filter list."); + return -EINVAL; + } + /*Fdir tx queue setup*/ err = ice_fdir_setup_tx_resources(pf); if (err) { @@ -177,6 +239,8 @@ ice_fdir_teardown(struct ice_pf *pf) if (!vsi) return; + ice_release_fdir_filter_list(pf); + err = ice_fdir_tx_queue_stop(eth_dev, pf->fdir.txq->queue_id); if (err) PMD_DRV_LOG(ERR, "Failed to stop TX queue."); @@ -490,6 +554,74 @@ ice_add_del_fdir_filter(struct ice_pf *pf, return 0; } +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_create_fdir_filter(struct ice_adapter *ad, struct rte_flow *flow, @@ -499,11 +631,22 @@ ice_create_fdir_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 = 0; - 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"); @@ -527,13 +670,22 @@ ice_create_fdir_filter(struct ice_adapter *ad, goto free_entry; } - 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_entry: - rte_free(rule); + rte_free(entry); return -rte_errno; } @@ -543,11 +695,22 @@ ice_destroy_fdir_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; + 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, @@ -556,7 +719,16 @@ ice_destroy_fdir_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; }