From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by dpdk.space (Postfix) with ESMTP id 28B85A045E for ; Tue, 28 May 2019 14:09:48 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E72311B9A4; Tue, 28 May 2019 14:08:27 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 342F51B956 for ; Tue, 28 May 2019 14:08:18 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 May 2019 05:08:17 -0700 X-ExtLoop1: 1 Received: from lkrakowx-mobl.ger.corp.intel.com ([10.103.104.99]) by fmsmga001.fm.intel.com with ESMTP; 28 May 2019 05:08:16 -0700 From: Lukasz Krakowiak To: cristian.dumitrescu@intel.com Cc: dev@dpdk.org, Jasvinder Singh , Abraham Tovar , Lukasz Krakowiak Date: Tue, 28 May 2019 14:05:33 +0200 Message-Id: <20190528120553.2992-8-lukaszx.krakowiak@intel.com> X-Mailer: git-send-email 2.19.2.windows.1 In-Reply-To: <20190528120553.2992-1-lukaszx.krakowiak@intel.com> References: <20190528120553.2992-1-lukaszx.krakowiak@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH 07/27] sched: update pipe profile add api 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: Jasvinder Singh Update the pipe profile add api implementation of the scheduler to allow configuration flexiblity for pipe traffic classes and queues, and subport level configuration of the pipe parameters. Signed-off-by: Jasvinder Singh Signed-off-by: Abraham Tovar Signed-off-by: Lukasz Krakowiak --- lib/librte_sched/rte_sched.c | 257 +++++++++++++++++++++++++++-------- lib/librte_sched/rte_sched.h | 3 + 2 files changed, 205 insertions(+), 55 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 020c028fd..c1079cdaa 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -365,44 +365,49 @@ rte_sched_port_qsize(struct rte_sched_port *port, uint32_t qindex) static int pipe_profile_check(struct rte_sched_pipe_params *params, - uint32_t rate) + uint32_t rate, uint16_t *qsize) { uint32_t i; /* Pipe parameters */ if (params == NULL) - return -10; + return -11; /* TB rate: non-zero, not greater than port rate */ if (params->tb_rate == 0 || params->tb_rate > rate) - return -11; + return -12; /* TB size: non-zero */ if (params->tb_size == 0) - return -12; + return -13; /* TC rate: non-zero, less than pipe rate */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate) - return -13; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + if ((qsize[i] == 0 && params->tc_rate[i] != 0) || + (qsize[i] != 0 && (params->tc_rate[i] == 0 || + params->tc_rate[i] > params->tb_rate))) + return -14; } + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) + return -15; /* TC period: non-zero */ if (params->tc_period == 0) - return -14; + return -16; #ifdef RTE_SCHED_SUBPORT_TC_OV /* TC3 oversubscription weight: non-zero */ if (params->tc_ov_weight == 0) - return -15; + return -17; #endif /* Queue WRR weights: non-zero */ - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { - if (params->wrr_weights[i] == 0) - return -16; + for (i = 0; i < RTE_SCHED_WRR_QUEUES_PER_PIPE; i++) { + uint32_t qindex = RTE_SCHED_TRAFFIC_CLASS_BE + i; + if ((qsize[qindex] != 0 && params->wrr_weights[i] == 0) || + (qsize[qindex] == 0 && params->wrr_weights[i] != 0)) + return -18; } return 0; @@ -549,6 +554,120 @@ rte_sched_subport_get_array_base(struct rte_sched_subport_params *params, return base; } +static void +rte_sched_pipe_queues_config(struct rte_sched_subport *subport, + struct rte_sched_pipe_profile *dst) +{ + uint32_t i; + + /* Queues: strict priority */ + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) + if (subport->qsize[i]) + dst->n_sp_queues++; + + /* Queues: best effort */ + for (i = 0; i < RTE_SCHED_WRR_QUEUES_PER_PIPE; i++) + if (subport->qsize[RTE_SCHED_TRAFFIC_CLASS_BE + i]) + dst->n_be_queues++; +} + +static void +rte_sched_pipe_wrr_queues_config(struct rte_sched_pipe_params *src, + struct rte_sched_pipe_profile *dst) +{ + uint32_t wrr_cost[RTE_SCHED_WRR_QUEUES_PER_PIPE]; + + if (dst->n_be_queues == 1) { + dst->wrr_cost[0] = (uint8_t) src->wrr_weights[0]; + + return; + } + + if (dst->n_be_queues == 2) { + uint32_t lcd; + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + + lcd = rte_get_lcd(wrr_cost[0], wrr_cost[1]); + + wrr_cost[0] = lcd / wrr_cost[0]; + wrr_cost[1] = lcd / wrr_cost[1]; + + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + + return; + } + + if (dst->n_be_queues == 4) { + uint32_t lcd, lcd1, lcd2; + + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + wrr_cost[2] = src->wrr_weights[2]; + wrr_cost[3] = src->wrr_weights[3]; + + lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); + lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); + lcd = rte_get_lcd(lcd1, lcd2); + + wrr_cost[0] = lcd / wrr_cost[0]; + wrr_cost[1] = lcd / wrr_cost[1]; + wrr_cost[2] = lcd / wrr_cost[2]; + wrr_cost[3] = lcd / wrr_cost[3]; + + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + dst->wrr_cost[2] = (uint8_t) wrr_cost[2]; + dst->wrr_cost[3] = (uint8_t) wrr_cost[3]; + + return; + } + + if (dst->n_be_queues == 8) { + uint32_t lcd1, lcd2, lcd3, lcd4, lcd5, lcd6, lcd7; + + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + wrr_cost[2] = src->wrr_weights[2]; + wrr_cost[3] = src->wrr_weights[3]; + wrr_cost[4] = src->wrr_weights[4]; + wrr_cost[5] = src->wrr_weights[5]; + wrr_cost[6] = src->wrr_weights[6]; + wrr_cost[7] = src->wrr_weights[7]; + + lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); + lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); + lcd3 = rte_get_lcd(wrr_cost[4], wrr_cost[5]); + lcd4 = rte_get_lcd(wrr_cost[6], wrr_cost[7]); + + lcd5 = rte_get_lcd(lcd1, lcd2); + lcd6 = rte_get_lcd(lcd3, lcd4); + + lcd7 = rte_get_lcd(lcd5, lcd6); + + wrr_cost[0] = lcd7 / wrr_cost[0]; + wrr_cost[1] = lcd7 / wrr_cost[1]; + wrr_cost[2] = lcd7 / wrr_cost[2]; + wrr_cost[3] = lcd7 / wrr_cost[3]; + wrr_cost[4] = lcd7 / wrr_cost[4]; + wrr_cost[5] = lcd7 / wrr_cost[5]; + wrr_cost[6] = lcd7 / wrr_cost[6]; + wrr_cost[7] = lcd7 / wrr_cost[7]; + + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + dst->wrr_cost[2] = (uint8_t) wrr_cost[2]; + dst->wrr_cost[3] = (uint8_t) wrr_cost[3]; + dst->wrr_cost[4] = (uint8_t) wrr_cost[4]; + dst->wrr_cost[5] = (uint8_t) wrr_cost[5]; + dst->wrr_cost[6] = (uint8_t) wrr_cost[6]; + dst->wrr_cost[7] = (uint8_t) wrr_cost[7]; + + return; + } +} + static void rte_sched_subport_config_qsize(struct rte_sched_subport *subport) { @@ -564,15 +683,15 @@ rte_sched_subport_config_qsize(struct rte_sched_subport *subport) } static void -rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) +rte_sched_port_log_pipe_profile(struct rte_sched_subport *subport, uint32_t i) { - struct rte_sched_pipe_profile *p = port->pipe_profiles + 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 = %u, credits per period = %u, size = %u\n" - " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" - " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu],\n", + " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u]\n" + " Traffic class BE oversubscription: weight = %hhu\n" + " WRR cost: [%hhu, %hhu, %hhu, %hhu, %hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -586,6 +705,11 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) 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], /* Traffic class 3 oversubscription */ p->tc_ov_weight, @@ -606,7 +730,8 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, uint32_t rate) } static void -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, +rte_sched_pipe_profile_convert(struct rte_sched_subport *subport, + struct rte_sched_pipe_params *src, struct rte_sched_pipe_profile *dst, uint32_t rate) { @@ -632,40 +757,42 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, 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]); + if (subport->qsize[i]) + dst->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(src->tc_period, + src->tc_rate[i]); #ifdef RTE_SCHED_SUBPORT_TC_OV dst->tc_ov_weight = src->tc_ov_weight; #endif + rte_sched_pipe_queues_config(subport, dst); + /* WRR */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - uint32_t wrr_cost[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; - uint32_t lcd, lcd1, lcd2; - uint32_t qindex; + rte_sched_pipe_wrr_queues_config(src, dst); +} - qindex = i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; +static void +rte_sched_subport_config_pipe_profile_table(struct rte_sched_subport *subport, + struct rte_sched_subport_params *params, uint32_t rate) +{ + uint32_t i; - wrr_cost[0] = src->wrr_weights[qindex]; - wrr_cost[1] = src->wrr_weights[qindex + 1]; - wrr_cost[2] = src->wrr_weights[qindex + 2]; - wrr_cost[3] = src->wrr_weights[qindex + 3]; + for (i = 0; i < subport->n_pipe_profiles; i++) { + struct rte_sched_pipe_params *src = params->pipe_profiles + i; + struct rte_sched_pipe_profile *dst = subport->pipe_profiles + i; - lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); - lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); - lcd = rte_get_lcd(lcd1, lcd2); + rte_sched_pipe_profile_convert(subport, src, dst, rate); + rte_sched_port_log_pipe_profile(subport, i); + } - wrr_cost[0] = lcd / wrr_cost[0]; - wrr_cost[1] = lcd / wrr_cost[1]; - wrr_cost[2] = lcd / wrr_cost[2]; - wrr_cost[3] = lcd / wrr_cost[3]; + subport->pipe_tc_be_rate_max = 0; + for (i = 0; i < subport->n_pipe_profiles; i++) { + struct rte_sched_pipe_params *src = params->pipe_profiles + i; + uint32_t pipe_tc_be_rate = src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; - dst->wrr_cost[qindex] = (uint8_t) wrr_cost[0]; - dst->wrr_cost[qindex + 1] = (uint8_t) wrr_cost[1]; - dst->wrr_cost[qindex + 2] = (uint8_t) wrr_cost[2]; - dst->wrr_cost[qindex + 3] = (uint8_t) wrr_cost[3]; + if (subport->pipe_tc_be_rate_max < pipe_tc_be_rate) + subport->pipe_tc_be_rate_max = pipe_tc_be_rate; } } @@ -733,6 +860,15 @@ rte_sched_subport_check_params(struct rte_sched_subport_params *params, params->n_pipe_profiles > RTE_SCHED_PIPE_PROFILES_PER_SUBPORT) return -10; + for (i = 0; i < params->n_pipe_profiles; i++) { + struct rte_sched_pipe_params *p = params->pipe_profiles + i; + int status; + + status = pipe_profile_check(p, rate, ¶ms->qsize[0]); + if (status != 0) + return status; + } + return 0; } @@ -1013,6 +1149,9 @@ rte_sched_subport_config(struct rte_sched_port *port, (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_queues = rte_sched_subport_queues(s); bmp_mem_size = rte_bitmap_get_memory_footprint(n_subport_queues); @@ -1150,10 +1289,12 @@ rte_sched_pipe_config(struct rte_sched_port *port, int __rte_experimental rte_sched_port_pipe_profile_add(struct rte_sched_port *port, + uint32_t subport_id, struct rte_sched_pipe_params *params, uint32_t *pipe_profile_id) { struct rte_sched_pipe_profile *pp; + struct rte_sched_subport *s; uint32_t i; int status; @@ -1161,31 +1302,37 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, if (port == NULL) return -1; - /* Pipe profiles not exceeds the max limit */ - if (port->n_pipe_profiles >= RTE_SCHED_PIPE_PROFILES_PER_PORT) + /* Subport id not exceeds the max limit */ + if (subport_id > port->n_subports_per_port) return -2; + s = port->subports[subport_id]; + + /* Pipe profiles not exceeds the max limit */ + if (s->n_pipe_profiles >= RTE_SCHED_PIPE_PROFILES_PER_SUBPORT) + return -3; + /* Pipe params */ - status = pipe_profile_check(params, port->rate); + status = pipe_profile_check(params, port->rate, &s->qsize[0]); if (status != 0) return status; - pp = &port->pipe_profiles[port->n_pipe_profiles]; - rte_sched_pipe_profile_convert(params, pp, port->rate); + pp = &s->pipe_profiles[s->n_pipe_profiles]; + rte_sched_pipe_profile_convert(s, params, pp, port->rate); /* Pipe profile not exists */ - for (i = 0; i < port->n_pipe_profiles; i++) - if (memcmp(port->pipe_profiles + i, pp, sizeof(*pp)) == 0) - return -3; + for (i = 0; i < s->n_pipe_profiles; i++) + if (memcmp(s->pipe_profiles + i, pp, sizeof(*pp)) == 0) + return -4; /* Pipe profile commit */ - *pipe_profile_id = port->n_pipe_profiles; - port->n_pipe_profiles++; + *pipe_profile_id = s->n_pipe_profiles; + s->n_pipe_profiles++; - if (port->pipe_tc3_rate_max < params->tc_rate[3]) - port->pipe_tc3_rate_max = params->tc_rate[3]; + if (s->pipe_tc_be_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) + s->pipe_tc_be_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; - rte_sched_port_log_pipe_profile(port, *pipe_profile_id); + rte_sched_port_log_pipe_profile(s, *pipe_profile_id); return 0; } diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 71728f725..51f801098 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -277,6 +277,8 @@ rte_sched_port_free(struct rte_sched_port *port); * * @param port * Handle to port scheduler instance + * @param subport_id + * Subport ID * @param params * Pipe profile parameters * @param pipe_profile_id @@ -286,6 +288,7 @@ rte_sched_port_free(struct rte_sched_port *port); */ int __rte_experimental rte_sched_port_pipe_profile_add(struct rte_sched_port *port, + uint32_t subport_id, struct rte_sched_pipe_params *params, uint32_t *pipe_profile_id); -- 2.20.1