From patchwork Fri Oct 18 11:15:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cao, Yahui" X-Patchwork-Id: 61453 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 1ADA01E8A0; Fri, 18 Oct 2019 05:34:01 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 0ECCF1E85F for ; Fri, 18 Oct 2019 05:33:50 +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:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,310,1566889200"; d="scan'208";a="202577938" Received: from dpdk-yahui-skylake.sh.intel.com ([10.67.119.16]) by FMSMGA003.fm.intel.com with ESMTP; 17 Oct 2019 20:33:49 -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:15:59 +0800 Message-Id: <20191018111602.26742-7-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 6/9] net/ice: add FDIR counter support 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" This patch add FDIR statistical counter support and it includes RTE_FLOW count actions support and query support. RTE_FLOW count actions support id and shared. RTE_FLOW query record packet hits by default. Signed-off-by: Yahui Cao Acked-by: Qi Zhang --- drivers/net/ice/ice_ethdev.h | 7 ++ drivers/net/ice/ice_fdir_filter.c | 179 +++++++++++++++++++++++++++++- 2 files changed, 185 insertions(+), 1 deletion(-) diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index 5947a7883..5129b3b67 100644 --- a/drivers/net/ice/ice_ethdev.h +++ b/drivers/net/ice/ice_ethdev.h @@ -249,6 +249,10 @@ TAILQ_HEAD(ice_parser_list, ice_flow_parser_node); struct ice_fdir_filter_conf { struct ice_fdir_fltr input; + + struct ice_fdir_counter *counter; /* flow specific counter context */ + struct rte_flow_action_count act_count; + uint64_t input_set; }; @@ -257,8 +261,11 @@ struct ice_fdir_filter_conf { #define ICE_FDIR_COUNTERS_PER_BLOCK 256 #define ICE_FDIR_COUNTER_INDEX(base_idx) \ ((base_idx) * ICE_FDIR_COUNTERS_PER_BLOCK) +struct ice_fdir_counter_pool; + struct ice_fdir_counter { TAILQ_ENTRY(ice_fdir_counter) next; + struct ice_fdir_counter_pool *pool; uint8_t shared; uint32_t ref_cnt; uint32_t id; diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c index 8dbd6fc72..b327ead80 100644 --- a/drivers/net/ice/ice_fdir_filter.c +++ b/drivers/net/ice/ice_fdir_filter.c @@ -183,6 +183,95 @@ ice_fdir_counter_release(struct ice_pf *pf) return 0; } +static struct ice_fdir_counter * +ice_fdir_counter_shared_search(struct ice_fdir_counter_pool_container + *container, + uint32_t id) +{ + struct ice_fdir_counter_pool *pool; + struct ice_fdir_counter *counter; + int i; + + TAILQ_FOREACH(pool, &container->pool_list, next) { + for (i = 0; i < ICE_FDIR_COUNTERS_PER_BLOCK; i++) { + counter = &pool->counters[i]; + + if (counter->shared && + counter->ref_cnt && + counter->id == id) + return counter; + } + } + + return NULL; +} + +static struct ice_fdir_counter * +ice_fdir_counter_alloc(struct ice_pf *pf, uint32_t shared, uint32_t id) +{ + struct ice_hw *hw = ICE_PF_TO_HW(pf); + struct ice_fdir_info *fdir_info = &pf->fdir; + struct ice_fdir_counter_pool_container *container = + &fdir_info->counter; + struct ice_fdir_counter_pool *pool = NULL; + struct ice_fdir_counter *counter_free = NULL; + + if (shared) { + counter_free = ice_fdir_counter_shared_search(container, id); + if (counter_free) { + if (counter_free->ref_cnt + 1 == 0) { + rte_errno = E2BIG; + return NULL; + } + counter_free->ref_cnt++; + return counter_free; + } + } + + TAILQ_FOREACH(pool, &container->pool_list, next) { + counter_free = TAILQ_FIRST(&pool->counter_list); + if (counter_free) + break; + counter_free = NULL; + } + + if (!counter_free) { + PMD_DRV_LOG(ERR, "No free counter found\n"); + return NULL; + } + + counter_free->shared = shared; + counter_free->id = id; + counter_free->ref_cnt = 1; + counter_free->pool = pool; + + /* reset statistic counter value */ + ICE_WRITE_REG(hw, GLSTAT_FD_CNT0H(counter_free->hw_index), 0); + ICE_WRITE_REG(hw, GLSTAT_FD_CNT0L(counter_free->hw_index), 0); + + TAILQ_REMOVE(&pool->counter_list, counter_free, next); + if (TAILQ_EMPTY(&pool->counter_list)) { + TAILQ_REMOVE(&container->pool_list, pool, next); + TAILQ_INSERT_TAIL(&container->pool_list, pool, next); + } + + return counter_free; +} + +static void +ice_fdir_counter_free(__rte_unused struct ice_pf *pf, + struct ice_fdir_counter *counter) +{ + if (!counter) + return; + + if (--counter->ref_cnt == 0) { + struct ice_fdir_counter_pool *pool = counter->pool; + + TAILQ_INSERT_TAIL(&pool->counter_list, counter, next); + } +} + /* * ice_fdir_setup - reserve and initialize the Flow Director resources * @pf: board private structure @@ -691,12 +780,28 @@ ice_fdir_create_filter(struct ice_adapter *ad, goto free_entry; } + /* alloc counter for FDIR */ + if (filter->input.cnt_ena) { + struct rte_flow_action_count *act_count = &filter->act_count; + + filter->counter = ice_fdir_counter_alloc(pf, + act_count->shared, + act_count->id); + if (!filter->counter) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "Failed to alloc FDIR counter."); + goto free_entry; + } + filter->input.cnt_index = filter->counter->hw_index; + } + ret = ice_fdir_add_del_filter(pf, filter, true); if (ret) { rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Add filter rule failed."); - goto free_entry; + goto free_counter; } rte_memcpy(rule, filter, sizeof(*rule)); @@ -704,6 +809,12 @@ ice_fdir_create_filter(struct ice_adapter *ad, ice_fdir_cnt_update(pf, filter->input.flow_type, false, true); return 0; +free_counter: + if (filter->counter) { + ice_fdir_counter_free(pf, filter->counter); + filter->counter = NULL; + } + free_entry: rte_free(rule); return -rte_errno; @@ -720,6 +831,11 @@ ice_fdir_destroy_filter(struct ice_adapter *ad, filter = (struct ice_fdir_filter_conf *)flow->rule; + if (filter->counter) { + ice_fdir_counter_free(pf, filter->counter); + filter->counter = NULL; + } + ret = ice_fdir_add_del_filter(pf, filter, false); if (ret) { rte_flow_error_set(error, -ret, @@ -736,11 +852,54 @@ ice_fdir_destroy_filter(struct ice_adapter *ad, return 0; } +static int +ice_fdir_query_count(struct ice_adapter *ad, + struct rte_flow *flow, + struct rte_flow_query_count *flow_stats, + struct rte_flow_error *error) +{ + struct ice_pf *pf = &ad->pf; + struct ice_hw *hw = ICE_PF_TO_HW(pf); + struct ice_fdir_filter_conf *filter = flow->rule; + struct ice_fdir_counter *counter = filter->counter; + uint64_t hits_lo, hits_hi; + + if (!counter) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "FDIR counters not available"); + return -rte_errno; + } + + /* + * Reading the low 32-bits latches the high 32-bits into a shadow + * register. Reading the high 32-bit returns the value in the + * shadow register. + */ + hits_lo = ICE_READ_REG(hw, GLSTAT_FD_CNT0L(counter->hw_index)); + hits_hi = ICE_READ_REG(hw, GLSTAT_FD_CNT0H(counter->hw_index)); + + flow_stats->hits_set = 1; + flow_stats->hits = hits_lo | (hits_hi << 32); + flow_stats->bytes_set = 0; + flow_stats->bytes = 0; + + if (flow_stats->reset) { + /* reset statistic counter value */ + ICE_WRITE_REG(hw, GLSTAT_FD_CNT0H(counter->hw_index), 0); + ICE_WRITE_REG(hw, GLSTAT_FD_CNT0L(counter->hw_index), 0); + } + + return 0; +} + static struct ice_flow_engine ice_fdir_engine = { .init = ice_fdir_init, .uninit = ice_fdir_uninit, .create = ice_fdir_create_filter, .destroy = ice_fdir_destroy_filter, + .query_count = ice_fdir_query_count, .type = ICE_FLOW_ENGINE_FDIR, }; @@ -810,8 +969,10 @@ ice_fdir_parse_action(struct ice_adapter *ad, struct ice_pf *pf = &ad->pf; const struct rte_flow_action_queue *act_q; const struct rte_flow_action_mark *mark_spec = NULL; + const struct rte_flow_action_count *act_count; uint32_t dest_num = 0; uint32_t mark_num = 0; + uint32_t counter_num = 0; int ret; for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { @@ -860,6 +1021,15 @@ ice_fdir_parse_action(struct ice_adapter *ad, mark_spec = actions->conf; filter->input.fltr_id = mark_spec->id; + break; + case RTE_FLOW_ACTION_TYPE_COUNT: + counter_num++; + + act_count = actions->conf; + filter->input.cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS; + rte_memcpy(&filter->act_count, act_count, + sizeof(filter->act_count)); + break; default: rte_flow_error_set(error, EINVAL, @@ -883,6 +1053,13 @@ ice_fdir_parse_action(struct ice_adapter *ad, return -rte_errno; } + if (counter_num >= 2) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, actions, + "Too many count actions"); + return -rte_errno; + } + return 0; }