From patchwork Wed Jul 15 19:53:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chenmin Sun X-Patchwork-Id: 74085 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 30B57A0545; Wed, 15 Jul 2020 12:56:43 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C64761BEDD; Wed, 15 Jul 2020 12:56:38 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 4C4751BED7 for ; Wed, 15 Jul 2020 12:56:36 +0200 (CEST) IronPort-SDR: fOM+/6pSi9CcMaTl7LnWdapalmGjc1HjdREE2tFyqkzRUuAIVvdKIB9hZEgHKOvRLCthuOOtnP dEPNmn0bK0RA== X-IronPort-AV: E=McAfee;i="6000,8403,9682"; a="137249740" X-IronPort-AV: E=Sophos;i="5.75,355,1589266800"; d="scan'208";a="137249740" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2020 03:56:36 -0700 IronPort-SDR: gPnLvR56HmWedPZtlFRXBnhysrcMjBJUX4AgAMtfAMxWyFfX6zy4VdBbfdhuQDmTdWK6zRcqcY rlwVWP3YSVWA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,355,1589266800"; d="scan'208";a="460026042" Received: from npg-dpdk-vpp-scm-1.sh.intel.com ([10.67.118.226]) by orsmga005.jf.intel.com with ESMTP; 15 Jul 2020 03:56:34 -0700 From: chenmin.sun@intel.com To: qi.z.zhang@intel.com, beilei.xing@intel.com, jingjing.wu@intel.com, haiyue.wang@intel.com Cc: dev@dpdk.org, chenmin.sun@intel.com Date: Thu, 16 Jul 2020 03:53:26 +0800 Message-Id: <20200715195329.34699-2-chenmin.sun@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200715195329.34699-1-chenmin.sun@intel.com> References: <20200713222321.2118-1-chenmin.sun@intel.com> <20200715195329.34699-1-chenmin.sun@intel.com> Subject: [dpdk-dev] [PATCH V4 1/4] net/i40e: introducing the fdir space tracking 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" From: Chenmin Sun This patch introduces a fdir flow management for guaranteed/shared space tracking. The fdir space is reported by the i40e_hw_capabilities.fd_filters_guaranteed and fd_filters_best_effort. The fdir space is managed by hardware and now is tracking in software. The management algorithm is controlled by the GLQF_CTL.INVALPRIO. Detailed implementation please check in the datasheet and the description of struct i40e_fdir_info.fdir_invalprio. This patch changes the global register GLQF_CTL. Therefore, when devarg ``support-multi-driver`` is set, the patch will not take effect to avoid affecting the normal behavior of other i40e drivers, e.g., Linux kernel driver. Signed-off-by: Chenmin Sun Reviewed-by: Jingjing Wu --- drivers/net/i40e/i40e_ethdev.c | 41 ++++++++++++++++++++++++++++++++++ drivers/net/i40e/i40e_ethdev.h | 28 +++++++++++++++++++++-- drivers/net/i40e/i40e_fdir.c | 16 +++++++++++++ drivers/net/i40e/i40e_flow.c | 5 +++++ drivers/net/i40e/i40e_rxtx.c | 1 + 5 files changed, 89 insertions(+), 2 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 393b5320f..dca84a1f1 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "i40e_logs.h" #include "base/i40e_prototype.h" @@ -1045,8 +1046,11 @@ static int i40e_init_fdir_filter_list(struct rte_eth_dev *dev) { struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct i40e_hw *hw = I40E_PF_TO_HW(pf); struct i40e_fdir_info *fdir_info = &pf->fdir; 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; int ret; struct rte_hash_parameters fdir_hash_params = { @@ -1067,6 +1071,7 @@ i40e_init_fdir_filter_list(struct rte_eth_dev *dev) PMD_INIT_LOG(ERR, "Failed to create fdir hash table!"); return -EINVAL; } + fdir_info->hash_map = rte_zmalloc("i40e_fdir_hash_map", sizeof(struct i40e_fdir_filter *) * I40E_MAX_FDIR_FILTER_NUM, @@ -1077,6 +1082,15 @@ i40e_init_fdir_filter_list(struct rte_eth_dev *dev) ret = -ENOMEM; goto err_fdir_hash_map_alloc; } + + fdir_info->fdir_space_size = alloc + best; + fdir_info->fdir_actual_cnt = 0; + fdir_info->fdir_guarantee_total_space = alloc; + fdir_info->fdir_guarantee_free_space = + fdir_info->fdir_guarantee_total_space; + + PMD_DRV_LOG(INFO, "FDIR guarantee space: %u, best_effort space %u.", alloc, best); + return 0; err_fdir_hash_map_alloc: @@ -1101,6 +1115,30 @@ i40e_init_customized_info(struct i40e_pf *pf) pf->esp_support = false; } +static void +i40e_init_filter_invalidation(struct i40e_pf *pf) +{ + struct i40e_hw *hw = I40E_PF_TO_HW(pf); + struct i40e_fdir_info *fdir_info = &pf->fdir; + uint32_t glqf_ctl_reg = 0; + + glqf_ctl_reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL); + if (!pf->support_multi_driver) { + fdir_info->fdir_invalprio = 1; + glqf_ctl_reg |= I40E_GLQF_CTL_INVALPRIO_MASK; + PMD_DRV_LOG(INFO, "FDIR INVALPRIO set to guaranteed first"); + i40e_write_rx_ctl(hw, I40E_GLQF_CTL, glqf_ctl_reg); + } else { + if (glqf_ctl_reg & I40E_GLQF_CTL_INVALPRIO_MASK) { + fdir_info->fdir_invalprio = 1; + PMD_DRV_LOG(INFO, "FDIR INVALPRIO is: guaranteed first"); + } else { + fdir_info->fdir_invalprio = 0; + PMD_DRV_LOG(INFO, "FDIR INVALPRIO is: shared first"); + } + } +} + void i40e_init_queue_region_conf(struct rte_eth_dev *dev) { @@ -1654,6 +1692,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) /* Initialize customized information */ i40e_init_customized_info(pf); + /* Initialize the filter invalidation configuration */ + i40e_init_filter_invalidation(pf); + ret = i40e_init_ethtype_filter_list(dev); if (ret < 0) goto err_init_ethtype_filter_list; diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 31ca05de9..eb505c799 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -698,6 +698,30 @@ struct i40e_fdir_info { struct i40e_fdir_filter **hash_map; struct rte_hash *hash_table; + /* + * Priority ordering at filter invalidation(destroying a flow) between + * "best effort" space and "guaranteed" space. + * + * 0 = At filter invalidation, the hardware first tries to increment the + * "best effort" space. The "guaranteed" space is incremented only when + * the global "best effort" space is at it max value or the "best effort" + * space of the PF is at its max value. + * 1 = At filter invalidation, the hardware first tries to increment its + * "guaranteed" space. The "best effort" space is incremented only when + * it is already at its max value. + */ + uint32_t fdir_invalprio; + /* the total size of the fdir, this number is the sum of the guaranteed + + * shared space + */ + uint32_t fdir_space_size; + /* the actual number of the fdir rules in hardware, initialized as 0 */ + uint32_t fdir_actual_cnt; + /* the free guaranteed space of the fdir */ + uint32_t fdir_guarantee_free_space; + /* the fdir total guaranteed space */ + uint32_t fdir_guarantee_total_space; + /* Mark if flex pit and mask is set */ bool flex_pit_flag[I40E_MAX_FLXPLD_LAYER]; bool flex_mask_flag[I40E_FILTER_PCTYPE_MAX]; @@ -1335,8 +1359,8 @@ int i40e_add_del_fdir_filter(struct rte_eth_dev *dev, const struct rte_eth_fdir_filter *filter, bool add); int i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev, - const struct i40e_fdir_filter_conf *filter, - bool add); + const struct i40e_fdir_filter_conf *filter, + bool add); int i40e_dev_tunnel_filter_set(struct i40e_pf *pf, struct rte_eth_tunnel_filter_conf *tunnel_filter, uint8_t add); diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index 71eb31fb8..c37343f8f 100644 --- a/drivers/net/i40e/i40e_fdir.c +++ b/drivers/net/i40e/i40e_fdir.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "i40e_logs.h" #include "base/i40e_type.h" @@ -244,6 +245,10 @@ i40e_fdir_setup(struct i40e_pf *pf) pf->fdir.dma_addr = mz->iova; pf->fdir.match_counter_index = I40E_COUNTER_INDEX_FDIR(hw->pf_id); + pf->fdir.fdir_actual_cnt = 0; + pf->fdir.fdir_guarantee_free_space = + pf->fdir.fdir_guarantee_total_space; + PMD_DRV_LOG(INFO, "FDIR setup successfully, with programming queue %u.", vsi->base_queue); return I40E_SUCCESS; @@ -1762,6 +1767,11 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev, } if (add) { + fdir_info->fdir_actual_cnt++; + if (fdir_info->fdir_invalprio == 1 && + fdir_info->fdir_guarantee_free_space > 0) + fdir_info->fdir_guarantee_free_space--; + fdir_filter = rte_zmalloc("fdir_filter", sizeof(*fdir_filter), 0); if (fdir_filter == NULL) { @@ -1774,6 +1784,12 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev, if (ret < 0) rte_free(fdir_filter); } else { + fdir_info->fdir_actual_cnt--; + if (fdir_info->fdir_invalprio == 1 && + fdir_info->fdir_guarantee_free_space < + fdir_info->fdir_guarantee_total_space) + fdir_info->fdir_guarantee_free_space++; + ret = i40e_sw_fdir_filter_del(pf, &node->fdir.input); } diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index 7cd537340..1f2da7926 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "i40e_logs.h" #include "base/i40e_type.h" @@ -5601,6 +5602,10 @@ i40e_flow_flush_fdir_filter(struct i40e_pf *pf) } } + fdir_info->fdir_actual_cnt = 0; + fdir_info->fdir_guarantee_free_space = + fdir_info->fdir_guarantee_total_space; + for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP; pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) pf->fdir.inset_flag[pctype] = 0; diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c index 2d2efb71a..d21fbeaca 100644 --- a/drivers/net/i40e/i40e_rxtx.c +++ b/drivers/net/i40e/i40e_rxtx.c @@ -2989,6 +2989,7 @@ i40e_fdir_setup_tx_resources(struct i40e_pf *pf) txq->tx_ring_phys_addr = tz->iova; txq->tx_ring = (struct i40e_tx_desc *)tz->addr; + /* * don't need to allocate software ring and reset for the fdir * program queue just set the queue has been configured.