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 210BBA04B7; Wed, 2 Sep 2020 10:58:19 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B53F21C066; Wed, 2 Sep 2020 10:58:18 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 94AEC4C99 for ; Wed, 2 Sep 2020 10:58:16 +0200 (CEST) IronPort-SDR: SiAI7bK/oCNh7xkXLAtjw0ACluYgBGeLCMR4WQPbrdVOIVuR5C56/s3K2CHIpsOVu6LvQ+3qMP T0QOhsIkkQhA== X-IronPort-AV: E=McAfee;i="6000,8403,9731"; a="158346005" X-IronPort-AV: E=Sophos;i="5.76,381,1592895600"; d="scan'208";a="158346005" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Sep 2020 01:58:14 -0700 IronPort-SDR: tCvPih42+tyA8QbUW0tqlLjxPT50ok+OsrghTed7Ux2tsHTIQ0UkoOiA46tv2yAEmu0Ldxa5jb sTyXtF6EAOug== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,381,1592895600"; d="scan'208";a="477557326" Received: from unknown (HELO silpixa00400629.ir.intel.com) ([10.237.214.135]) by orsmga005.jf.intel.com with ESMTP; 02 Sep 2020 01:58:11 -0700 From: Savinay Dharmappa To: cristian.dumitrescu@intel.com, jasvinder.singh@intel.com, dev@dpdk.org Cc: savinay.dharmappa@intel.com Date: Wed, 2 Sep 2020 09:56:43 +0100 Message-Id: <1599037006-3931-1-git-send-email-savinay.dharmappa@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1594837677-313175-2-git-send-email-savinay.dharmappa@intel.com> References: <1594837677-313175-2-git-send-email-savinay.dharmappa@intel.com> Subject: [dpdk-dev] [PATCH v1 1/4] sched: add dynamic config of subport bandwidth profile 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" This patch modifies the subport level data structures and add internal functions to create subport profile table. Signed-off-by: Savinay Dharmappa Signed-off-by: Jasvinder Singh --- lib/librte_sched/rte_sched.c | 173 +++++++++++++++++++++++++++++++++++++++---- lib/librte_sched/rte_sched.h | 37 ++++++--- 2 files changed, 185 insertions(+), 25 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index c0983dd..c82e09c 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -2,6 +2,7 @@ * Copyright(c) 2010-2014 Intel Corporation */ +#include #include #include @@ -101,6 +102,16 @@ enum grinder_state { e_GRINDER_READ_MBUF }; +struct rte_sched_subport_profile { + /* Token bucket (TB) */ + uint64_t tb_period; + uint64_t tb_credits_per_period; + uint64_t tb_size; + + uint64_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint64_t tc_period; +}; + struct rte_sched_grinder { /* Pipe cache */ uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE]; @@ -139,18 +150,13 @@ struct rte_sched_grinder { }; struct rte_sched_subport { - /* Token bucket (TB) */ + uint64_t tb_time; /* time of last update */ - uint64_t tb_period; - uint64_t tb_credits_per_period; - uint64_t tb_size; uint64_t tb_credits; /* Traffic classes (TCs) */ uint64_t tc_time; /* time of next update */ - uint64_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint64_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint64_t tc_period; /* TC oversubscription */ uint64_t tc_ov_wm; @@ -164,6 +170,8 @@ struct rte_sched_subport { /* Statistics */ struct rte_sched_subport_stats stats __rte_cache_aligned; + /* subport profile flag */ + uint32_t profile; /* Subport pipes */ uint32_t n_pipes_per_subport_enabled; uint32_t n_pipe_profiles; @@ -212,6 +220,8 @@ struct rte_sched_port { uint16_t pipe_queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint8_t pipe_tc[RTE_SCHED_QUEUES_PER_PIPE]; uint8_t tc_queue[RTE_SCHED_QUEUES_PER_PIPE]; + uint32_t n_subport_profiles; + uint32_t n_max_subport_profiles; uint64_t rate; uint32_t mtu; uint32_t frame_overhead; @@ -229,6 +239,7 @@ struct rte_sched_port { uint32_t subport_id; /* Large data structures */ + struct rte_sched_subport_profile *subport_profiles; struct rte_sched_subport *subports[0] __rte_cache_aligned; } __rte_cache_aligned; @@ -375,6 +386,56 @@ pipe_profile_check(struct rte_sched_pipe_params *params, } static int +subport_profile_check(struct rte_sched_subport_profile_params *params, + uint64_t rate) +{ + uint32_t i; + + /* Check user parameters */ + if (params == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter params\n", __func__); + return -EINVAL; + } + + if (params->tb_rate == 0 || params->tb_rate > rate) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tb rate\n", __func__); + return -EINVAL; + } + + if (params->tb_size == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tb size\n", __func__); + return -EINVAL; + } + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { + uint64_t tc_rate = params->tc_rate[i]; + + if (tc_rate == 0 || (tc_rate > params->tb_rate)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate\n", __func__); + return -EINVAL; + } + } + + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect tc rate(best effort)\n", __func__); + return -EINVAL; + } + + if (params->tc_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc period\n", __func__); + return -EINVAL; + } + + return 0; +} + +static int rte_sched_port_check_params(struct rte_sched_port_params *params) { if (params == NULL) { @@ -517,13 +578,14 @@ rte_sched_port_log_pipe_profile(struct rte_sched_subport *subport, uint32_t i) struct rte_sched_pipe_profile *p = subport->pipe_profiles + i; RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n" - " Token bucket: period = %"PRIu64", credits per period = %"PRIu64", size = %"PRIu64"\n" - " Traffic classes: period = %"PRIu64",\n" - " credits per period = [%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64 - ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64 - ", %"PRIu64", %"PRIu64", %"PRIu64"]\n" - " Best-effort traffic class oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", + "Token bucket: period = %"PRIu64", credits per period = %"PRIu64"" + " size = %"PRIu64",\n" + " Traffic classes: period = %"PRIu64",\n" + " credits per period = [%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64"" + ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64"" + ", %"PRIu64", %"PRIu64", %"PRIu64"]\n" + " Best-effort traffic class oversubscription: weight = %hhu\n" + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -554,6 +616,42 @@ rte_sched_port_log_pipe_profile(struct rte_sched_subport *subport, uint32_t i) p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p->wrr_cost[3]); } +static void +rte_sched_port_log_subport_profile(struct rte_sched_port *port, uint32_t i) +{ + struct rte_sched_subport_profile *p = port->subport_profiles + i; + + RTE_LOG(DEBUG, SCHED, "Low level config for subport profile %u:\n" + "Token bucket: period = %"PRIu64", credits per period = %"PRIu64",\ + size = %"PRIu64"\n" + "Traffic classes: period = %"PRIu64",\n" + "credits per period = [%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64 + " %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64 + " %"PRIu64", %"PRIu64", %"PRIu64"]\n", + i, + + /* Token bucket */ + p->tb_period, + p->tb_credits_per_period, + p->tb_size, + + /* Traffic classes */ + p->tc_period, + p->tc_credits_per_period[0], + p->tc_credits_per_period[1], + p->tc_credits_per_period[2], + p->tc_credits_per_period[3], + p->tc_credits_per_period[4], + p->tc_credits_per_period[5], + p->tc_credits_per_period[6], + p->tc_credits_per_period[7], + p->tc_credits_per_period[8], + p->tc_credits_per_period[9], + p->tc_credits_per_period[10], + p->tc_credits_per_period[11], + p->tc_credits_per_period[12]); +} + static inline uint64_t rte_sched_time_ms_to_bytes(uint64_t time_ms, uint64_t rate) { @@ -623,6 +721,37 @@ rte_sched_pipe_profile_convert(struct rte_sched_subport *subport, } static void +rte_sched_subport_profile_convert(struct rte_sched_subport_profile_params *src, + struct rte_sched_subport_profile *dst, + uint64_t rate) +{ + uint32_t i; + + /* Token Bucket */ + if (src->tb_rate == rate) { + dst->tb_credits_per_period = 1; + dst->tb_period = 1; + } else { + double tb_rate = (double) src->tb_rate + / (double) rate; + double d = RTE_SCHED_TB_RATE_CONFIG_ERR; + + rte_approx_64(tb_rate, d, &dst->tb_credits_per_period, + &dst->tb_period); + } + + dst->tb_size = src->tb_size; + + /* Traffic Classes */ + dst->tc_period = rte_sched_time_ms_to_bytes(src->tc_period, rate); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + dst->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(src->tc_period, + src->tc_rate[i]); +} + +static void rte_sched_subport_config_pipe_profile_table(struct rte_sched_subport *subport, struct rte_sched_subport_params *params, uint32_t rate) { @@ -646,6 +775,24 @@ rte_sched_subport_config_pipe_profile_table(struct rte_sched_subport *subport, } } +static void +rte_sched_port_config_subport_profile_table(struct rte_sched_port *port, + struct rte_sched_port_params *params, + uint64_t rate) +{ + uint32_t i; + + for (i = 0; i < port->n_subport_profiles; i++) { + struct rte_sched_subport_profile_params *src + = params->subport_profiles + i; + struct rte_sched_subport_profile *dst + = port->subport_profiles + i; + + rte_sched_subport_profile_convert(src, dst, rate); + rte_sched_port_log_subport_profile(port, i); + } +} + static int rte_sched_subport_check_params(struct rte_sched_subport_params *params, uint32_t n_max_pipes_per_subport, diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 8a5a93c..e7514bb 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -149,18 +149,6 @@ struct rte_sched_pipe_params { * byte. */ struct rte_sched_subport_params { - /** Token bucket rate (measured in bytes per second) */ - uint64_t tb_rate; - - /** Token bucket size (measured in credits) */ - uint64_t tb_size; - - /** Traffic class rates (measured in bytes per second) */ - uint64_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - - /** Enforcement period for rates (measured in milliseconds) */ - uint64_t tc_period; - /** Number of subport pipes. * The subport can enable/allocate fewer pipes than the maximum * number set through struct port_params::n_max_pipes_per_subport, @@ -192,6 +180,20 @@ struct rte_sched_subport_params { #endif }; +struct rte_sched_subport_profile_params { + /** Token bucket rate (measured in bytes per second) */ + uint64_t tb_rate; + + /** Token bucket size (measured in credits) */ + uint64_t tb_size; + + /** Traffic class rates (measured in bytes per second) */ + uint64_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + + /** Enforcement period for rates (measured in milliseconds) */ + uint64_t tc_period; +}; + /** Subport statistics */ struct rte_sched_subport_stats { /** Number of packets successfully written */ @@ -254,6 +256,17 @@ struct rte_sched_port_params { /** Number of subports */ uint32_t n_subports_per_port; + /** subport profile table. + * Every pipe is configured using one of the profiles from this table. + */ + struct rte_sched_subport_profile_params *subport_profiles; + + /** Profiles in the pipe profile table */ + uint32_t n_subport_profiles; + + /** Max allowed profiles in the pipe profile table */ + uint32_t n_max_subport_profiles; + /** Maximum number of subport pipes. * This parameter is used to reserve a fixed number of bits * in struct rte_mbuf::sched.queue_id for the pipe_id for all -- 2.7.4