From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id C24D6A0597; Fri, 17 Apr 2020 18:20:54 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id F40A01EA49; Fri, 17 Apr 2020 18:19:39 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 26FF51E9DE for ; Fri, 17 Apr 2020 18:19:28 +0200 (CEST) Received: from mail-irv-17.broadcom.com (mail-irv-17.lvn.broadcom.net [10.75.242.48]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id BEAD330C1E8; Fri, 17 Apr 2020 09:08:07 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com BEAD330C1E8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1587139687; bh=gaj0H8cUZSIn8694koqZ7uAN+BCbI+BjUdqq8OvbqbE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tx4skEAPVcMld2D8ergkpfHfH+dKHfB9O28rjjl8+36Tn0zacSEXIjLntBa4uQ6ow qxkCvY6LyNxh2Vt/xAhWp1/I6whUVd2kyN0m4cXf8h9XHP2cGwTPOgL2h0hAgWk2E8 cf0XaRnc6ta3w5jBmUOvvIEZsKMpqwRZ6tzar6XA= Received: from localhost.localdomain (unknown [10.230.185.215]) by mail-irv-17.broadcom.com (Postfix) with ESMTP id 068DE14008C; Fri, 17 Apr 2020 09:19:27 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: Kishore Padmanabha , Venkat Duvvuru , Michael Baucom Date: Fri, 17 Apr 2020 09:19:16 -0700 Message-Id: <20200417161920.85858-9-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20200417161920.85858-1-ajit.khaparde@broadcom.com> References: <1586962156-11179-1-git-send-email-venkatkumar.duvvuru@broadcom.com> <20200417161920.85858-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v2 08/12] net/bnxt: add session and function flow flush 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: Kishore Padmanabha The ulp flow flush has been extended to support session flow flush and function flow flush. The session flow flush is called when there the device is sole owner of the session and it deletes all the flows associated with that session. The function flow flush is called if the device function is not the sole owner of the session, it deletes all the flows that are associated with that device function. Reviewed-by: Venkat Duvvuru Reviewed-by: Michael Baucom Reviewed-by: Ajit Khaparde Signed-off-by: Kishore Padmanabha Signed-off-by: Venkat Duvvuru --- drivers/net/bnxt/bnxt.h | 1 + drivers/net/bnxt/bnxt_ethdev.c | 12 ++ drivers/net/bnxt/tf_ulp/bnxt_ulp.c | 8 +- drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c | 31 +++-- drivers/net/bnxt/tf_ulp/ulp_flow_db.c | 149 ++++++++++++++++++++++-- drivers/net/bnxt/tf_ulp/ulp_flow_db.h | 46 +++++++- drivers/net/bnxt/tf_ulp/ulp_mapper.c | 2 +- drivers/net/bnxt/tf_ulp/ulp_mapper.h | 1 + 8 files changed, 224 insertions(+), 26 deletions(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 00a4d0b3e..941eee6cd 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -755,6 +755,7 @@ void bnxt_ulp_deinit(struct bnxt *bp); uint16_t bnxt_get_vnic_id(uint16_t port); uint16_t bnxt_get_svif(uint16_t port_id, bool func_svif); +uint16_t bnxt_get_fw_func_id(uint16_t port); void bnxt_cancel_fc_thread(struct bnxt *bp); void bnxt_flow_cnt_alarm_cb(void *arg); diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index bd2c3fcb6..3fa0daffd 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -4901,6 +4901,18 @@ bnxt_get_vnic_id(uint16_t port) return vnic->fw_vnic_id; } +uint16_t +bnxt_get_fw_func_id(uint16_t port) +{ + struct rte_eth_dev *eth_dev; + struct bnxt *bp; + + eth_dev = &rte_eth_devices[port]; + bp = eth_dev->data->dev_private; + + return bp->fw_fid; +} + static int bnxt_init_fw(struct bnxt *bp) { uint16_t mtu; diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c index 56e08f233..c67da6d76 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c @@ -659,10 +659,8 @@ int32_t bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx, struct bnxt_ulp_flow_db *flow_db) { - if (!ulp_ctx || !ulp_ctx->cfg_data) { - BNXT_TF_DBG(ERR, "Invalid ulp context data\n"); + if (!ulp_ctx || !ulp_ctx->cfg_data) return -EINVAL; - } ulp_ctx->cfg_data->flow_db = flow_db; return 0; @@ -672,10 +670,8 @@ bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx, struct bnxt_ulp_flow_db * bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx) { - if (!ulp_ctx || !ulp_ctx->cfg_data) { - BNXT_TF_DBG(ERR, "Invalid ulp context data\n"); + if (!ulp_ctx || !ulp_ctx->cfg_data) return NULL; - } return ulp_ctx->cfg_data->flow_db; } diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c index 7f7aa24e6..f0c812ced 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c @@ -125,6 +125,7 @@ bnxt_ulp_flow_create(struct rte_eth_dev *dev, mapper_cparms.act_prop = ¶ms.act_prop; mapper_cparms.class_tid = class_id; mapper_cparms.act_tid = act_tmpl; + mapper_cparms.func_id = bnxt_get_fw_func_id(dev->data->port_id); /* call the ulp mapper to create the flow in the hardware */ ret = ulp_mapper_flow_create(ulp_ctx, @@ -202,7 +203,8 @@ bnxt_ulp_flow_destroy(struct rte_eth_dev *dev, { int ret = 0; struct bnxt_ulp_context *ulp_ctx; - uint32_t fid; + uint32_t flow_id; + uint16_t func_id; ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); if (!ulp_ctx) { @@ -213,9 +215,19 @@ bnxt_ulp_flow_destroy(struct rte_eth_dev *dev, return -EINVAL; } - fid = (uint32_t)(uintptr_t)flow; + flow_id = (uint32_t)(uintptr_t)flow; + func_id = bnxt_get_fw_func_id(dev->data->port_id); - ret = ulp_mapper_flow_destroy(ulp_ctx, fid); + if (ulp_flow_db_validate_flow_func(ulp_ctx, flow_id, func_id) == + false) { + BNXT_TF_DBG(ERR, "Incorrect device params\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to destroy flow."); + return -EINVAL; + } + + ret = ulp_mapper_flow_destroy(ulp_ctx, flow_id); if (ret) rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, @@ -230,8 +242,9 @@ bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error) { struct bnxt_ulp_context *ulp_ctx; - int32_t ret; + int32_t ret = 0; struct bnxt *bp; + uint16_t func_id; ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); if (!ulp_ctx) { @@ -244,10 +257,12 @@ bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev, bp = eth_dev->data->dev_private; /* Free the resources for the last device */ - if (!ulp_ctx_deinit_allowed(bp)) - return 0; - - ret = ulp_flow_db_flush_flows(ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE); + if (ulp_ctx_deinit_allowed(bp)) { + ret = ulp_flow_db_session_flow_flush(ulp_ctx); + } else if (bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx)) { + func_id = bnxt_get_fw_func_id(eth_dev->data->port_id); + ret = ulp_flow_db_function_flow_flush(ulp_ctx, func_id); + } if (ret) rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, diff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c index 9e7f9f5e3..35a7f868a 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c +++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c @@ -209,6 +209,27 @@ ulp_flow_db_dealloc_resource(struct bnxt_ulp_flow_db *flow_db, } } +/* + * Helper function to add function id to the flow table + * + * flow_db [in] Ptr to flow table + * flow_id [in] The flow id of the flow + * func_id [in] The func_id to be set, for reset pass zero + * + * returns none + */ +static void +ulp_flow_db_func_id_set(struct bnxt_ulp_flow_db *flow_db, + uint32_t flow_id, + uint32_t func_id) +{ + /* set the function id in the function table */ + if (flow_id < flow_db->func_id_tbl_size) + flow_db->func_id_tbl[flow_id] = func_id; + else /* This should never happen */ + BNXT_TF_DBG(ERR, "Invalid flow id, flowdb corrupt\n"); +} + /* * Initialize the flow database. Memory is allocated in this * call and assigned to the flow database. @@ -241,7 +262,7 @@ int32_t ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt) if (!flow_db) { BNXT_TF_DBG(ERR, "Failed to allocate memory for flow table ptr\n"); - goto error_free; + return -ENOMEM; } /* Attach the flow database to the ulp context. */ @@ -265,6 +286,17 @@ int32_t ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt) if (ulp_flow_db_alloc_resource(flow_db, BNXT_ULP_DEFAULT_FLOW_TABLE)) goto error_free; + /* add 1 since we are not using index 0 for flow id */ + flow_db->func_id_tbl_size = dparms->num_flows + 1; + /* Allocate the function Id table */ + flow_db->func_id_tbl = rte_zmalloc("bnxt_ulp_flow_db_func_id_table", + flow_db->func_id_tbl_size * + sizeof(uint16_t), 0); + if (!flow_db->func_id_tbl) { + BNXT_TF_DBG(ERR, + "Failed to allocate mem for flow table func id\n"); + goto error_free; + } /* All good so return. */ return 0; error_free: @@ -297,6 +329,7 @@ int32_t ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt) /* Free up all the memory. */ ulp_flow_db_dealloc_resource(flow_db, BNXT_ULP_REGULAR_FLOW_TABLE); ulp_flow_db_dealloc_resource(flow_db, BNXT_ULP_DEFAULT_FLOW_TABLE); + rte_free(flow_db->func_id_tbl); rte_free(flow_db); return 0; @@ -311,12 +344,13 @@ int32_t ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt) * * returns 0 on success and negative on failure. */ -int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt, - enum bnxt_ulp_flow_db_tables tbl_idx, - uint32_t *fid) +int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt, + enum bnxt_ulp_flow_db_tables tbl_idx, + uint16_t func_id, + uint32_t *fid) { - struct bnxt_ulp_flow_db *flow_db; - struct bnxt_ulp_flow_tbl *flow_tbl; + struct bnxt_ulp_flow_db *flow_db; + struct bnxt_ulp_flow_tbl *flow_tbl; *fid = 0; /* Initialize fid to invalid value */ flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); @@ -339,6 +373,10 @@ int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt, flow_tbl->head_index++; ulp_flow_db_active_flow_set(flow_tbl, *fid, 1); + /* The function id update is only valid for regular flow table */ + if (tbl_idx == BNXT_ULP_REGULAR_FLOW_TABLE) + ulp_flow_db_func_id_set(flow_db, *fid, func_id); + /* all good, return success */ return 0; } @@ -555,6 +593,8 @@ int32_t ulp_flow_db_fid_free(struct bnxt_ulp_context *ulp_ctxt, } flow_tbl->flow_tbl_stack[flow_tbl->head_index] = fid; ulp_flow_db_active_flow_set(flow_tbl, fid, 0); + if (tbl_idx == BNXT_ULP_REGULAR_FLOW_TABLE) + ulp_flow_db_func_id_set(flow_db, fid, 0); /* all good, return success */ return 0; @@ -636,19 +676,29 @@ ulp_flow_db_next_entry_get(struct bnxt_ulp_flow_tbl *flowtbl, uint32_t *fid) { uint32_t lfid = *fid; - uint32_t idx; + uint32_t idx, s_idx, mod_fid; uint64_t bs; do { + /* increment the flow id to find the next valid flow id */ lfid++; if (lfid >= flowtbl->num_flows) return -ENOENT; idx = lfid / ULP_INDEX_BITMAP_SIZE; + mod_fid = lfid % ULP_INDEX_BITMAP_SIZE; + s_idx = idx; while (!(bs = flowtbl->active_flow_tbl[idx])) { idx++; if ((idx * ULP_INDEX_BITMAP_SIZE) >= flowtbl->num_flows) return -ENOENT; } + /* + * remove the previous bits in the bitset bs to find the + * next non zero bit in the bitset. This needs to be done + * only if the idx is same as he one you started. + */ + if (s_idx == idx) + bs &= (-1UL >> mod_fid); lfid = (idx * ULP_INDEX_BITMAP_SIZE) + __builtin_clzl(bs); if (*fid >= lfid) { BNXT_TF_DBG(ERR, "Flow Database is corrupt\n"); @@ -688,7 +738,90 @@ int32_t ulp_flow_db_flush_flows(struct bnxt_ulp_context *ulp_ctx, } flow_tbl = &flow_db->flow_tbl[idx]; while (!ulp_flow_db_next_entry_get(flow_tbl, &fid)) - (void)ulp_mapper_resources_free(ulp_ctx, fid, idx); + ulp_mapper_resources_free(ulp_ctx, fid, idx); return 0; } + +/* + * Flush all flows in the flow database that belong to a device function. + * + * ulp_ctxt [in] Ptr to ulp context + * tbl_idx [in] The index to table + * + * returns 0 on success or negative number on failure + */ +int32_t +ulp_flow_db_function_flow_flush(struct bnxt_ulp_context *ulp_ctx, + uint16_t func_id) +{ + uint32_t flow_id = 0; + struct bnxt_ulp_flow_db *flow_db; + struct bnxt_ulp_flow_tbl *flow_tbl; + + if (!ulp_ctx || !func_id) { + BNXT_TF_DBG(ERR, "Invalid Argument\n"); + return -EINVAL; + } + + flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx); + if (!flow_db) { + BNXT_TF_DBG(ERR, "Flow database not found\n"); + return -EINVAL; + } + flow_tbl = &flow_db->flow_tbl[BNXT_ULP_REGULAR_FLOW_TABLE]; + while (!ulp_flow_db_next_entry_get(flow_tbl, &flow_id)) { + if (flow_db->func_id_tbl[flow_id] == func_id) + ulp_mapper_resources_free(ulp_ctx, flow_id, + BNXT_ULP_REGULAR_FLOW_TABLE); + } + + return 0; +} + +/* + * Flush all flows in the flow database that are associated with the session. + * + * ulp_ctxt [in] Ptr to ulp context + * + * returns 0 on success or negative number on failure + */ +int32_t +ulp_flow_db_session_flow_flush(struct bnxt_ulp_context *ulp_ctx) +{ + /* + * TBD: Tf core implementation of FW session flush shall change this + * implementation. + */ + return ulp_flow_db_flush_flows(ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE); +} + +/* + * Check that flow id matches the function id or not + * + * ulp_ctxt [in] Ptr to ulp context + * flow_db [in] Ptr to flow table + * func_id [in] The func_id to be set, for reset pass zero. + * + * returns true on success or false on failure + */ +bool +ulp_flow_db_validate_flow_func(struct bnxt_ulp_context *ulp_ctx, + uint32_t flow_id, + uint32_t func_id) +{ + struct bnxt_ulp_flow_db *flow_db; + + flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx); + if (!flow_db) { + BNXT_TF_DBG(ERR, "Flow database not found\n"); + return false; + } + + /* set the function id in the function table */ + if (flow_id < flow_db->func_id_tbl_size && func_id && + flow_db->func_id_tbl[flow_id] == func_id) + return true; + + return false; +} diff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h index 5361dd025..ebca84947 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h +++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h @@ -51,6 +51,8 @@ enum bnxt_ulp_flow_db_tables { /* Structure for the flow database resource information. */ struct bnxt_ulp_flow_db { struct bnxt_ulp_flow_tbl flow_tbl[BNXT_ULP_FLOW_TABLE_MAX]; + uint16_t *func_id_tbl; + uint32_t func_id_tbl_size; }; /* flow db resource params to add resources */ @@ -88,13 +90,15 @@ int32_t ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt); * * ulp_ctxt [in] Ptr to ulp_context * tbl_idx [in] Specify it is regular or default flow + * func_id [in] The function id of the device.Valid only for regular flows. * fid [out] The index to the flow entry * * returns 0 on success and negative on failure. */ -int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt, - enum bnxt_ulp_flow_db_tables tbl_idx, - uint32_t *fid); +int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt, + enum bnxt_ulp_flow_db_tables tbl_idx, + uint16_t func_id, + uint32_t *fid); /* * Allocate the flow database entry. @@ -170,4 +174,40 @@ int32_t ulp_flow_db_resource_get(struct bnxt_ulp_context *ulp_ctxt, int32_t ulp_flow_db_flush_flows(struct bnxt_ulp_context *ulp_ctx, uint32_t idx); +/* + * Flush all flows in the flow database that belong to a device function. + * + * ulp_ctxt [in] Ptr to ulp context + * tbl_idx [in] The index to table + * + * returns 0 on success or negative number on failure + */ +int32_t +ulp_flow_db_function_flow_flush(struct bnxt_ulp_context *ulp_ctx, + uint16_t func_id); + +/* + * Flush all flows in the flow database that are associated with the session. + * + * ulp_ctxt [in] Ptr to ulp context + * + * returns 0 on success or negative number on failure + */ +int32_t +ulp_flow_db_session_flow_flush(struct bnxt_ulp_context *ulp_ctx); + +/* + * Check that flow id matches the function id or not + * + * ulp_ctxt [in] Ptr to ulp context + * flow_db [in] Ptr to flow table + * func_id [in] The func_id to be set, for reset pass zero. + * + * returns true on success or false on failure + */ +bool +ulp_flow_db_validate_flow_func(struct bnxt_ulp_context *ulp_ctx, + uint32_t flow_id, + uint32_t func_id); + #endif /* _ULP_FLOW_DB_H_ */ diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c index a0aba403f..94899c005 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c +++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c @@ -461,7 +461,6 @@ ulp_mapper_result_field_process(struct bnxt_ulp_mapper_parms *parms, default: return -EINVAL; } - return 0; } @@ -1481,6 +1480,7 @@ ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx, */ rc = ulp_flow_db_fid_alloc(ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE, + cparms->func_id, &parms.fid); if (rc) { BNXT_TF_DBG(ERR, "Unable to allocate flow table entry\n"); diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.h b/drivers/net/bnxt/tf_ulp/ulp_mapper.h index 24727a32d..2fa6ffce2 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_mapper.h +++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.h @@ -46,6 +46,7 @@ struct bnxt_ulp_mapper_create_parms { struct ulp_rte_act_prop *act_prop; uint32_t class_tid; uint32_t act_tid; + uint16_t func_id; }; /* -- 2.21.1 (Apple Git-122.3)