From patchwork Sat May 27 08:17:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenzhuo Lu X-Patchwork-Id: 24725 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id C1CBE56A1; Sat, 27 May 2017 10:17:47 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id D89CE2BA2 for ; Sat, 27 May 2017 10:17:32 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 May 2017 01:17:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,400,1491289200"; d="scan'208";a="92489184" Received: from dpdk26.sh.intel.com ([10.239.128.228]) by orsmga002.jf.intel.com with ESMTP; 27 May 2017 01:17:30 -0700 From: Wenzhuo Lu To: dev@dpdk.org Cc: jingjing.wu@intel.com, cristian.dumitrescu@intel.com, jasvinder.singh@intel.com, Wenzhuo Lu Date: Sat, 27 May 2017 16:17:40 +0800 Message-Id: <1495873075-49542-6-git-send-email-wenzhuo.lu@intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1495873075-49542-1-git-send-email-wenzhuo.lu@intel.com> References: <1495873075-49542-1-git-send-email-wenzhuo.lu@intel.com> Subject: [dpdk-dev] [PATCH 05/20] net/i40e: support adding TM node 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 the support of the Traffic Management API, rte_tm_node_add. Signed-off-by: Wenzhuo Lu --- drivers/net/i40e/i40e_ethdev.h | 28 ++++++ drivers/net/i40e/i40e_tm.c | 223 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+) diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index da73d64..34ba3e5 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -636,9 +636,37 @@ struct i40e_tm_shaper_profile { TAILQ_HEAD(i40e_shaper_profile_list, i40e_tm_shaper_profile); +/* node type of Traffic Manager */ +enum i40e_tm_node_type { + I40E_TM_NODE_TYPE_PORT, + I40E_TM_NODE_TYPE_TC, + I40E_TM_NODE_TYPE_MAX, +}; + +/* Struct to store Traffic Manager node configuration. */ +struct i40e_tm_node { + TAILQ_ENTRY(i40e_tm_node) node; + uint32_t id; + uint32_t priority; + uint32_t weight; + uint32_t reference_count; + struct i40e_tm_node *parent; + struct i40e_tm_shaper_profile *shaper_profile; + struct rte_tm_node_params params; +}; + +TAILQ_HEAD(i40e_tm_node_list, i40e_tm_node); + /* Struct to store all the Traffic Manager configuration. */ struct i40e_tm_conf { struct i40e_shaper_profile_list shaper_profile_list; + struct i40e_tm_node *root; /* root node - port */ + struct i40e_tm_node_list tc_list; /* node list for all the TCs */ + /** + * The number of added TC nodes. + * It should be no more than the TC number of this port. + */ + uint32_t nb_tc_node; }; /* diff --git a/drivers/net/i40e/i40e_tm.c b/drivers/net/i40e/i40e_tm.c index 233adcf..6ebce77 100644 --- a/drivers/net/i40e/i40e_tm.c +++ b/drivers/net/i40e/i40e_tm.c @@ -46,11 +46,16 @@ static int i40e_shaper_profile_add(struct rte_eth_dev *dev, static int i40e_shaper_profile_del(struct rte_eth_dev *dev, uint32_t shaper_profile_id, struct rte_tm_error *error); +static int i40e_node_add(struct rte_eth_dev *dev, uint32_t node_id, + uint32_t parent_node_id, uint32_t priority, + uint32_t weight, struct rte_tm_node_params *params, + struct rte_tm_error *error); const struct rte_tm_ops i40e_tm_ops = { .capabilities_get = i40e_tm_capabilities_get, .shaper_profile_add = i40e_shaper_profile_add, .shaper_profile_delete = i40e_shaper_profile_del, + .node_add = i40e_node_add, }; int @@ -72,6 +77,11 @@ static int i40e_shaper_profile_del(struct rte_eth_dev *dev, /* initialize shaper profile list */ TAILQ_INIT(&pf->tm_conf.shaper_profile_list); + + /* initialize node configuration */ + pf->tm_conf.root = NULL; + TAILQ_INIT(&pf->tm_conf.tc_list); + pf->tm_conf.nb_tc_node = 0; } void @@ -79,6 +89,18 @@ static int i40e_shaper_profile_del(struct rte_eth_dev *dev, { struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); struct i40e_tm_shaper_profile *shaper_profile; + struct i40e_tm_node *tc; + + /* clear node configuration */ + while ((tc = TAILQ_FIRST(&pf->tm_conf.tc_list))) { + TAILQ_REMOVE(&pf->tm_conf.tc_list, tc, node); + rte_free(tc); + } + pf->tm_conf.nb_tc_node = 0; + if (pf->tm_conf.root) { + rte_free(pf->tm_conf.root); + pf->tm_conf.root = NULL; + } /* Remove all shaper profiles */ while ((shaper_profile = @@ -272,3 +294,204 @@ static int i40e_shaper_profile_del(struct rte_eth_dev *dev, return 0; } + +static inline struct i40e_tm_node * +i40e_tm_node_search(struct rte_eth_dev *dev, + uint32_t node_id, enum i40e_tm_node_type *node_type) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct i40e_tm_node_list *tc_list = &pf->tm_conf.tc_list; + struct i40e_tm_node *tm_node; + + if (pf->tm_conf.root && pf->tm_conf.root->id == node_id) { + *node_type = I40E_TM_NODE_TYPE_PORT; + return pf->tm_conf.root; + } + + TAILQ_FOREACH(tm_node, tc_list, node) { + if (tm_node->id == node_id) { + *node_type = I40E_TM_NODE_TYPE_TC; + return tm_node; + } + } + + return NULL; +} + +static int +i40e_node_add(struct rte_eth_dev *dev, uint32_t node_id, + uint32_t parent_node_id, uint32_t priority, + uint32_t weight, struct rte_tm_node_params *params, + struct rte_tm_error *error) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + enum i40e_tm_node_type node_type = I40E_TM_NODE_TYPE_MAX; + struct i40e_tm_shaper_profile *shaper_profile; + struct i40e_tm_node *tm_node; + uint16_t tc_nb = 0; + + if (!params || !error) + return -EINVAL; + + if (node_id == RTE_TM_NODE_ID_NULL) { + error->type = RTE_TM_ERROR_TYPE_NODE_ID; + error->message = "invalid node id"; + return -EINVAL; + } + + if (priority) { + error->type = RTE_TM_ERROR_TYPE_NODE_PRIORITY; + error->message = "priority not supported"; + return -EINVAL; + } + + if (weight) { + error->type = RTE_TM_ERROR_TYPE_NODE_WEIGHT; + error->message = "weight not supported"; + return -EINVAL; + } + + /* check if the node ID is already used */ + if (i40e_tm_node_search(dev, node_id, &node_type)) { + error->type = RTE_TM_ERROR_TYPE_NODE_ID; + error->message = "node id already used"; + return -EINVAL; + } + + /* check the shaper profile id */ + shaper_profile = i40e_shaper_profile_search(dev, + params->shaper_profile_id); + if (!shaper_profile) { + error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID; + error->message = "shaper profile not exist"; + return -EINVAL; + } + + /* not support shared shaper */ + if (params->shared_shaper_id) { + error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_SHAPER_ID; + error->message = "shared shaper not supported"; + return -EINVAL; + } + if (params->n_shared_shapers) { + error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS; + error->message = "shared shaper not supported"; + return -EINVAL; + } + + /* root node if not have a parent */ + if (parent_node_id == RTE_TM_NODE_ID_NULL) { + /* check the unsupported parameters */ + if (params->nonleaf.wfq_weight_mode) { + error->type = + RTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE; + error->message = "WFQ not supported"; + return -EINVAL; + } + if (params->nonleaf.n_sp_priorities) { + error->type = + RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SP_PRIORITIES; + error->message = "SP priority not supported"; + return -EINVAL; + } + + /* obviously no more than one root */ + if (pf->tm_conf.root) { + error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID; + error->message = "already have a root"; + return -EINVAL; + } + + /* add the root node */ + tm_node = rte_zmalloc("i40e_tm_node", + sizeof(struct i40e_tm_node), + 0); + if (!tm_node) + return -ENOMEM; + tm_node->id = node_id; + tm_node->priority = priority; + tm_node->weight = weight; + tm_node->reference_count = 0; + tm_node->parent = NULL; + tm_node->shaper_profile = shaper_profile; + (void)rte_memcpy(&tm_node->params, params, + sizeof(struct rte_tm_node_params)); + pf->tm_conf.root = tm_node; + + /* increase the reference counter of the shaper profile */ + shaper_profile->reference_count++; + + return 0; + } + + /* TC node */ + /* check the unsupported parameters */ + if (params->leaf.cman) { + error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN; + error->message = "Congestion management not supported"; + return -EINVAL; + } + if (params->leaf.wred.wred_profile_id != + RTE_TM_WRED_PROFILE_ID_NONE) { + error->type = + RTE_TM_ERROR_TYPE_NODE_PARAMS_WRED_PROFILE_ID; + error->message = "WRED not supported"; + return -EINVAL; + } + if (params->leaf.wred.shared_wred_context_id) { + error->type = + RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_WRED_CONTEXT_ID; + error->message = "WRED not supported"; + return -EINVAL; + } + if (params->leaf.wred.n_shared_wred_contexts) { + error->type = + RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_WRED_CONTEXTS; + error->message = "WRED not supported"; + return -EINVAL; + } + + /* should have a root first */ + if (!pf->tm_conf.root) { + error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID; + error->message = "no root yet"; + return -EINVAL; + } + if (pf->tm_conf.root->id != parent_node_id) { + error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID; + error->message = "parent id doesn't belong to the root"; + return -EINVAL; + } + + /* check the TC number */ + tc_nb = i40e_tc_nb_get(dev); + if (pf->tm_conf.nb_tc_node >= tc_nb) { + error->type = RTE_TM_ERROR_TYPE_NODE_ID; + error->message = "too much TC"; + return -EINVAL; + } + + /* add the TC node */ + tm_node = rte_zmalloc("i40e_tm_node", + sizeof(struct i40e_tm_node), + 0); + if (!tm_node) + return -ENOMEM; + tm_node->id = node_id; + tm_node->priority = priority; + tm_node->weight = weight; + tm_node->reference_count = 0; + tm_node->parent = pf->tm_conf.root; + tm_node->shaper_profile = shaper_profile; + (void)rte_memcpy(&tm_node->params, params, + sizeof(struct rte_tm_node_params)); + TAILQ_INSERT_TAIL(&pf->tm_conf.tc_list, + tm_node, node); + tm_node->parent->reference_count++; + pf->tm_conf.nb_tc_node++; + + /* increase the reference counter of the shaper profile */ + shaper_profile->reference_count++; + + return 0; +}