From: Satha Rao <[email protected]> Create a new default tree for the SDP interface if more than one TX queue is requested. This helps to backpressure each queue independently when they are created with separate channels.
Signed-off-by: Satha Rao <[email protected]> --- v5: - Rebase to ToT v4: - Further split patch 19/19 to 5 patches. v3: - Fixed usage of rte_atomic in common/cnxk folder. v2: - Handled comments related to commit messages - Fixed typo drivers/common/cnxk/roc_nix.h | 2 + drivers/common/cnxk/roc_nix_priv.h | 2 + drivers/common/cnxk/roc_nix_tm.c | 158 ++++++++++++++++++ drivers/common/cnxk/roc_nix_tm_ops.c | 5 +- drivers/common/cnxk/roc_nix_tm_utils.c | 2 +- .../common/cnxk/roc_platform_base_symbols.c | 1 + 6 files changed, 168 insertions(+), 2 deletions(-) diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h index a62ddf4732..f4b9236486 100644 --- a/drivers/common/cnxk/roc_nix.h +++ b/drivers/common/cnxk/roc_nix.h @@ -689,6 +689,7 @@ enum roc_nix_tm_tree { ROC_NIX_TM_DEFAULT = 0, ROC_NIX_TM_RLIMIT, ROC_NIX_TM_PFC, + ROC_NIX_TM_SDP, ROC_NIX_TM_USER, ROC_NIX_TM_TREE_MAX, }; @@ -861,6 +862,7 @@ int __roc_api roc_nix_tm_lvl_cnt_get(struct roc_nix *roc_nix); int __roc_api roc_nix_tm_lvl_have_link_access(struct roc_nix *roc_nix, int lvl); int __roc_api roc_nix_tm_prepare_rate_limited_tree(struct roc_nix *roc_nix); int __roc_api roc_nix_tm_pfc_prepare_tree(struct roc_nix *roc_nix); +int __roc_api roc_nix_tm_sdp_prepare_tree(struct roc_nix *roc_nix); bool __roc_api roc_nix_tm_is_user_hierarchy_enabled(struct roc_nix *nix); int __roc_api roc_nix_tm_tree_type_get(struct roc_nix *nix); int __roc_api roc_nix_tm_mark_config(struct roc_nix *roc_nix, diff --git a/drivers/common/cnxk/roc_nix_priv.h b/drivers/common/cnxk/roc_nix_priv.h index c949621196..f1fcee2acb 100644 --- a/drivers/common/cnxk/roc_nix_priv.h +++ b/drivers/common/cnxk/roc_nix_priv.h @@ -389,6 +389,8 @@ nix_tm_tree2str(enum roc_nix_tm_tree tree) return "Rate Limit Tree"; else if (tree == ROC_NIX_TM_PFC) return "PFC Tree"; + else if (tree == ROC_NIX_TM_SDP) + return "SDP Tree"; else if (tree == ROC_NIX_TM_USER) return "User Tree"; return "???"; diff --git a/drivers/common/cnxk/roc_nix_tm.c b/drivers/common/cnxk/roc_nix_tm.c index abfe80978b..2771fd8fc4 100644 --- a/drivers/common/cnxk/roc_nix_tm.c +++ b/drivers/common/cnxk/roc_nix_tm.c @@ -1890,6 +1890,164 @@ roc_nix_tm_pfc_prepare_tree(struct roc_nix *roc_nix) return rc; } +int +roc_nix_tm_sdp_prepare_tree(struct roc_nix *roc_nix) +{ + struct nix *nix = roc_nix_to_nix_priv(roc_nix); + uint32_t nonleaf_id = nix->nb_tx_queues; + uint32_t tl2_node_id, tl3_node_id; + uint8_t leaf_lvl, lvl, lvl_start; + struct nix_tm_node *node = NULL; + uint32_t parent, i; + int rc = -ENOMEM; + + parent = ROC_NIX_TM_NODE_ID_INVALID; + leaf_lvl = (nix_tm_have_tl1_access(nix) ? ROC_TM_LVL_QUEUE : ROC_TM_LVL_SCH4); + + /* TL1 node */ + node = nix_tm_node_alloc(); + if (!node) + goto error; + + node->id = nonleaf_id; + node->parent_id = parent; + node->priority = 0; + node->weight = NIX_TM_DFLT_RR_WT; + node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE; + node->lvl = ROC_TM_LVL_ROOT; + node->tree = ROC_NIX_TM_SDP; + node->rel_chan = NIX_TM_CHAN_INVALID; + + rc = nix_tm_node_add(roc_nix, node); + if (rc) + goto error; + + parent = nonleaf_id; + nonleaf_id++; + + lvl_start = ROC_TM_LVL_SCH1; + if (roc_nix_is_pf(roc_nix)) { + /* TL2 node */ + rc = -ENOMEM; + node = nix_tm_node_alloc(); + if (!node) + goto error; + + node->id = nonleaf_id; + node->parent_id = parent; + node->priority = 0; + node->weight = NIX_TM_DFLT_RR_WT; + node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE; + node->lvl = ROC_TM_LVL_SCH1; + node->tree = ROC_NIX_TM_SDP; + node->rel_chan = NIX_TM_CHAN_INVALID; + + rc = nix_tm_node_add(roc_nix, node); + if (rc) + goto error; + + lvl_start = ROC_TM_LVL_SCH2; + tl2_node_id = nonleaf_id; + nonleaf_id++; + } else { + tl2_node_id = parent; + } + + /* Allocate TL3 node */ + rc = -ENOMEM; + node = nix_tm_node_alloc(); + if (!node) + goto error; + + node->id = nonleaf_id; + node->parent_id = tl2_node_id; + node->priority = 0; + node->weight = NIX_TM_DFLT_RR_WT; + node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE; + node->lvl = lvl_start; + node->tree = ROC_NIX_TM_SDP; + node->rel_chan = NIX_TM_CHAN_INVALID; + + rc = nix_tm_node_add(roc_nix, node); + if (rc) + goto error; + + tl3_node_id = nonleaf_id; + nonleaf_id++; + lvl_start++; + + for (i = 0; i < nix->nb_tx_queues; i++) { + parent = tl3_node_id; + rc = -ENOMEM; + node = nix_tm_node_alloc(); + if (!node) + goto error; + + node->id = nonleaf_id; + node->parent_id = parent; + node->priority = 0; + node->weight = NIX_TM_DFLT_RR_WT; + node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE; + node->lvl = lvl_start; + node->tree = ROC_NIX_TM_SDP; + /* For SDP, if BP enabled use channel to PAUSE the corresponding queue */ + node->rel_chan = (i % nix->tx_chan_cnt); + + rc = nix_tm_node_add(roc_nix, node); + if (rc) + goto error; + + parent = nonleaf_id; + nonleaf_id++; + + lvl = (nix_tm_have_tl1_access(nix) ? ROC_TM_LVL_SCH4 : ROC_TM_LVL_SCH3); + + rc = -ENOMEM; + node = nix_tm_node_alloc(); + if (!node) + goto error; + + node->id = nonleaf_id; + node->parent_id = parent; + node->priority = 0; + node->weight = NIX_TM_DFLT_RR_WT; + node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE; + node->lvl = lvl; + node->tree = ROC_NIX_TM_SDP; + node->rel_chan = NIX_TM_CHAN_INVALID; + + rc = nix_tm_node_add(roc_nix, node); + if (rc) + goto error; + + parent = nonleaf_id; + nonleaf_id++; + + rc = -ENOMEM; + node = nix_tm_node_alloc(); + if (!node) + goto error; + + node->id = i; + node->parent_id = parent; + node->priority = 0; + node->weight = NIX_TM_DFLT_RR_WT; + node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE; + node->lvl = leaf_lvl; + node->tree = ROC_NIX_TM_SDP; + node->rel_chan = NIX_TM_CHAN_INVALID; + + rc = nix_tm_node_add(roc_nix, node); + if (rc) + goto error; + } + + return 0; +error: + nix_tm_node_free(node); + return rc; +} + int nix_tm_free_resources(struct roc_nix *roc_nix, uint32_t tree_mask, bool hw_only) { diff --git a/drivers/common/cnxk/roc_nix_tm_ops.c b/drivers/common/cnxk/roc_nix_tm_ops.c index b89f08ac66..951c310a56 100644 --- a/drivers/common/cnxk/roc_nix_tm_ops.c +++ b/drivers/common/cnxk/roc_nix_tm_ops.c @@ -1035,7 +1035,10 @@ roc_nix_tm_init(struct roc_nix *roc_nix) } /* Prepare default tree */ - rc = nix_tm_prepare_default_tree(roc_nix); + if (roc_nix_is_sdp(roc_nix) && (nix->nb_tx_queues > 1)) + rc = roc_nix_tm_sdp_prepare_tree(roc_nix); + else + rc = nix_tm_prepare_default_tree(roc_nix); if (rc) { plt_err("failed to prepare default tm tree, rc=%d", rc); return rc; diff --git a/drivers/common/cnxk/roc_nix_tm_utils.c b/drivers/common/cnxk/roc_nix_tm_utils.c index 4a09cc2aae..eaf6f9e4c7 100644 --- a/drivers/common/cnxk/roc_nix_tm_utils.c +++ b/drivers/common/cnxk/roc_nix_tm_utils.c @@ -582,7 +582,7 @@ nix_tm_topology_reg_prep(struct nix *nix, struct nix_tm_node *node, /* Configure TL4 to send to SDP channel instead of CGX/LBK */ if (nix->sdp_link) { - relchan = nix->tx_chan_base & 0xff; + relchan = (nix->tx_chan_base & 0xff) + node->rel_chan; plt_tm_dbg("relchan=%u schq=%u tx_chan_cnt=%u", relchan, schq, nix->tx_chan_cnt); reg[k] = NIX_AF_TL4X_SDP_LINK_CFG(schq); diff --git a/drivers/common/cnxk/roc_platform_base_symbols.c b/drivers/common/cnxk/roc_platform_base_symbols.c index ff64e82914..40d5cd290b 100644 --- a/drivers/common/cnxk/roc_platform_base_symbols.c +++ b/drivers/common/cnxk/roc_platform_base_symbols.c @@ -223,6 +223,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_rq_dump) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_cq_dump) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_sq_dump) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_tm_dump) +RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_tm_sdp_prepare_tree) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_dump) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_inl_dev_dump) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_inl_outb_cpt_lfs_dump) -- 2.34.1

