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 5E5CDA04BA; Wed, 7 Oct 2020 16:11:12 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8C40B1BC88; Wed, 7 Oct 2020 16:10:12 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 5491C1BBD2 for ; Wed, 7 Oct 2020 16:10:08 +0200 (CEST) IronPort-SDR: Hk2L+fowR8y4ThbfxaWae51uqBAozGtUdAnPh8TeWEF/fq9v13t+2kLWNgPfQwjsG+/BGelIQB /kiCz93sESKw== X-IronPort-AV: E=McAfee;i="6000,8403,9767"; a="162336152" X-IronPort-AV: E=Sophos;i="5.77,347,1596524400"; d="scan'208";a="162336152" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Oct 2020 07:10:07 -0700 IronPort-SDR: ftk+toq65AIbXPJndS/zAcJZ1zxZZ5uYarffyljCbvtOBsTqdUcdT2daLQN5gCqN97cUlFtS/G YW+o+J859pPg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,347,1596524400"; d="scan'208";a="311760444" Received: from silpixa00400629.ir.intel.com ([10.237.214.112]) by orsmga003.jf.intel.com with ESMTP; 07 Oct 2020 07:10:04 -0700 From: Savinay Dharmappa To: cristian.dumitrescu@intel.com, jasvinder.singh@intel.com, dev@dpdk.org Cc: savinay.dharmappa@intel.com Date: Wed, 7 Oct 2020 15:09:10 +0100 Message-Id: <20201007140915.19491-4-savinay.dharmappa@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201007140915.19491-1-savinay.dharmappa@intel.com> References: <20201006180233.15793-1-savinay.dharmappa@intel.com> <20201007140915.19491-1-savinay.dharmappa@intel.com> Subject: [dpdk-dev] [PATCH v8 3/8] sched: update subport rate dynamically 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 support to update subport rate dynamically. Signed-off-by: Savinay Dharmappa --- app/test/test_sched.c | 2 +- drivers/net/softnic/rte_eth_softnic_tm.c | 6 +- examples/ip_pipeline/tmgr.c | 6 +- examples/qos_sched/init.c | 3 +- lib/librte_sched/rte_sched.c | 373 +++++++++++------------ lib/librte_sched/rte_sched.h | 13 +- 6 files changed, 202 insertions(+), 201 deletions(-) diff --git a/app/test/test_sched.c b/app/test/test_sched.c index fc31080ef..5e5c2a59b 100644 --- a/app/test/test_sched.c +++ b/app/test/test_sched.c @@ -138,7 +138,7 @@ test_sched(void) port = rte_sched_port_config(&port_param); TEST_ASSERT_NOT_NULL(port, "Error config sched port\n"); - err = rte_sched_subport_config(port, SUBPORT, subport_param); + err = rte_sched_subport_config(port, SUBPORT, subport_param, 0); TEST_ASSERT_SUCCESS(err, "Error config sched, err=%d\n", err); for (pipe = 0; pipe < subport_param[0].n_pipes_per_subport_enabled; pipe++) { diff --git a/drivers/net/softnic/rte_eth_softnic_tm.c b/drivers/net/softnic/rte_eth_softnic_tm.c index d30976378..5199dd2cd 100644 --- a/drivers/net/softnic/rte_eth_softnic_tm.c +++ b/drivers/net/softnic/rte_eth_softnic_tm.c @@ -92,7 +92,7 @@ softnic_tmgr_port_create(struct pmd_internals *p, status = rte_sched_subport_config(sched, subport_id, - &t->subport_params[subport_id]); + &t->subport_params[subport_id], 0); if (status) { rte_sched_port_free(sched); return NULL; @@ -1141,7 +1141,7 @@ update_subport_tc_rate(struct rte_eth_dev *dev, /* Update the subport configuration. */ if (rte_sched_subport_config(SCHED(p), - subport_id, &subport_params)) + subport_id, &subport_params, 0)) return -1; /* Commit changes. */ @@ -2912,7 +2912,7 @@ update_subport_rate(struct rte_eth_dev *dev, /* Update the subport configuration. */ if (rte_sched_subport_config(SCHED(p), subport_id, - &subport_params)) + &subport_params, 0)) return -1; /* Commit changes. */ diff --git a/examples/ip_pipeline/tmgr.c b/examples/ip_pipeline/tmgr.c index 91ccbf60f..46c6a83a4 100644 --- a/examples/ip_pipeline/tmgr.c +++ b/examples/ip_pipeline/tmgr.c @@ -119,7 +119,8 @@ tmgr_port_create(const char *name, struct tmgr_port_params *params) status = rte_sched_subport_config( s, i, - &subport_profile[0]); + &subport_profile[0], + 0); if (status) { rte_sched_port_free(s); @@ -180,7 +181,8 @@ tmgr_subport_config(const char *port_name, status = rte_sched_subport_config( port->s, subport_id, - &subport_profile[subport_profile_id]); + &subport_profile[subport_profile_id], + 0); return status; } diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c index 06328ddb2..b188c624b 100644 --- a/examples/qos_sched/init.c +++ b/examples/qos_sched/init.c @@ -314,7 +314,8 @@ app_init_sched_port(uint32_t portid, uint32_t socketid) } for (subport = 0; subport < port_params.n_subports_per_port; subport ++) { - err = rte_sched_subport_config(port, subport, &subport_params[subport]); + err = rte_sched_subport_config(port, subport, + &subport_params[subport], 0); if (err) { rte_exit(EXIT_FAILURE, "Unable to config sched subport %u, err=%d\n", subport, err); diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 895b40d72..c5482d6e0 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -123,6 +123,7 @@ struct rte_sched_grinder { uint32_t productive; uint32_t pindex; struct rte_sched_subport *subport; + struct rte_sched_subport_profile *subport_params; struct rte_sched_pipe *pipe; struct rte_sched_pipe_profile *pipe_params; @@ -174,6 +175,8 @@ struct rte_sched_subport { /* Statistics */ struct rte_sched_subport_stats stats __rte_cache_aligned; + /* subport profile */ + uint32_t profile; /* Subport pipes */ uint32_t n_pipes_per_subport_enabled; uint32_t n_pipe_profiles; @@ -1098,48 +1101,6 @@ rte_sched_port_free(struct rte_sched_port *port) rte_free(port); } -static void -rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) -{ - struct rte_sched_subport *s = port->subports[i]; - - RTE_LOG(DEBUG, SCHED, "Low level config for subport %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: wm min = %"PRIu64 - ", wm max = %"PRIu64"\n", - i, - - /* Token bucket */ - s->tb_period, - s->tb_credits_per_period, - s->tb_size, - - /* Traffic classes */ - s->tc_period, - s->tc_credits_per_period[0], - s->tc_credits_per_period[1], - s->tc_credits_per_period[2], - s->tc_credits_per_period[3], - s->tc_credits_per_period[4], - s->tc_credits_per_period[5], - s->tc_credits_per_period[6], - s->tc_credits_per_period[7], - s->tc_credits_per_period[8], - s->tc_credits_per_period[9], - s->tc_credits_per_period[10], - s->tc_credits_per_period[11], - s->tc_credits_per_period[12], - - /* Best effort traffic class oversubscription */ - s->tc_ov_wm_min, - s->tc_ov_wm_max); -} - static void rte_sched_free_memory(struct rte_sched_port *port, uint32_t n_subports) { @@ -1158,10 +1119,12 @@ rte_sched_free_memory(struct rte_sched_port *port, uint32_t n_subports) int rte_sched_subport_config(struct rte_sched_port *port, uint32_t subport_id, - struct rte_sched_subport_params *params) + struct rte_sched_subport_params *params, + uint32_t subport_profile_id) { struct rte_sched_subport *s = NULL; uint32_t n_subports = subport_id; + struct rte_sched_subport_profile *profile; uint32_t n_subport_pipe_queues, i; uint32_t size0, size1, bmp_mem_size; int status; @@ -1181,165 +1144,183 @@ rte_sched_subport_config(struct rte_sched_port *port, return -EINVAL; } - status = rte_sched_subport_check_params(params, - port->n_pipes_per_subport, - port->rate); - if (status != 0) { - RTE_LOG(NOTICE, SCHED, - "%s: Port scheduler params check failed (%d)\n", - __func__, status); - + if (subport_profile_id >= port->n_max_subport_profiles) { + RTE_LOG(ERR, SCHED, "%s: " + "Number of subport profile exceeds the max limit\n", + __func__); rte_sched_free_memory(port, n_subports); return -EINVAL; } - /* Determine the amount of memory to allocate */ - size0 = sizeof(struct rte_sched_subport); - size1 = rte_sched_subport_get_array_base(params, - e_RTE_SCHED_SUBPORT_ARRAY_TOTAL); + /** Memory is allocated only on first invocation of the api for a + * given subport. Subsequent invocation on same subport will just + * update subport bandwidth parameter. + **/ + if (port->subports[subport_id] == NULL) { - /* Allocate memory to store the data structures */ - s = rte_zmalloc_socket("subport_params", size0 + size1, - RTE_CACHE_LINE_SIZE, port->socket); - if (s == NULL) { - RTE_LOG(ERR, SCHED, - "%s: Memory allocation fails\n", __func__); + status = rte_sched_subport_check_params(params, + port->n_pipes_per_subport, + port->rate); + if (status != 0) { + RTE_LOG(NOTICE, SCHED, + "%s: Port scheduler params check failed (%d)\n", + __func__, status); - rte_sched_free_memory(port, n_subports); - return -ENOMEM; - } + rte_sched_free_memory(port, n_subports); + return -EINVAL; + } - n_subports++; + /* Determine the amount of memory to allocate */ + size0 = sizeof(struct rte_sched_subport); + size1 = rte_sched_subport_get_array_base(params, + e_RTE_SCHED_SUBPORT_ARRAY_TOTAL); - /* Port */ - port->subports[subport_id] = s; + /* Allocate memory to store the data structures */ + s = rte_zmalloc_socket("subport_params", size0 + size1, + RTE_CACHE_LINE_SIZE, port->socket); + if (s == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Memory allocation fails\n", __func__); - /* Token Bucket (TB) */ - if (params->tb_rate == port->rate) { - s->tb_credits_per_period = 1; - s->tb_period = 1; - } else { - double tb_rate = ((double) params->tb_rate) / ((double) port->rate); - double d = RTE_SCHED_TB_RATE_CONFIG_ERR; + rte_sched_free_memory(port, n_subports); + return -ENOMEM; + } - rte_approx_64(tb_rate, d, &s->tb_credits_per_period, &s->tb_period); - } + n_subports++; - s->tb_size = params->tb_size; - s->tb_time = port->time; - s->tb_credits = s->tb_size / 2; + subport_profile_id = 0; - /* Traffic Classes (TCs) */ - s->tc_period = rte_sched_time_ms_to_bytes(params->tc_period, port->rate); - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->qsize[i]) - s->tc_credits_per_period[i] - = rte_sched_time_ms_to_bytes(params->tc_period, - params->tc_rate[i]); - } - s->tc_time = port->time + s->tc_period; - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - if (params->qsize[i]) - s->tc_credits[i] = s->tc_credits_per_period[i]; + /* Port */ + port->subports[subport_id] = s; - /* compile time checks */ - RTE_BUILD_BUG_ON(RTE_SCHED_PORT_N_GRINDERS == 0); - RTE_BUILD_BUG_ON(RTE_SCHED_PORT_N_GRINDERS & - (RTE_SCHED_PORT_N_GRINDERS - 1)); + s->tb_time = port->time; - /* User parameters */ - s->n_pipes_per_subport_enabled = params->n_pipes_per_subport_enabled; - memcpy(s->qsize, params->qsize, sizeof(params->qsize)); - s->n_pipe_profiles = params->n_pipe_profiles; - s->n_max_pipe_profiles = params->n_max_pipe_profiles; + /* compile time checks */ + RTE_BUILD_BUG_ON(RTE_SCHED_PORT_N_GRINDERS == 0); + RTE_BUILD_BUG_ON(RTE_SCHED_PORT_N_GRINDERS & + (RTE_SCHED_PORT_N_GRINDERS - 1)); + + /* User parameters */ + s->n_pipes_per_subport_enabled = + params->n_pipes_per_subport_enabled; + memcpy(s->qsize, params->qsize, sizeof(params->qsize)); + s->n_pipe_profiles = params->n_pipe_profiles; + s->n_max_pipe_profiles = params->n_max_pipe_profiles; #ifdef RTE_SCHED_RED - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - uint32_t j; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { + uint32_t j; - for (j = 0; j < RTE_COLORS; j++) { + for (j = 0; j < RTE_COLORS; j++) { /* if min/max are both zero, then RED is disabled */ - if ((params->red_params[i][j].min_th | - params->red_params[i][j].max_th) == 0) { - continue; + if ((params->red_params[i][j].min_th | + params->red_params[i][j].max_th) == 0) { + continue; + } + + if (rte_red_config_init(&s->red_config[i][j], + params->red_params[i][j].wq_log2, + params->red_params[i][j].min_th, + params->red_params[i][j].max_th, + params->red_params[i][j].maxp_inv) != 0) { + rte_sched_free_memory(port, n_subports); + + RTE_LOG(NOTICE, SCHED, + "%s: RED configuration init fails\n", + __func__); + return -EINVAL; + } } + } +#endif - if (rte_red_config_init(&s->red_config[i][j], - params->red_params[i][j].wq_log2, - params->red_params[i][j].min_th, - params->red_params[i][j].max_th, - params->red_params[i][j].maxp_inv) != 0) { - rte_sched_free_memory(port, n_subports); + /* Scheduling loop detection */ + s->pipe_loop = RTE_SCHED_PIPE_INVALID; + s->pipe_exhaustion = 0; + + /* Grinders */ + s->busy_grinders = 0; + + /* Queue base calculation */ + rte_sched_subport_config_qsize(s); + + /* Large data structures */ + s->pipe = (struct rte_sched_pipe *) + (s->memory + rte_sched_subport_get_array_base(params, + e_RTE_SCHED_SUBPORT_ARRAY_PIPE)); + s->queue = (struct rte_sched_queue *) + (s->memory + rte_sched_subport_get_array_base(params, + e_RTE_SCHED_SUBPORT_ARRAY_QUEUE)); + s->queue_extra = (struct rte_sched_queue_extra *) + (s->memory + rte_sched_subport_get_array_base(params, + e_RTE_SCHED_SUBPORT_ARRAY_QUEUE_EXTRA)); + s->pipe_profiles = (struct rte_sched_pipe_profile *) + (s->memory + rte_sched_subport_get_array_base(params, + e_RTE_SCHED_SUBPORT_ARRAY_PIPE_PROFILES)); + s->bmp_array = s->memory + rte_sched_subport_get_array_base( + params, e_RTE_SCHED_SUBPORT_ARRAY_BMP_ARRAY); + s->queue_array = (struct rte_mbuf **) + (s->memory + rte_sched_subport_get_array_base(params, + e_RTE_SCHED_SUBPORT_ARRAY_QUEUE_ARRAY)); + + /* Pipe profile table */ + rte_sched_subport_config_pipe_profile_table(s, params, + port->rate); + + /* Bitmap */ + n_subport_pipe_queues = rte_sched_subport_pipe_queues(s); + bmp_mem_size = rte_bitmap_get_memory_footprint( + n_subport_pipe_queues); + s->bmp = rte_bitmap_init(n_subport_pipe_queues, s->bmp_array, + bmp_mem_size); + if (s->bmp == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Subport bitmap init error\n", __func__); - RTE_LOG(NOTICE, SCHED, - "%s: RED configuration init fails\n", __func__); - return -EINVAL; - } + rte_sched_free_memory(port, n_subports); + return -EINVAL; } - } -#endif - /* Scheduling loop detection */ - s->pipe_loop = RTE_SCHED_PIPE_INVALID; - s->pipe_exhaustion = 0; + for (i = 0; i < RTE_SCHED_PORT_N_GRINDERS; i++) + s->grinder_base_bmp_pos[i] = RTE_SCHED_PIPE_INVALID; - /* Grinders */ - s->busy_grinders = 0; +#ifdef RTE_SCHED_SUBPORT_TC_OV + /* TC oversubscription */ + s->tc_ov_wm_min = port->mtu; + s->tc_ov_wm = s->tc_ov_wm_max; + s->tc_ov_period_id = 0; + s->tc_ov = 0; + s->tc_ov_n = 0; + s->tc_ov_rate = 0; +#endif + } - /* Queue base calculation */ - rte_sched_subport_config_qsize(s); + { + /* update subport parameters from subport profile table*/ + profile = port->subport_profiles + subport_profile_id; - /* Large data structures */ - s->pipe = (struct rte_sched_pipe *) - (s->memory + rte_sched_subport_get_array_base(params, - e_RTE_SCHED_SUBPORT_ARRAY_PIPE)); - s->queue = (struct rte_sched_queue *) - (s->memory + rte_sched_subport_get_array_base(params, - e_RTE_SCHED_SUBPORT_ARRAY_QUEUE)); - s->queue_extra = (struct rte_sched_queue_extra *) - (s->memory + rte_sched_subport_get_array_base(params, - e_RTE_SCHED_SUBPORT_ARRAY_QUEUE_EXTRA)); - s->pipe_profiles = (struct rte_sched_pipe_profile *) - (s->memory + rte_sched_subport_get_array_base(params, - e_RTE_SCHED_SUBPORT_ARRAY_PIPE_PROFILES)); - s->bmp_array = s->memory + rte_sched_subport_get_array_base(params, - e_RTE_SCHED_SUBPORT_ARRAY_BMP_ARRAY); - s->queue_array = (struct rte_mbuf **) - (s->memory + rte_sched_subport_get_array_base(params, - e_RTE_SCHED_SUBPORT_ARRAY_QUEUE_ARRAY)); - - /* Pipe profile table */ - rte_sched_subport_config_pipe_profile_table(s, params, port->rate); + s = port->subports[subport_id]; - /* Bitmap */ - n_subport_pipe_queues = rte_sched_subport_pipe_queues(s); - bmp_mem_size = rte_bitmap_get_memory_footprint(n_subport_pipe_queues); - s->bmp = rte_bitmap_init(n_subport_pipe_queues, s->bmp_array, - bmp_mem_size); - if (s->bmp == NULL) { - RTE_LOG(ERR, SCHED, - "%s: Subport bitmap init error\n", __func__); + s->tb_credits = profile->tb_size / 2; - rte_sched_free_memory(port, n_subports); - return -EINVAL; - } + s->tc_time = port->time + profile->tc_period; - for (i = 0; i < RTE_SCHED_PORT_N_GRINDERS; i++) - s->grinder_base_bmp_pos[i] = RTE_SCHED_PIPE_INVALID; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + if (s->qsize[i]) + s->tc_credits[i] = + profile->tc_credits_per_period[i]; + else + profile->tc_credits_per_period[i] = 0; #ifdef RTE_SCHED_SUBPORT_TC_OV - /* TC oversubscription */ - s->tc_ov_wm_min = port->mtu; - s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(params->tc_period, - s->pipe_tc_be_rate_max); - s->tc_ov_wm = s->tc_ov_wm_max; - s->tc_ov_period_id = 0; - s->tc_ov = 0; - s->tc_ov_n = 0; - s->tc_ov_rate = 0; + s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(profile->tc_period, + s->pipe_tc_be_rate_max); #endif + s->profile = subport_profile_id; + + } - rte_sched_port_log_subport_config(port, subport_id); + rte_sched_port_log_subport_profile(port, subport_profile_id); return 0; } @@ -1351,6 +1332,7 @@ rte_sched_pipe_config(struct rte_sched_port *port, int32_t pipe_profile) { struct rte_sched_subport *s; + struct rte_sched_subport_profile *sp; struct rte_sched_pipe *p; struct rte_sched_pipe_profile *params; uint32_t n_subports = subport_id + 1; @@ -1391,14 +1373,15 @@ rte_sched_pipe_config(struct rte_sched_port *port, return -EINVAL; } + sp = port->subport_profiles + s->profile; /* Handle the case when pipe already has a valid configuration */ p = s->pipe + pipe_id; if (p->tb_time) { params = s->pipe_profiles + p->profile; double subport_tc_be_rate = - (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - / (double) s->tc_period; + (double)sp->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] + / (double) sp->tc_period; double pipe_tc_be_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; @@ -1440,8 +1423,8 @@ rte_sched_pipe_config(struct rte_sched_port *port, { /* Subport best effort tc oversubscription */ double subport_tc_be_rate = - (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - / (double) s->tc_period; + (double)sp->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] + / (double) sp->tc_period; double pipe_tc_be_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; @@ -2229,14 +2212,15 @@ grinder_credits_update(struct rte_sched_port *port, struct rte_sched_grinder *grinder = subport->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; + struct rte_sched_subport_profile *sp = grinder->subport_params; uint64_t n_periods; uint32_t i; /* Subport TB */ - n_periods = (port->time - subport->tb_time) / subport->tb_period; - subport->tb_credits += n_periods * subport->tb_credits_per_period; - subport->tb_credits = RTE_MIN(subport->tb_credits, subport->tb_size); - subport->tb_time += n_periods * subport->tb_period; + n_periods = (port->time - subport->tb_time) / sp->tb_period; + subport->tb_credits += n_periods * sp->tb_credits_per_period; + subport->tb_credits = RTE_MIN(subport->tb_credits, sp->tb_size); + subport->tb_time += n_periods * sp->tb_period; /* Pipe TB */ n_periods = (port->time - pipe->tb_time) / params->tb_period; @@ -2247,9 +2231,9 @@ grinder_credits_update(struct rte_sched_port *port, /* Subport TCs */ if (unlikely(port->time >= subport->tc_time)) { for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - subport->tc_credits[i] = subport->tc_credits_per_period[i]; + subport->tc_credits[i] = sp->tc_credits_per_period[i]; - subport->tc_time = port->time + subport->tc_period; + subport->tc_time = port->time + sp->tc_period; } /* Pipe TCs */ @@ -2265,8 +2249,10 @@ grinder_credits_update(struct rte_sched_port *port, static inline uint64_t grinder_tc_ov_credits_update(struct rte_sched_port *port, - struct rte_sched_subport *subport) + struct rte_sched_subport *subport, uint32_t pos) { + struct rte_sched_grinder *grinder = subport->grinder + pos; + struct rte_sched_subport_profile *sp = grinder->subport_params; uint64_t tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint64_t tc_consumption = 0, tc_ov_consumption_max; uint64_t tc_ov_wm = subport->tc_ov_wm; @@ -2276,17 +2262,17 @@ grinder_tc_ov_credits_update(struct rte_sched_port *port, return subport->tc_ov_wm_max; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { - tc_ov_consumption[i] = - subport->tc_credits_per_period[i] - subport->tc_credits[i]; + tc_ov_consumption[i] = sp->tc_credits_per_period[i] + - subport->tc_credits[i]; tc_consumption += tc_ov_consumption[i]; } tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] = - subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - + sp->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - subport->tc_credits[RTE_SCHED_TRAFFIC_CLASS_BE]; tc_ov_consumption_max = - subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - + sp->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - tc_consumption; if (tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] > @@ -2312,14 +2298,15 @@ grinder_credits_update(struct rte_sched_port *port, struct rte_sched_grinder *grinder = subport->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; + struct rte_sched_subport_profile *sp = grinder->subport_params; uint64_t n_periods; uint32_t i; /* Subport TB */ - n_periods = (port->time - subport->tb_time) / subport->tb_period; - subport->tb_credits += n_periods * subport->tb_credits_per_period; - subport->tb_credits = RTE_MIN(subport->tb_credits, subport->tb_size); - subport->tb_time += n_periods * subport->tb_period; + n_periods = (port->time - subport->tb_time) / sp->tb_period; + subport->tb_credits += n_periods * sp->tb_credits_per_period; + subport->tb_credits = RTE_MIN(subport->tb_credits, sp->tb_size); + subport->tb_time += n_periods * sp->tb_period; /* Pipe TB */ n_periods = (port->time - pipe->tb_time) / params->tb_period; @@ -2329,12 +2316,13 @@ grinder_credits_update(struct rte_sched_port *port, /* Subport TCs */ if (unlikely(port->time >= subport->tc_time)) { - subport->tc_ov_wm = grinder_tc_ov_credits_update(port, subport); + subport->tc_ov_wm = + grinder_tc_ov_credits_update(port, subport, pos); for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - subport->tc_credits[i] = subport->tc_credits_per_period[i]; + subport->tc_credits[i] = sp->tc_credits_per_period[i]; - subport->tc_time = port->time + subport->tc_period; + subport->tc_time = port->time + sp->tc_period; subport->tc_ov_period_id++; } @@ -2857,6 +2845,9 @@ grinder_handle(struct rte_sched_port *port, struct rte_sched_pipe *pipe = grinder->pipe; grinder->pipe_params = subport->pipe_profiles + pipe->profile; + grinder->subport_params = port->subport_profiles + + subport->profile; + grinder_prefetch_tc_queue_arrays(subport, pos); grinder_credits_update(port, subport, pos); diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index aede2e986..1506c6487 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -361,20 +361,27 @@ rte_sched_port_subport_profile_add(struct rte_sched_port *port, /** * Hierarchical scheduler subport configuration - * + * Note that this function is safe to use at runtime + * to configure subport bandwidth profile. * @param port * Handle to port scheduler instance * @param subport_id * Subport ID * @param params - * Subport configuration parameters + * Subport configuration parameters. Must be non-NULL + * for first invocation (i.e initialization) for a given + * subport. Ignored (recommended value is NULL) for all + * subsequent invocation on the same subport. + * @param subport_profile_id + * ID of subport bandwidth profile * @return * 0 upon success, error code otherwise */ int rte_sched_subport_config(struct rte_sched_port *port, uint32_t subport_id, - struct rte_sched_subport_params *params); + struct rte_sched_subport_params *params, + uint32_t subport_profile_id); /** * Hierarchical scheduler pipe configuration -- 2.17.1