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 A44C4A0562; Thu, 2 Apr 2020 21:35:53 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D2F661BFDC; Thu, 2 Apr 2020 21:35:23 +0200 (CEST) Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by dpdk.org (Postfix) with ESMTP id A5C6E1BFD1 for ; Thu, 2 Apr 2020 21:35:22 +0200 (CEST) Received: by mail-pg1-f196.google.com with SMTP id b1so2303443pgm.8 for ; Thu, 02 Apr 2020 12:35:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=NdVu1uylhE5tWcxpg3g9hMpWUHWl4JcCwOLlAcfUniE=; b=i+4/UhJJF3flNqxfGZ/R/+jJE3Ez/NzLY0Q0FLFsmNFAZYQs6LKZdnLGH2vlYSF62G h4U9YNV4ZrjoIF+YBRbRDQTurowwE+LKIAuNhtlomlHOA+QxUBefHdhI897B2I3kJHqn p82F247CBRxnLoouIX1s+HK9ldstRiKEp5wR1ln+Z04o766BtVtHQmCHTruZ0mQ9nQqD i+eMGqy/PiuE4Y2uswyAmD3+h/H2MI/zxuRBrJvMCuNMdrLGWDtHUVA8eaLrWcBqbWVA z4/7O8Gb4OdjXlpVbCYJLmDP4WXyjvNq3m9TwCcPZDFoaIDBFCs7hRmdE8KYiptzReTX ndgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=NdVu1uylhE5tWcxpg3g9hMpWUHWl4JcCwOLlAcfUniE=; b=DDsFUrU88pTnePk/abNfkAQGuN9OlB6foAYwLCP3moZmD0jgp9+6M6dy2nL3i8t7Ek 8sFAUp7AxPJvYNm9iR8stq5FIIhEHeuG/h49Ud/t2bs8tqkK8c+P8sfiasyAMp48tHFp NLLfNBYHAv9B4isynjpzYjODIRJAHhJzt8BL9B2k9BZQX8cfPpm5lSS5VlCVAP4eVQGK Nc61/uhrX5k3UGHpJeTJ6+wlDLOuNMqghiAPbsGPm2B0qW9/JXwikzFBSdSoyPZ+IWmn WVObEWvIyArZpEvvLjX61ApjmJkYQS613hTSkGIT1QbNcOYczMSgV+pEv1C4P7UAJ7MR 3bPA== X-Gm-Message-State: AGi0PubFlI4/M9xYXMJurTH8ytAXpnlfU0kr4nIOgAdyw8l84/N8A3vA QorfAHcPFfVdPa8djrxcUOYGhbfFc5Fhyg== X-Google-Smtp-Source: APiQypL4a/Xs82Ra9GR1VlUCsstmUGOtWAl5ae1y+lCCBa/N8hw/TjrIUmIZIvo8TgbFrFWjwuuf3A== X-Received: by 2002:aa7:9588:: with SMTP id z8mr4460835pfj.240.1585856121759; Thu, 02 Apr 2020 12:35:21 -0700 (PDT) Received: from hyd1588t430.marvell.com ([115.113.156.2]) by smtp.gmail.com with ESMTPSA id k70sm3898259pga.91.2020.04.02.12.35.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Apr 2020 12:35:21 -0700 (PDT) From: Nithin Dabilpuram To: Jerin Jacob , Nithin Dabilpuram , Kiran Kumar K Cc: dev@dpdk.org, kkanas@marvell.com Date: Fri, 3 Apr 2020 01:04:46 +0530 Message-Id: <20200402193453.17266-5-nithind1988@gmail.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20200402193453.17266-1-nithind1988@gmail.com> References: <20200312111907.31555-1-ndabilpuram@marvell.com> <20200402193453.17266-1-nithind1988@gmail.com> Subject: [dpdk-dev] [PATCH v2 04/11] net/octeontx2: add tm node add and delete cb 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: Nithin Dabilpuram Adds support to Traffic Management callbacks "node_add" and "node_delete". These callbacks doesn't support dynamic node addition or deletion post hierarchy commit. Signed-off-by: Nithin Dabilpuram Signed-off-by: Krzysztof Kanas --- drivers/net/octeontx2/otx2_tm.c | 271 ++++++++++++++++++++++++++++++++++++++++ drivers/net/octeontx2/otx2_tm.h | 2 + 2 files changed, 273 insertions(+) diff --git a/drivers/net/octeontx2/otx2_tm.c b/drivers/net/octeontx2/otx2_tm.c index 01b327b..bbd8e19 100644 --- a/drivers/net/octeontx2/otx2_tm.c +++ b/drivers/net/octeontx2/otx2_tm.c @@ -1540,6 +1540,277 @@ nix_tm_alloc_resources(struct rte_eth_dev *eth_dev, bool xmit_enable) return 0; } +static uint16_t +nix_tm_lvl2nix(struct otx2_eth_dev *dev, uint32_t lvl) +{ + if (nix_tm_have_tl1_access(dev)) { + switch (lvl) { + case OTX2_TM_LVL_ROOT: + return NIX_TXSCH_LVL_TL1; + case OTX2_TM_LVL_SCH1: + return NIX_TXSCH_LVL_TL2; + case OTX2_TM_LVL_SCH2: + return NIX_TXSCH_LVL_TL3; + case OTX2_TM_LVL_SCH3: + return NIX_TXSCH_LVL_TL4; + case OTX2_TM_LVL_SCH4: + return NIX_TXSCH_LVL_SMQ; + default: + return NIX_TXSCH_LVL_CNT; + } + } else { + switch (lvl) { + case OTX2_TM_LVL_ROOT: + return NIX_TXSCH_LVL_TL2; + case OTX2_TM_LVL_SCH1: + return NIX_TXSCH_LVL_TL3; + case OTX2_TM_LVL_SCH2: + return NIX_TXSCH_LVL_TL4; + case OTX2_TM_LVL_SCH3: + return NIX_TXSCH_LVL_SMQ; + default: + return NIX_TXSCH_LVL_CNT; + } + } +} + +static uint16_t +nix_max_prio(struct otx2_eth_dev *dev, uint16_t hw_lvl) +{ + if (hw_lvl >= NIX_TXSCH_LVL_CNT) + return 0; + + /* MDQ doesn't support SP */ + if (hw_lvl == NIX_TXSCH_LVL_MDQ) + return 0; + + /* PF's TL1 with VF's enabled doesn't support SP */ + if (hw_lvl == NIX_TXSCH_LVL_TL1 && + (dev->otx2_tm_root_lvl == NIX_TXSCH_LVL_TL2 || + (dev->tm_flags & NIX_TM_TL1_NO_SP))) + return 0; + + return TXSCH_TLX_SP_PRIO_MAX - 1; +} + + +static int +validate_prio(struct otx2_eth_dev *dev, uint32_t lvl, + uint32_t parent_id, uint32_t priority, + struct rte_tm_error *error) +{ + uint8_t priorities[TXSCH_TLX_SP_PRIO_MAX]; + struct otx2_nix_tm_node *tm_node; + uint32_t rr_num = 0; + int i; + + /* Validate priority against max */ + if (priority > nix_max_prio(dev, nix_tm_lvl2nix(dev, lvl - 1))) { + error->type = RTE_TM_ERROR_TYPE_CAPABILITIES; + error->message = "unsupported priority value"; + return -EINVAL; + } + + if (parent_id == RTE_TM_NODE_ID_NULL) + return 0; + + memset(priorities, 0, TXSCH_TLX_SP_PRIO_MAX); + priorities[priority] = 1; + + TAILQ_FOREACH(tm_node, &dev->node_list, node) { + if (!tm_node->parent) + continue; + + if (!(tm_node->flags & NIX_TM_NODE_USER)) + continue; + + if (tm_node->parent->id != parent_id) + continue; + + priorities[tm_node->priority]++; + } + + for (i = 0; i < TXSCH_TLX_SP_PRIO_MAX; i++) + if (priorities[i] > 1) + rr_num++; + + /* At max, one rr groups per parent */ + if (rr_num > 1) { + error->type = RTE_TM_ERROR_TYPE_NODE_PRIORITY; + error->message = "multiple DWRR node priority"; + return -EINVAL; + } + + /* Check for previous priority to avoid holes in priorities */ + if (priority && !priorities[priority - 1]) { + error->type = RTE_TM_ERROR_TYPE_NODE_PRIORITY; + error->message = "priority not in order"; + return -EINVAL; + } + + return 0; +} + +static int +otx2_nix_tm_node_add(struct rte_eth_dev *eth_dev, uint32_t node_id, + uint32_t parent_node_id, uint32_t priority, + uint32_t weight, uint32_t lvl, + struct rte_tm_node_params *params, + struct rte_tm_error *error) +{ + struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); + struct otx2_nix_tm_node *parent_node; + int rc, clear_on_fail = 0; + uint32_t exp_next_lvl; + uint16_t hw_lvl; + + /* we don't support dynamic updates */ + if (dev->tm_flags & NIX_TM_COMMITTED) { + error->type = RTE_TM_ERROR_TYPE_CAPABILITIES; + error->message = "dynamic update not supported"; + return -EIO; + } + + /* Leaf nodes have to be same priority */ + if (nix_tm_is_leaf(dev, lvl) && priority != 0) { + error->type = RTE_TM_ERROR_TYPE_CAPABILITIES; + error->message = "queue shapers must be priority 0"; + return -EIO; + } + + parent_node = nix_tm_node_search(dev, parent_node_id, true); + + /* find the right level */ + if (lvl == RTE_TM_NODE_LEVEL_ID_ANY) { + if (parent_node_id == RTE_TM_NODE_ID_NULL) { + lvl = OTX2_TM_LVL_ROOT; + } else if (parent_node) { + lvl = parent_node->lvl + 1; + } else { + /* Neigher proper parent nor proper level id given */ + error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID; + error->message = "invalid parent node id"; + return -ERANGE; + } + } + + /* Translate rte_tm level id's to nix hw level id's */ + hw_lvl = nix_tm_lvl2nix(dev, lvl); + if (hw_lvl == NIX_TXSCH_LVL_CNT && + !nix_tm_is_leaf(dev, lvl)) { + error->type = RTE_TM_ERROR_TYPE_LEVEL_ID; + error->message = "invalid level id"; + return -ERANGE; + } + + if (node_id < dev->tm_leaf_cnt) + exp_next_lvl = NIX_TXSCH_LVL_SMQ; + else + exp_next_lvl = hw_lvl + 1; + + /* Check if there is no parent node yet */ + if (hw_lvl != dev->otx2_tm_root_lvl && + (!parent_node || parent_node->hw_lvl != exp_next_lvl)) { + error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID; + error->message = "invalid parent node id"; + return -EINVAL; + } + + /* Check if a node already exists */ + if (nix_tm_node_search(dev, node_id, true)) { + error->type = RTE_TM_ERROR_TYPE_NODE_ID; + error->message = "node already exists"; + return -EINVAL; + } + + /* Check if shaper profile exists for non leaf node */ + if (!nix_tm_is_leaf(dev, lvl) && + params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE && + !nix_tm_shaper_profile_search(dev, params->shaper_profile_id)) { + error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID; + error->message = "invalid shaper profile"; + return -EINVAL; + } + + /* Check if there is second DWRR already in siblings or holes in prio */ + if (validate_prio(dev, lvl, parent_node_id, priority, error)) + return -EINVAL; + + if (weight > MAX_SCHED_WEIGHT) { + error->type = RTE_TM_ERROR_TYPE_NODE_WEIGHT; + error->message = "max weight exceeded"; + return -EINVAL; + } + + rc = nix_tm_node_add_to_list(dev, node_id, parent_node_id, + priority, weight, hw_lvl, + lvl, true, params); + if (rc) { + error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED; + /* cleanup user added nodes */ + if (clear_on_fail) + nix_tm_free_resources(dev, NIX_TM_NODE_USER, + NIX_TM_NODE_USER, false); + error->message = "failed to add node"; + return rc; + } + error->type = RTE_TM_ERROR_TYPE_NONE; + return 0; +} + +static int +otx2_nix_tm_node_delete(struct rte_eth_dev *eth_dev, uint32_t node_id, + struct rte_tm_error *error) +{ + struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); + struct otx2_nix_tm_node *tm_node, *child_node; + struct otx2_nix_tm_shaper_profile *profile; + uint32_t profile_id; + + /* we don't support dynamic updates yet */ + if (dev->tm_flags & NIX_TM_COMMITTED) { + error->type = RTE_TM_ERROR_TYPE_CAPABILITIES; + error->message = "hierarchy exists"; + return -EIO; + } + + if (node_id == RTE_TM_NODE_ID_NULL) { + error->type = RTE_TM_ERROR_TYPE_NODE_ID; + error->message = "invalid node id"; + return -EINVAL; + } + + tm_node = nix_tm_node_search(dev, node_id, true); + if (!tm_node) { + error->type = RTE_TM_ERROR_TYPE_NODE_ID; + error->message = "no such node"; + return -EINVAL; + } + + /* Check for any existing children */ + TAILQ_FOREACH(child_node, &dev->node_list, node) { + if (child_node->parent == tm_node) { + error->type = RTE_TM_ERROR_TYPE_NODE_ID; + error->message = "children exist"; + return -EINVAL; + } + } + + /* Remove shaper profile reference */ + profile_id = tm_node->params.shaper_profile_id; + profile = nix_tm_shaper_profile_search(dev, profile_id); + profile->reference_count--; + + TAILQ_REMOVE(&dev->node_list, tm_node, node); + rte_free(tm_node); + return 0; +} + +const struct rte_tm_ops otx2_tm_ops = { + .node_add = otx2_nix_tm_node_add, + .node_delete = otx2_nix_tm_node_delete, +}; + static int nix_tm_prepare_default_tree(struct rte_eth_dev *eth_dev) { diff --git a/drivers/net/octeontx2/otx2_tm.h b/drivers/net/octeontx2/otx2_tm.h index 413120a..ebb4e90 100644 --- a/drivers/net/octeontx2/otx2_tm.h +++ b/drivers/net/octeontx2/otx2_tm.h @@ -135,6 +135,8 @@ TAILQ_HEAD(otx2_nix_tm_shaper_profile_list, otx2_nix_tm_shaper_profile); #define TXSCH_TL1_DFLT_RR_QTM ((1 << 24) - 1) #define TXSCH_TL1_DFLT_RR_PRIO 1 +#define TXSCH_TLX_SP_PRIO_MAX 10 + static inline const char * nix_hwlvl2str(uint32_t hw_lvl) { -- 2.8.4