All of lore.kernel.org
 help / color / mirror / Atom feed
From: Savinay Dharmappa <savinay.dharmappa@intel.com>
To: cristian.dumitrescu@intel.com, jasvinder.singh@intel.com, dev@dpdk.org
Cc: savinay.dharmappa@intel.com
Subject: [dpdk-dev] [PATCH v9 3/8] sched: update subport rate dynamically
Date: Fri,  9 Oct 2020 13:39:14 +0100	[thread overview]
Message-ID: <20201009123919.43004-4-savinay.dharmappa@intel.com> (raw)
In-Reply-To: <20201009123919.43004-1-savinay.dharmappa@intel.com>

Add support to update subport rate dynamically.

Signed-off-by: Savinay Dharmappa <savinay.dharmappa@intel.com>
---
 app/test/test_sched.c                    |   2 +-
 doc/guides/rel_notes/deprecation.rst     |   6 -
 doc/guides/rel_notes/release_20_11.rst   |   9 +
 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             | 415 ++++++++++-------------
 lib/librte_sched/rte_sched.h             |  13 +-
 8 files changed, 213 insertions(+), 247 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/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 584e72087..f7363a585 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -212,12 +212,6 @@ Deprecation Notices
   in "rte_sched.h". These changes are aligned to improvements suggested in the
   RFC https://mails.dpdk.org/archives/dev/2018-November/120035.html.
 
-* sched: To allow dynamic configuration of the subport bandwidth profile,
-  changes will be made to data structures ``rte_sched_subport_params``,
-  ``rte_sched_port_params`` and new data structure, API functions will be
-  defined in ``rte_sched.h``. These changes are aligned as suggested in the
-  RFC https://mails.dpdk.org/archives/dev/2020-July/175161.html
-
 * metrics: The function ``rte_metrics_init`` will have a non-void return
   in order to notify errors instead of calling ``rte_exit``.
 
diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 6968c27f6..85d56d46c 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -136,6 +136,12 @@ New Features
   * Extern objects and functions can be plugged into the pipeline.
   * Transaction-oriented table updates.
 
+* **Added support to update subport bandwidth dynamically.**
+
+   * Added new API ``rte_sched_port_subport_profile_add`` to add new
+     subport bandwidth profile to subport porfile table at runtime.
+
+   * Added support to update subport rate dynamically.
 
 Removed Items
 -------------
@@ -287,6 +293,9 @@ ABI Changes
 
   * Added new fields to ``struct rte_sched_subport_port_params``.
 
+  * Added ``subport_profile_id`` as a argument to function
+    ``rte_sched_subport_config``.
+
 Known Issues
 ------------
 
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..7c5688068 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;
 
@@ -151,16 +152,11 @@ 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;
@@ -174,6 +170,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;
@@ -834,18 +832,6 @@ rte_sched_subport_check_params(struct rte_sched_subport_params *params,
 		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;
-	}
-
 	/* qsize: if non-zero, power of 2,
 	 * no bigger than 32K (due to 16-bit read/write pointers)
 	 */
@@ -859,29 +845,8 @@ rte_sched_subport_check_params(struct rte_sched_subport_params *params,
 		}
 	}
 
-	for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
-		uint64_t tc_rate = params->tc_rate[i];
-		uint16_t qsize = params->qsize[i];
-
-		if ((qsize == 0 && tc_rate != 0) ||
-			(qsize != 0 && tc_rate == 0) ||
-			(tc_rate > params->tb_rate)) {
-			RTE_LOG(ERR, SCHED,
-				"%s: Incorrect value for tc rate\n", __func__);
-			return -EINVAL;
-		}
-	}
-
-	if (params->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 ||
-		params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) {
-		RTE_LOG(ERR, SCHED,
-			"%s: Incorrect qsize or 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__);
+	if (params->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) {
+		RTE_LOG(ERR, SCHED, "%s: Incorrect qsize\n", __func__);
 		return -EINVAL;
 	}
 
@@ -1098,48 +1063,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 +1081,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 +1106,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 +1294,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 +1335,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 +1385,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 +2174,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 +2193,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 +2211,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 +2224,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 +2260,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 +2278,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 +2807,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


  parent reply	other threads:[~2020-10-09 12:40 UTC|newest]

Thread overview: 107+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-15 18:27 [dpdk-dev] [RFC PATCH 0/2] Enable dyynamic configuration of subport bandwidth profile Savinay Dharmappa
2020-07-15 18:27 ` [dpdk-dev] [RFC PATCH 1/2] sched: add dynamic config " Savinay Dharmappa
2020-07-16  8:14   ` Singh, Jasvinder
2020-07-20 11:20   ` Dumitrescu, Cristian
2020-07-20 11:21     ` Dumitrescu, Cristian
2020-09-02  8:56   ` [dpdk-dev] [PATCH v1 1/4] " Savinay Dharmappa
2020-09-02  8:56     ` [dpdk-dev] [PATCH v1 2/4] " Savinay Dharmappa
2020-09-02  8:56     ` [dpdk-dev] [PATCH v1 3/4] " Savinay Dharmappa
2020-09-02  8:56     ` [dpdk-dev] [PATCH v1 4/4] " Savinay Dharmappa
2020-09-10 18:48     ` [dpdk-dev] [PATCH v2 00/10] Enable dynamic config of subport bandwidth Savinay Dharmappa
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 01/10] sched: add support profile data structure Savinay Dharmappa
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 02/10] sched: add subport profile table Savinay Dharmappa
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 03/10] sched: add subport profile add and config api Savinay Dharmappa
2020-09-14 14:05         ` Singh, Jasvinder
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 04/10] sched: update the grinder credit update function Savinay Dharmappa
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 05/10] sched: update the pipe config api implementation Savinay Dharmappa
2020-09-14 14:26         ` Singh, Jasvinder
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 06/10] example/qos_sched: add dynamic config of subport Savinay Dharmappa
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 07/10] example/ip_pipeline: " Savinay Dharmappa
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 08/10] drivers/softnic: " Savinay Dharmappa
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 09/10] app/test_sched: " Savinay Dharmappa
2020-09-10 18:48       ` [dpdk-dev] [PATCH v2 10/10] sched: remove the redundant code Savinay Dharmappa
2020-09-16 16:43       ` [dpdk-dev] [PATCH v3 0/9] Enable dynamic config of subport bandwidth Savinay Dharmappa
2020-09-16 16:43         ` [dpdk-dev] [PATCH v3 1/9] sched: add support profile data structure Savinay Dharmappa
2020-09-16 16:43         ` [dpdk-dev] [PATCH v3 2/9] sched: add subport profile table Savinay Dharmappa
2020-09-16 16:43         ` [dpdk-dev] [PATCH v3 3/9] sched: add subport profile add and config api Savinay Dharmappa
2020-09-16 16:43         ` [dpdk-dev] [PATCH v3 4/9] sched: update grinder credit and pipe config function Savinay Dharmappa
2020-09-16 16:43         ` [dpdk-dev] [PATCH v3 5/9] example/qos_sched: add dynamic config of subport Savinay Dharmappa
2020-09-16 16:43         ` [dpdk-dev] [PATCH v3 6/9] example/ip_pipeline: " Savinay Dharmappa
2020-09-16 16:43         ` [dpdk-dev] [PATCH v3 7/9] drivers/softnic: " Savinay Dharmappa
2020-09-16 16:43         ` [dpdk-dev] [PATCH v3 8/9] app/test_sched: " Savinay Dharmappa
2020-09-16 16:43         ` [dpdk-dev] [PATCH v3 9/9] sched: remove the redundant code Savinay Dharmappa
2020-09-17  8:42         ` [dpdk-dev] [PATCH v4 0/9] Enable dynamic config of subport bandwidth Savinay Dharmappa
2020-09-17  8:42           ` [dpdk-dev] [PATCH v4 1/9] sched: add support profile data structure Savinay Dharmappa
2020-09-17  8:42           ` [dpdk-dev] [PATCH v4 2/9] sched: add subport profile table Savinay Dharmappa
2020-09-17  8:42           ` [dpdk-dev] [PATCH v4 3/9] sched: add subport profile add and config api Savinay Dharmappa
2020-09-29 21:19             ` Dumitrescu, Cristian
2020-09-17  8:42           ` [dpdk-dev] [PATCH v4 4/9] sched: update grinder credit and pipe config function Savinay Dharmappa
2020-09-17  8:42           ` [dpdk-dev] [PATCH v4 5/9] example/qos_sched: add dynamic config of subport Savinay Dharmappa
2020-09-17  8:42           ` [dpdk-dev] [PATCH v4 6/9] example/ip_pipeline: " Savinay Dharmappa
2020-09-29 21:23             ` Dumitrescu, Cristian
2020-09-17  8:42           ` [dpdk-dev] [PATCH v4 7/9] drivers/softnic: " Savinay Dharmappa
2020-09-17  8:42           ` [dpdk-dev] [PATCH v4 8/9] app/test_sched: " Savinay Dharmappa
2020-09-17  8:42           ` [dpdk-dev] [PATCH v4 9/9] sched: remove the redundant code Savinay Dharmappa
2020-09-30 19:24           ` [dpdk-dev] [PATCH v5 0/9] Enable dynamic config of subport bandwidth Savinay Dharmappa
2020-09-30 19:24             ` [dpdk-dev] [PATCH v5 1/9] sched: add support profile table Savinay Dharmappa
2020-09-30 19:24             ` [dpdk-dev] [PATCH v5 2/9] sched: add subport profile add api Savinay Dharmappa
2020-09-30 19:24             ` [dpdk-dev] [PATCH v5 3/9] sched : add dynamic config of subport bandwidth Savinay Dharmappa
2020-09-30 19:24             ` [dpdk-dev] [PATCH v5 4/9] sched: update grinder credit and pipe config function Savinay Dharmappa
2020-09-30 19:24             ` [dpdk-dev] [PATCH v5 5/9] example/qos_sched: add dynamic config of subport Savinay Dharmappa
2020-09-30 19:24             ` [dpdk-dev] [PATCH v5 6/9] example/ip_pipeline: " Savinay Dharmappa
2020-09-30 19:24             ` [dpdk-dev] [PATCH v5 7/9] drivers/softnic: " Savinay Dharmappa
2020-09-30 19:24             ` [dpdk-dev] [PATCH v5 8/9] app/test_sched: " Savinay Dharmappa
2020-09-30 19:24             ` [dpdk-dev] [PATCH v5 9/9] sched : remove redundant code Savinay Dharmappa
2020-10-06 15:27             ` [dpdk-dev] [PATCH v6 0/8] Enable dynamic config of subport bandwidth Savinay Dharmappa
2020-10-06 15:27               ` [dpdk-dev] [PATCH v6 1/8] sched: add support profile table Savinay Dharmappa
2020-10-06 15:27               ` [dpdk-dev] [PATCH v6 2/8] sched: introduce subport profile add function Savinay Dharmappa
2020-10-06 15:27               ` [dpdk-dev] [PATCH v6 3/8] sched: update subport rate dynamically Savinay Dharmappa
2020-10-06 15:27               ` [dpdk-dev] [PATCH v6 4/8] example/qos_sched: " Savinay Dharmappa
2020-10-06 15:27               ` [dpdk-dev] [PATCH v6 5/8] example/ip_pipeline: " Savinay Dharmappa
2020-10-06 15:27               ` [dpdk-dev] [PATCH v6 6/8] drivers/softnic: " Savinay Dharmappa
2020-10-06 15:27               ` [dpdk-dev] [PATCH v6 7/8] app/test_sched: " Savinay Dharmappa
2020-10-06 15:27               ` [dpdk-dev] [PATCH v6 8/8] sched: remove redundant code Savinay Dharmappa
2020-10-06 15:52               ` [dpdk-dev] [PATCH v6 0/8] Enable dynamic config of subport bandwidth Dumitrescu, Cristian
2020-10-06 18:02               ` [dpdk-dev] [PATCH v7 " Savinay Dharmappa
2020-10-06 18:02                 ` [dpdk-dev] [PATCH v7 1/8] sched: add support profile table Savinay Dharmappa
2020-10-06 18:02                 ` [dpdk-dev] [PATCH v7 2/8] sched: introduce subport profile add function Savinay Dharmappa
2020-10-06 18:02                 ` [dpdk-dev] [PATCH v7 3/8] sched: update subport rate dynamically Savinay Dharmappa
2020-10-06 18:02                 ` [dpdk-dev] [PATCH v7 4/8] example/qos_sched: " Savinay Dharmappa
2020-10-06 18:02                 ` [dpdk-dev] [PATCH v7 5/8] example/ip_pipeline: " Savinay Dharmappa
2020-10-06 18:02                 ` [dpdk-dev] [PATCH v7 6/8] drivers/softnic: " Savinay Dharmappa
2020-10-06 18:02                 ` [dpdk-dev] [PATCH v7 7/8] app/test_sched: " Savinay Dharmappa
2020-10-06 18:02                 ` [dpdk-dev] [PATCH v7 8/8] sched: remove redundant code Savinay Dharmappa
2020-10-06 19:05                 ` [dpdk-dev] [PATCH v7 0/8] Enable dynamic config of subport bandwidth Dumitrescu, Cristian
2020-10-07 14:09                 ` [dpdk-dev] [PATCH v8 " Savinay Dharmappa
2020-10-07 14:09                   ` [dpdk-dev] [PATCH v8 1/8] sched: add support profile table Savinay Dharmappa
2020-10-07 14:09                   ` [dpdk-dev] [PATCH v8 2/8] sched: introduce subport profile add function Savinay Dharmappa
2020-10-07 14:09                   ` [dpdk-dev] [PATCH v8 3/8] sched: update subport rate dynamically Savinay Dharmappa
2020-10-07 14:09                   ` [dpdk-dev] [PATCH v8 4/8] example/qos_sched: " Savinay Dharmappa
2020-10-07 14:09                   ` [dpdk-dev] [PATCH v8 5/8] example/ip_pipeline: " Savinay Dharmappa
2020-10-07 14:09                   ` [dpdk-dev] [PATCH v8 6/8] drivers/softnic: " Savinay Dharmappa
2020-10-07 14:09                   ` [dpdk-dev] [PATCH v8 7/8] app/test_sched: " Savinay Dharmappa
2020-10-07 14:09                   ` [dpdk-dev] [PATCH v8 8/8] sched: remove redundant code Savinay Dharmappa
2020-10-09  8:28                     ` Thomas Monjalon
2020-10-09 12:39                   ` [dpdk-dev] [PATCH v9 0/8] Enable dynamic config of subport bandwidth Savinay Dharmappa
2020-10-09 12:39                     ` [dpdk-dev] [PATCH v9 1/8] sched: add support profile table Savinay Dharmappa
2020-10-09 12:39                     ` [dpdk-dev] [PATCH v9 2/8] sched: introduce subport profile add function Savinay Dharmappa
2020-10-09 12:39                     ` Savinay Dharmappa [this message]
2020-10-09 12:39                     ` [dpdk-dev] [PATCH v9 4/8] example/qos_sched: update subport rate dynamically Savinay Dharmappa
2020-10-09 12:39                     ` [dpdk-dev] [PATCH v9 5/8] example/ip_pipeline: " Savinay Dharmappa
2020-10-09 12:39                     ` [dpdk-dev] [PATCH v9 6/8] drivers/softnic: " Savinay Dharmappa
2020-10-09 12:39                     ` [dpdk-dev] [PATCH v9 7/8] app/test_sched: " Savinay Dharmappa
2020-10-09 12:39                     ` [dpdk-dev] [PATCH v9 8/8] sched: remove redundant code Savinay Dharmappa
2020-10-11 20:11                     ` [dpdk-dev] [PATCH v9 0/8] Enable dynamic config of subport bandwidth Thomas Monjalon
2020-10-12  5:24                       ` Dharmappa, Savinay
2020-10-12 23:08                         ` Dharmappa, Savinay
2020-10-13 13:56                           ` Dharmappa, Savinay
2020-10-13 14:06                             ` Thomas Monjalon
2020-10-15  0:17                     ` Thomas Monjalon
2020-07-15 18:27 ` [dpdk-dev] [RFC PATCH 2/2] example/qos_sched: subport bandwidth profile config Savinay Dharmappa
2020-07-16  8:14   ` Singh, Jasvinder
2020-09-02  9:07   ` [dpdk-dev] [PATCH v1 1/4] example/qos_sched: subport bandwidth dynmaic conf Savinay Dharmappa
2020-09-02  9:07     ` [dpdk-dev] [PATCH v1 2/4] example/ip_pipeline: " Savinay Dharmappa
2020-09-02  9:07     ` [dpdk-dev] [PATCH v1 3/4] drivers/softnic: subport bandwidth profile config Savinay Dharmappa
2020-09-02  9:07     ` [dpdk-dev] [PATCH v1 4/4] app/test_sched: " Savinay Dharmappa
2020-09-02 10:46     ` [dpdk-dev] [PATCH v1 1/4] example/qos_sched: subport bandwidth dynmaic conf Dharmappa, Savinay
2020-07-16  8:14 ` [dpdk-dev] [RFC PATCH 0/2] Enable dyynamic configuration of subport bandwidth profile Singh, Jasvinder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201009123919.43004-4-savinay.dharmappa@intel.com \
    --to=savinay.dharmappa@intel.com \
    --cc=cristian.dumitrescu@intel.com \
    --cc=dev@dpdk.org \
    --cc=jasvinder.singh@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.