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 421DCA0562; Fri, 3 Apr 2020 10:53:15 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id AA8AB1C136; Fri, 3 Apr 2020 10:52:43 +0200 (CEST) Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by dpdk.org (Postfix) with ESMTP id 0BDB61C134 for ; Fri, 3 Apr 2020 10:52:42 +0200 (CEST) Received: by mail-pf1-f195.google.com with SMTP id c21so3181294pfo.5 for ; Fri, 03 Apr 2020 01:52:41 -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=Up+S8uYp6uw/FWWngY7M7hkqNHw0XtZuIs/bQHvNz+U=; b=oenY1wXHeix4Sr9rkqLAGZr49DZckm3L7RGr7wtwSjdJMiVynFmaAzWMNhrClvgzG5 0IqdKVx1EeURp+kMTpOEU++Sqnub/avNHvVKfSkDq8johPL65Puvrwz13ghR7nib/UXF PTIi+VdaXVpnQU5O11N5xFDlL6AOW9n7Nq/VolF3jVi3FOInCAxxQ1Lj7hNrU/8JDcRb UJEYP/ixfqYrX/FpUNqO3OfIK640EaqeJ/rkLnGBZljxGuWywJoNX9DU1xJjj8BDgJDs KYHhk51K8IxkMJsHnFJMS5ry27B9Iyxm7E7w32qCeumpQGQKMgcDUwuQqBsmLNx/JbR7 518A== 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=Up+S8uYp6uw/FWWngY7M7hkqNHw0XtZuIs/bQHvNz+U=; b=ZwIfWCoDmaXf8MQT109quTjrgPXRaEeCskcCQ0A+cWUPP2y1m5Kdedm6lUPt+ya96E bN1XrRF3bzLIZbQaMTfSoqkA4NxrM529iNDq9mRVweKPvd4+eGKtSIYT+uUImDgJkxoc tbEzxdHEpgcz5AZ1UZs/C1i1R1MY4d4jJJJizJ7zmPNKGu/RYAlN3QtM6C+9hKSeMDOD cI2TVMIJUj8q2mynPYMel3VjAw6R0Aj4va4bVyjIsTH1WE/97YI5er9ClESfDx2pIPf2 NUXTowYVKWZFn3IJlel2EUM0KOUCUyMi9GjUv7Fg3jTYXOmEYjByA9vfjg7X4vjHq0Bt GxNQ== X-Gm-Message-State: AGi0PuYkrDvdb4rWz6OqiwB3kCmWO04Qo2t/+1YJbB5lsYIO5aQLcuQz WB5qpa2j+h9gPA/L504GkSfz+L43ldOvYw== X-Google-Smtp-Source: APiQypJbND0Lwst6Hmng6mNwHgkJBJCmkL61bPJes4JlOl6cY1fZp4e6XBv46hW902LFkkNo/EQK6A== X-Received: by 2002:a62:778d:: with SMTP id s135mr7761332pfc.21.1585903961184; Fri, 03 Apr 2020 01:52:41 -0700 (PDT) Received: from hyd1588t430.marvell.com ([115.113.156.2]) by smtp.gmail.com with ESMTPSA id s9sm5267899pjr.5.2020.04.03.01.52.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Apr 2020 01:52:40 -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 14:22:09 +0530 Message-Id: <20200403085216.32684-5-nithind1988@gmail.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20200403085216.32684-1-nithind1988@gmail.com> References: <20200312111907.31555-1-ndabilpuram@marvell.com> <20200403085216.32684-1-nithind1988@gmail.com> Subject: [dpdk-dev] [PATCH v3 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 d1a4529..3e2ace6 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