From patchwork Fri Jun 12 13:29:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Somnath Kotur X-Patchwork-Id: 71442 X-Patchwork-Delegate: ajit.khaparde@broadcom.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 54E71A00BE; Fri, 12 Jun 2020 15:53:14 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A14061D44B; Fri, 12 Jun 2020 15:35:16 +0200 (CEST) Received: from relay.smtp.broadcom.com (unknown [192.19.232.149]) by dpdk.org (Postfix) with ESMTP id B28B21D40E for ; Fri, 12 Jun 2020 15:35:11 +0200 (CEST) Received: from dhcp-10-123-153-55.dhcp.broadcom.net (dhcp-10-123-153-55.dhcp.broadcom.net [10.123.153.55]) by relay.smtp.broadcom.com (Postfix) with ESMTP id 8B0D31BD7A4; Fri, 12 Jun 2020 06:35:10 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 relay.smtp.broadcom.com 8B0D31BD7A4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1591968911; bh=Q7yvNHSH9dHCf4eqMpJiFbyXzov7dsKBuyw+WzJNYu0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZcGa2EgCV0frJpeEmAIGLyjF+TlLYvyJnqwAfrHiIYH4qIUwsFYBnmrrLrBdd6mOy +iaGKFFzRp/XH5KwFklHl6PqYKeIPBrwyBXensEF3nePFerb7VCYwf0afBUXPHnLSw lY/ioySaFpZb2gItUhoJ1UJQ0AIemuT7OiL63Ox8= From: Somnath Kotur To: dev@dpdk.org Cc: ferruh.yigit@intel.com Date: Fri, 12 Jun 2020 18:59:34 +0530 Message-Id: <20200612132934.16488-51-somnath.kotur@broadcom.com> X-Mailer: git-send-email 2.10.1.613.g2cc2e70 In-Reply-To: <20200612132934.16488-1-somnath.kotur@broadcom.com> References: <20200612132934.16488-1-somnath.kotur@broadcom.com> Subject: [dpdk-dev] [PATCH 50/50] net/bnxt: Add support for flow query with action_type COUNT 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" Use the flow counter manager to fetch the accumulated stats for a flow. Reviewed-by: Venkat Duvvuru Signed-off-by: Somnath Kotur Signed-off-by: Venkat Duvvuru --- drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c | 46 ++++++++++- drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c | 141 ++++++++++++++++++++++++++++++-- drivers/net/bnxt/tf_ulp/ulp_fc_mgr.h | 17 +++- 3 files changed, 197 insertions(+), 7 deletions(-) diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c index 7ef306e..a7a0769 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c @@ -9,6 +9,7 @@ #include "ulp_matcher.h" #include "ulp_flow_db.h" #include "ulp_mapper.h" +#include "ulp_fc_mgr.h" #include static int32_t @@ -289,11 +290,54 @@ bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev, return ret; } +/* Function to query the rte flows. */ +static int32_t +bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev, + struct rte_flow *flow, + const struct rte_flow_action *action, + void *data, + struct rte_flow_error *error) +{ + int rc = 0; + struct bnxt_ulp_context *ulp_ctx; + struct rte_flow_query_count *count; + uint32_t flow_id; + + ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); + if (!ulp_ctx) { + BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to query flow."); + return -EINVAL; + } + + flow_id = (uint32_t)(uintptr_t)flow; + + switch (action->type) { + case RTE_FLOW_ACTION_TYPE_COUNT: + count = data; + rc = ulp_fc_mgr_query_count_get(ulp_ctx, flow_id, count); + if (rc) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to query flow."); + } + break; + default: + rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM, + NULL, "Unsupported action item"); + } + + return rc; +} + const struct rte_flow_ops bnxt_ulp_rte_flow_ops = { .validate = bnxt_ulp_flow_validate, .create = bnxt_ulp_flow_create, .destroy = bnxt_ulp_flow_destroy, .flush = bnxt_ulp_flow_flush, - .query = NULL, + .query = bnxt_ulp_flow_query, .isolate = NULL }; + diff --git a/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c b/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c index f70d4a2..9944e9e 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c +++ b/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c @@ -11,6 +11,7 @@ #include "bnxt_ulp.h" #include "bnxt_tf_common.h" #include "ulp_fc_mgr.h" +#include "ulp_flow_db.h" #include "ulp_template_db_enum.h" #include "ulp_template_struct.h" #include "tf_tbl.h" @@ -226,9 +227,10 @@ void ulp_fc_mgr_thread_cancel(struct bnxt_ulp_context *ctxt) * num_counters [in] The number of counters * */ -static int32_t ulp_bulk_get_flow_stats(struct tf *tfp, +__rte_unused static int32_t ulp_bulk_get_flow_stats(struct tf *tfp, struct bnxt_ulp_fc_info *fc_info, enum tf_dir dir, uint32_t num_counters) +/* MARK AS UNUSED FOR NOW TO AVOID COMPILATION ERRORS TILL API is RESOLVED */ { int rc = 0; struct tf_tbl_get_bulk_parms parms = { 0 }; @@ -275,6 +277,45 @@ static int32_t ulp_bulk_get_flow_stats(struct tf *tfp, return rc; } + +static int ulp_get_single_flow_stat(struct tf *tfp, + struct bnxt_ulp_fc_info *fc_info, + enum tf_dir dir, + uint32_t hw_cntr_id) +{ + int rc = 0; + struct tf_get_tbl_entry_parms parms = { 0 }; + enum tf_tbl_type stype = TF_TBL_TYPE_ACT_STATS_64; /* TBD:Template? */ + struct sw_acc_counter *sw_acc_tbl_entry = NULL; + uint64_t stats = 0; + uint32_t sw_cntr_indx = 0; + + parms.dir = dir; + parms.type = stype; + parms.idx = hw_cntr_id; + /* + * TODO: + * Size of an entry needs to obtained from template + */ + parms.data_sz_in_bytes = sizeof(uint64_t); + parms.data = (uint8_t *)&stats; + rc = tf_get_tbl_entry(tfp, &parms); + if (rc) { + PMD_DRV_LOG(ERR, + "Get failed for id:0x%x rc:%d\n", + parms.idx, rc); + return rc; + } + + /* TBD - Get PKT/BYTE COUNT SHIFT/MASK from Template */ + sw_cntr_indx = hw_cntr_id - fc_info->shadow_hw_tbl[dir].start_idx; + sw_acc_tbl_entry = &fc_info->sw_acc_tbl[dir][sw_cntr_indx]; + sw_acc_tbl_entry->pkt_count += FLOW_CNTR_PKTS(stats); + sw_acc_tbl_entry->byte_count += FLOW_CNTR_BYTES(stats); + + return rc; +} + /* * Alarm handler that will issue the TF-Core API to fetch * data from the chip's internal flow counters @@ -282,15 +323,18 @@ static int32_t ulp_bulk_get_flow_stats(struct tf *tfp, * ctxt [in] The ulp context for the flow counter manager * */ + void ulp_fc_mgr_alarm_cb(void *arg) { - int rc = 0, i; + int rc = 0; + unsigned int j; + enum tf_dir i; struct bnxt_ulp_context *ctxt = arg; struct bnxt_ulp_fc_info *ulp_fc_info; struct bnxt_ulp_device_params *dparms; struct tf *tfp; - uint32_t dev_id; + uint32_t dev_id, hw_cntr_id = 0; ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); if (!ulp_fc_info) @@ -325,13 +369,27 @@ ulp_fc_mgr_alarm_cb(void *arg) ulp_fc_mgr_thread_cancel(ctxt); return; } - - for (i = 0; i < TF_DIR_MAX; i++) { + /* + * Commented for now till GET_BULK is resolved, just get the first flow + * stat for now + for (i = 0; i < TF_DIR_MAX; i++) { rc = ulp_bulk_get_flow_stats(tfp, ulp_fc_info, i, dparms->flow_count_db_entries); if (rc) break; } + */ + for (i = 0; i < TF_DIR_MAX; i++) { + for (j = 0; j < ulp_fc_info->num_entries; j++) { + if (!ulp_fc_info->sw_acc_tbl[i][j].valid) + continue; + hw_cntr_id = ulp_fc_info->sw_acc_tbl[i][j].hw_cntr_id; + rc = ulp_get_single_flow_stat(tfp, ulp_fc_info, i, + hw_cntr_id); + if (rc) + break; + } + } pthread_mutex_unlock(&ulp_fc_info->fc_lock); @@ -425,6 +483,7 @@ int32_t ulp_fc_mgr_cntr_set(struct bnxt_ulp_context *ctxt, enum tf_dir dir, pthread_mutex_lock(&ulp_fc_info->fc_lock); sw_cntr_idx = hw_cntr_id - ulp_fc_info->shadow_hw_tbl[dir].start_idx; ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].valid = true; + ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].hw_cntr_id = hw_cntr_id; ulp_fc_info->num_entries++; pthread_mutex_unlock(&ulp_fc_info->fc_lock); @@ -456,6 +515,7 @@ int32_t ulp_fc_mgr_cntr_reset(struct bnxt_ulp_context *ctxt, enum tf_dir dir, pthread_mutex_lock(&ulp_fc_info->fc_lock); sw_cntr_idx = hw_cntr_id - ulp_fc_info->shadow_hw_tbl[dir].start_idx; ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].valid = false; + ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].hw_cntr_id = 0; ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].pkt_count = 0; ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].byte_count = 0; ulp_fc_info->num_entries--; @@ -463,3 +523,74 @@ int32_t ulp_fc_mgr_cntr_reset(struct bnxt_ulp_context *ctxt, enum tf_dir dir, return 0; } + +/* + * Fill the rte_flow_query_count 'data' argument passed + * in the rte_flow_query() with the values obtained and + * accumulated locally. + * + * ctxt [in] The ulp context for the flow counter manager + * + * flow_id [in] The HW flow ID + * + * count [out] The rte_flow_query_count 'data' that is set + * + */ +int ulp_fc_mgr_query_count_get(struct bnxt_ulp_context *ctxt, + uint32_t flow_id, + struct rte_flow_query_count *count) +{ + int rc = 0; + uint32_t nxt_resource_index = 0; + struct bnxt_ulp_fc_info *ulp_fc_info; + struct ulp_flow_db_res_params params; + enum tf_dir dir; + uint32_t hw_cntr_id = 0, sw_cntr_idx = 0; + struct sw_acc_counter sw_acc_tbl_entry; + bool found_cntr_resource = false; + + ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); + if (!ulp_fc_info) + return -ENODEV; + + do { + rc = ulp_flow_db_resource_get(ctxt, + BNXT_ULP_REGULAR_FLOW_TABLE, + flow_id, + &nxt_resource_index, + ¶ms); + if (params.resource_func == + BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE && + (params.resource_sub_type == + BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TYPE_INT_COUNT || + params.resource_sub_type == + BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TYPE_EXT_COUNT)) { + found_cntr_resource = true; + break; + } + + } while (!rc); + + if (rc) + return rc; + + if (found_cntr_resource) { + dir = params.direction; + hw_cntr_id = params.resource_hndl; + sw_cntr_idx = hw_cntr_id - + ulp_fc_info->shadow_hw_tbl[dir].start_idx; + sw_acc_tbl_entry = ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx]; + if (params.resource_sub_type == + BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TYPE_INT_COUNT) { + count->hits_set = 1; + count->bytes_set = 1; + count->hits = sw_acc_tbl_entry.pkt_count; + count->bytes = sw_acc_tbl_entry.byte_count; + } else { + /* TBD: Handle External counters */ + rc = -EINVAL; + } + } + + return rc; +} diff --git a/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.h b/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.h index faa77dd..2072670 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.h +++ b/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.h @@ -23,6 +23,7 @@ struct sw_acc_counter { uint64_t pkt_count; uint64_t byte_count; bool valid; + uint32_t hw_cntr_id; }; struct hw_fc_mem_info { @@ -142,7 +143,21 @@ bool ulp_fc_mgr_start_idx_isset(struct bnxt_ulp_context *ctxt, enum tf_dir dir); * ctxt [in] The ulp context for the flow counter manager * */ - bool ulp_fc_mgr_thread_isstarted(struct bnxt_ulp_context *ctxt); +/* + * Fill the rte_flow_query_count 'data' argument passed + * in the rte_flow_query() with the values obtained and + * accumulated locally. + * + * ctxt [in] The ulp context for the flow counter manager + * + * flow_id [in] The HW flow ID + * + * count [out] The rte_flow_query_count 'data' that is set + * + */ +int ulp_fc_mgr_query_count_get(struct bnxt_ulp_context *ulp_ctx, + uint32_t flow_id, + struct rte_flow_query_count *count); #endif /* _ULP_FC_MGR_H_ */