From patchwork Tue Sep 3 02:18:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58431 X-Patchwork-Delegate: ferruh.yigit@amd.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 275E61EB16; Tue, 3 Sep 2019 04:19:29 +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 82AC22B94 for ; Tue, 3 Sep 2019 04:19:08 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id C890430C208; Mon, 2 Sep 2019 19:19:00 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com C890430C208 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567477140; bh=UOUJ64riKeRn6/64EPzkruK+WWOcSXToGQrDHonUScQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ii/+tAV+2smoqz8PXjdMSke4aqwUCajEUAI55yU9RffdKt+9E9+4A6HqpoXiaSJKc /oeU1Vi9V8k0btuSK5bXk3tQoxtFAcUVsg5GM2N2HGRlhdwXTXvosTkAov8Od1IiCD gbK6h6QjXyeOZ9xp6/NFg4LsbickXL/CjMFN3oog= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id D6A1DAC078E; Mon, 2 Sep 2019 19:19:06 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Rahul Gupta , Venkat Duvvuru Date: Mon, 2 Sep 2019 19:18:49 -0700 Message-Id: <20190903021901.25895-6-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190903021901.25895-1-ajit.khaparde@broadcom.com> References: <20190903021901.25895-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 05/17] net/bnxt: add support for RSS action 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" Add support for RSS action during flow creation. group id should not be 0 when RSS action is specified. Driver will return an error for such a flow. If a group id is used to create a filter with ā€œnā€ RSS queues, it cannot be used to create a filter with a different number of RSS queues till all the flows using that combination are deleted. While creating a flow if a group id groups a certain Rx queue ids for RSS, the same group id shall not create a flow with a different group of Rx queue ids till all the flows belonging to the group ids are deleted. While creating a flow if a group id groups a certain Rx queue ids for RSS, the same queue ids shall not be used with a different group id till all flows created with that group id are deleted. Reviewed-by: Rahul Gupta Reviewed-by: Venkat Duvvuru Signed-off-by: Ajit Khaparde --- drivers/net/bnxt/bnxt_flow.c | 243 +++++++++++++++++++++++++++++++---- drivers/net/bnxt/bnxt_vnic.c | 2 +- drivers/net/bnxt/bnxt_vnic.h | 1 + 3 files changed, 219 insertions(+), 27 deletions(-) diff --git a/drivers/net/bnxt/bnxt_flow.c b/drivers/net/bnxt/bnxt_flow.c index 4ba280fff..1328f25bc 100644 --- a/drivers/net/bnxt/bnxt_flow.c +++ b/drivers/net/bnxt/bnxt_flow.c @@ -829,6 +829,60 @@ static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic) return rc; } +static int match_vnic_rss_cfg(struct bnxt *bp, + struct bnxt_vnic_info *vnic, + const struct rte_flow_action_rss *rss) +{ + unsigned int match = 0, i; + + if (vnic->rx_queue_cnt != rss->queue_num) + return -EINVAL; + + for (i = 0; i < rss->queue_num; i++) { + if (!bp->rx_queues[rss->queue[i]]->vnic->rx_queue_cnt && + !bp->rx_queues[rss->queue[i]]->rx_started) + return -EINVAL; + } + + for (i = 0; i < vnic->rx_queue_cnt; i++) { + int j; + + for (j = 0; j < vnic->rx_queue_cnt; j++) { + if (bp->grp_info[rss->queue[i]].fw_grp_id == + vnic->fw_grp_ids[j]) + match++; + } + } + + if (match != vnic->rx_queue_cnt) { + PMD_DRV_LOG(ERR, + "VNIC queue count %d vs queues matched %d\n", + match, vnic->rx_queue_cnt); + return -EINVAL; + } + + return 0; +} + +static void +bnxt_update_filter_flags_en(struct bnxt_filter_info *filter, + struct bnxt_filter_info *filter1) +{ + if (!(filter->valid_flags & + ~(BNXT_FLOW_L2_DST_VALID_FLAG | + BNXT_FLOW_L2_SRC_VALID_FLAG | + BNXT_FLOW_L2_INNER_SRC_VALID_FLAG | + BNXT_FLOW_L2_INNER_DST_VALID_FLAG))) { + filter->flags = filter1->flags; + filter->enables = filter1->enables; + filter->filter_type = HWRM_CFA_L2_FILTER; + memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN); + filter->pri_hint = filter1->pri_hint; + filter->l2_filter_id_hint = filter1->l2_filter_id_hint; + } + filter->fw_l2_filter_id = filter1->fw_l2_filter_id; +} + static int bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, const struct rte_flow_item pattern[], @@ -842,12 +896,14 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, struct bnxt *bp = dev->data->dev_private; struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; const struct rte_flow_action_queue *act_q; + const struct rte_flow_action_rss *rss; const struct rte_flow_action_vf *act_vf; struct bnxt_vnic_info *vnic, *vnic0; struct bnxt_filter_info *filter1; struct bnxt_rx_queue *rxq = NULL; int dflt_vnic, vnic_id; - uint32_t vf = 0; + unsigned int rss_idx; + uint32_t vf = 0, i; int rc; rc = @@ -916,10 +972,13 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS) && rxq) goto use_vnic; + //if (!rxq || + //bp->vnic_info[0].fw_grp_ids[act_q->index] != + //INVALID_HW_RING_ID || + //!rxq->rx_deferred_start) { if (!rxq || bp->vnic_info[0].fw_grp_ids[act_q->index] != - INVALID_HW_RING_ID || - !rxq->rx_deferred_start) { + INVALID_HW_RING_ID) { PMD_DRV_LOG(ERR, "Queue invalid or used with other VNIC\n"); rte_flow_error_set(error, @@ -931,8 +990,8 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, goto ret; } -use_vnic: rxq->vnic = vnic; + rxq->rx_started = 1; vnic->rx_queue_cnt++; vnic->start_grp_id = act_q->index; vnic->end_grp_id = act_q->index; @@ -948,6 +1007,7 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, "vnic[%d] = %p vnic->fw_grp_ids = %p\n", act_q->index, vnic, vnic->fw_grp_ids); +use_vnic: vnic->ff_pool_idx = vnic_id; PMD_DRV_LOG(DEBUG, "Setting vnic ff_idx %d\n", vnic->ff_pool_idx); @@ -958,20 +1018,8 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, goto ret; } - if (!(filter->valid_flags & - ~(BNXT_FLOW_L2_DST_VALID_FLAG | - BNXT_FLOW_L2_SRC_VALID_FLAG | - BNXT_FLOW_L2_INNER_SRC_VALID_FLAG | - BNXT_FLOW_L2_INNER_DST_VALID_FLAG))) { - PMD_DRV_LOG(DEBUG, "L2 filter created\n"); - filter->flags = filter1->flags; - filter->enables = filter1->enables; - filter->filter_type = HWRM_CFA_L2_FILTER; - memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN); - filter->pri_hint = filter1->pri_hint; - filter->l2_filter_id_hint = filter1->l2_filter_id_hint; - } - filter->fw_l2_filter_id = filter1->fw_l2_filter_id; + PMD_DRV_LOG(DEBUG, "L2 filter created\n"); + bnxt_update_filter_flags_en(filter, filter1); break; case RTE_FLOW_ACTION_TYPE_DROP: vnic0 = &bp->vnic_info[0]; @@ -1063,15 +1111,158 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, filter->fw_l2_filter_id = filter1->fw_l2_filter_id; break; case RTE_FLOW_ACTION_TYPE_RSS: - rte_flow_error_set(error, - ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, - act, - "This action is not supported right now."); - rc = -rte_errno; - goto ret; - //break; + rss = (const struct rte_flow_action_rss *)act->conf; + + vnic_id = attr->group; + if (!vnic_id) { + PMD_DRV_LOG(ERR, "Group id cannot be 0\n"); + rte_flow_error_set(error, + EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, + NULL, + "Group id cannot be 0"); + rc = -rte_errno; + goto ret; + } + + vnic = &bp->vnic_info[vnic_id]; + if (vnic == NULL) { + rte_flow_error_set(error, + EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + act, + "No matching VNIC for RSS group."); + rc = -rte_errno; + goto ret; + } + PMD_DRV_LOG(DEBUG, "VNIC found\n"); + + /* Check if requested RSS config matches RSS config of VNIC + * only if it is not a fresh VNIC configuration. + * Otherwise the existing VNIC configuration can be used. + */ + if (vnic->rx_queue_cnt) { + rc = match_vnic_rss_cfg(bp, vnic, rss); + if (rc) { + PMD_DRV_LOG(ERR, + "VNIC and RSS config mismatch\n"); + rte_flow_error_set(error, + EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + act, + "VNIC and RSS cfg mismatch"); + rc = -rte_errno; + goto ret; + } + goto vnic_found; + } + + for (i = 0; i < rss->queue_num; i++) { + PMD_DRV_LOG(DEBUG, "RSS action Queue %d\n", + rss->queue[i]); + + if (!rss->queue[i] || + rss->queue[i] >= bp->rx_nr_rings || + !bp->rx_queues[rss->queue[i]]) { + rte_flow_error_set(error, + EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + act, + "Invalid queue ID for RSS"); + rc = -rte_errno; + goto ret; + } + rxq = bp->rx_queues[rss->queue[i]]; + //if (bp->vnic_info[0].fw_grp_ids[rss->queue[i]] != + //INVALID_HW_RING_ID || + //!rxq->rx_deferred_start) { + if (bp->vnic_info[0].fw_grp_ids[rss->queue[i]] != + INVALID_HW_RING_ID) { + PMD_DRV_LOG(ERR, + "queue active with other VNIC\n"); + rte_flow_error_set(error, + EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + act, + "Invalid queue ID for RSS"); + rc = -rte_errno; + goto ret; + } + + rxq->vnic = vnic; + rxq->rx_started = 1; + vnic->rx_queue_cnt++; + } + + vnic->start_grp_id = rss->queue[0]; + vnic->end_grp_id = rss->queue[rss->queue_num - 1]; + vnic->func_default = 0; //This is not a default VNIC. + + rc = bnxt_vnic_prep(bp, vnic); + if (rc) + goto ret; + + PMD_DRV_LOG(DEBUG, + "vnic[%d] = %p vnic->fw_grp_ids = %p\n", + vnic_id, vnic, vnic->fw_grp_ids); + + vnic->ff_pool_idx = vnic_id; + PMD_DRV_LOG(DEBUG, + "Setting vnic ff_pool_idx %d\n", vnic->ff_pool_idx); + + /* This can be done only after vnic_grp_alloc is done. */ + for (i = 0; i < vnic->rx_queue_cnt; i++) { + vnic->fw_grp_ids[i] = + bp->grp_info[rss->queue[i]].fw_grp_id; + /* Make sure vnic0 does not use these rings. */ + bp->vnic_info[0].fw_grp_ids[rss->queue[i]] = + INVALID_HW_RING_ID; + } + + for (rss_idx = 0; rss_idx < HW_HASH_INDEX_SIZE; ) { + for (i = 0; i < vnic->rx_queue_cnt; i++) + vnic->rss_table[rss_idx++] = + vnic->fw_grp_ids[i]; + } + + /* Configure RSS only if the queue count is > 1 */ + if (vnic->rx_queue_cnt > 1) { + vnic->hash_type = + bnxt_rte_to_hwrm_hash_types(rss->types); + + if (!rss->key_len) { + /* If hash key has not been specified, + * use random hash key. + */ + prandom_bytes(vnic->rss_hash_key, + HW_HASH_KEY_SIZE); + } else { + if (rss->key_len > HW_HASH_KEY_SIZE) + memcpy(vnic->rss_hash_key, + rss->key, + HW_HASH_KEY_SIZE); + else + memcpy(vnic->rss_hash_key, + rss->key, + rss->key_len); + } + bnxt_hwrm_vnic_rss_cfg(bp, vnic); + } else { + PMD_DRV_LOG(DEBUG, "No RSS config required\n"); + } + +vnic_found: + filter->dst_id = vnic->fw_vnic_id; + filter1 = bnxt_get_l2_filter(bp, filter, vnic); + if (filter1 == NULL) { + rc = -ENOSPC; + goto ret; + } + + PMD_DRV_LOG(DEBUG, "L2 filter created\n"); + bnxt_update_filter_flags_en(filter, filter1); + break; default: rte_flow_error_set(error, EINVAL, diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c index 4f3f9b359..2f0ed1026 100644 --- a/drivers/net/bnxt/bnxt_vnic.c +++ b/drivers/net/bnxt/bnxt_vnic.c @@ -16,7 +16,7 @@ * VNIC Functions */ -static void prandom_bytes(void *dest_ptr, size_t len) +void prandom_bytes(void *dest_ptr, size_t len) { char *dest = (char *)dest_ptr; uint64_t rb; diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h index ec3a3ff51..de34b21eb 100644 --- a/drivers/net/bnxt/bnxt_vnic.h +++ b/drivers/net/bnxt/bnxt_vnic.h @@ -67,5 +67,6 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp); void bnxt_free_vnic_mem(struct bnxt *bp); int bnxt_alloc_vnic_mem(struct bnxt *bp); int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic); +void prandom_bytes(void *dest_ptr, size_t len); uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type); #endif