Skip to contentSkip to conversation

RTE scheduler fixes

PATCH In review Stephen Hemminger 2 participants 5 messages May 14, 2014 – May 22, 2014 1 message not in the archive

lore
Share & tools
lore
#0 lore raw

cover RTE scheduler fixes

These patches address a number of issues found during development and testing of QoS in Vyatta 5600 router.

#1 lore raw

PATCH 1/3 qos: use rte_zmalloc instead of memzone for allocation

The existing rte scheduler can only be safely configured once per port because a memory zone has a fixed size once it is created and can never be freed or change in size.

This patch changes the scheduler to use rte_malloc instead. This allows for a port to be reconfigured by doing rte_sched_port_free followed rte_sched_port_config.

The patch also removes the now unused name parameter from the port parameters structure.

---
 app/test/test_sched.c        |    2 --
 lib/librte_sched/rte_sched.c |   29 ++++++-----------------------
 2 files changed, 6 insertions(+), 25 deletions(-)
lib/librte_sched/rte_sched.c +6 -23
@@ -37,7 +37,7 @@
 #include <rte_common.h>
 #include <rte_log.h>
 #include <rte_memory.h>
-#include <rte_memzone.h>
+#include <rte_malloc.h>
 #include <rte_cycles.h>
 #include <rte_prefetch.h>
 #include <rte_branch_prediction.h>
@@ -306,11 +306,6 @@ rte_sched_port_check_params(struct rte_s
 		return -1;
 	}
 	
-	/* name */
-	if (params->name == NULL) {
-		return -2;
-	}
-	
 	/* socket */
 	if ((params->socket < 0) || (params->socket >= RTE_MAX_NUMA_NODES)) {
 		return -3;
@@ -613,7 +608,6 @@ struct rte_sched_port *
 rte_sched_port_config(struct rte_sched_port_params *params)
 {
 	struct rte_sched_port *port = NULL;
-	const struct rte_memzone *mz = NULL;
 	uint32_t mem_size, bmp_mem_size, n_queues_per_port, i;
 	
 	/* Check user parameters. Determine the amount of memory to allocate */
@@ -623,21 +617,10 @@ rte_sched_port_config(struct rte_sched_p
 	}
 	
 	/* Allocate memory to store the data structures */
-	mz = rte_memzone_lookup(params->name);
-	if (mz) {
-		/* Use existing memzone, provided that its size is big enough */
-		if (mz->len < mem_size) {
-			return NULL;
-		}
-	} else {
-		/* Create new memzone */
-		mz = rte_memzone_reserve(params->name, mem_size, params->socket, 0);		
-		if (mz == NULL) {
-			return NULL;
-		}
+	port = rte_zmalloc("qos_params", mem_size, CACHE_LINE_SIZE);
+	if (port == NULL) {
+		return NULL;
 	}
-	memset(mz->addr, 0, mem_size);
-	port = (struct rte_sched_port *) mz->addr;
 
 	/* User parameters */
 	port->n_subports_per_port = params->n_subports_per_port;
@@ -716,9 +699,9 @@ rte_sched_port_free(struct rte_sched_por
 	if (port == NULL){
 		return;
 	}
+
 	rte_bitmap_free(port->bmp);
-	
-	return;
+	rte_free(port);
 }
 
 static void
app/test/test_sched.c +0 -2
@@ -83,7 +83,6 @@ static struct rte_sched_pipe_params pipe
 };
 
 static struct rte_sched_port_params port_param = {
-	.name = "port_0",
 	.socket = 0, /* computed */
 	.rate = 0, /* computed */
 	.mtu = 1522,
@@ -172,7 +171,6 @@ test_sched(void)
 
 	port_param.socket = 0;
 	port_param.rate = (uint64_t) 10000 * 1000 * 1000 / 8;
-	port_param.name = "port_0";
 
 	port = rte_sched_port_config(&port_param);
 	VERIFY(port != NULL, "Error config sched port\n");
#2 lore raw

PATCH 2/3 rte_sched: fix compile if DEBUG enabled

In reply to Stephen Hemminger

Fix build error if RTE_SCHED_DEBUG is enabled.

---
 lib/librte_sched/rte_sched.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
lib/librte_sched/rte_sched.c +1 -1
@@ -1001,7 +1001,7 @@ rte_sched_port_queue_is_full(struct rte_
 {
 	struct rte_sched_queue *queue = port->queue + qindex;
 	uint16_t qsize = rte_sched_port_qsize(port, qindex);
-	uint16_t qlen = q->qw - q->qr;
+	uint16_t qlen = queue->qw - queue->qr;
 	
 	return (qlen >= qsize);
 }
#3 lore raw

PATCH 3/3 rte_sched: fix grinder bug

In reply to Stephen Hemminger

The rte_scheduler will get stuck and not deliver any more packets if there are two active subports and then one of them stops enqueing more packets. This is because of abug in how the grinder state machines are managed.

If a non-zero grinder is assigned (but not yet active), then the dequeue would miss it and always return zero packets. The cure is to always do a first pass over all grinders.

---
 lib/librte_sched/rte_sched.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
lib/librte_sched/rte_sched.c +4 -3
@@ -2113,12 +2113,12 @@ rte_sched_port_time_resync(struct rte_sc
 }
 
 static inline int
-rte_sched_port_exceptions(struct rte_sched_port *port)
+rte_sched_port_exceptions(struct rte_sched_port *port, int second_pass)
 {
 	int exceptions;
 
 	/* Check if any exception flag is set */
-	exceptions = (port->busy_grinders == 0) ||
+	exceptions = (second_pass && port->busy_grinders == 0) ||
 		(port->pipe_exhaustion == 1);
 	
 	/* Clear exception flags */
@@ -2140,7 +2140,8 @@ rte_sched_port_dequeue(struct rte_sched_
 	/* Take each queue in the grinder one step further */
 	for (i = 0, count = 0; ; i ++)  {
 		count += grinder_handle(port, i & (RTE_SCHED_PORT_N_GRINDERS - 1));
-		if ((count == n_pkts) || rte_sched_port_exceptions(port)) {
+		if ((count == n_pkts) ||
+		    rte_sched_port_exceptions(port, i >= RTE_SCHED_PORT_N_GRINDERS)) {
 			break;
 		}
 	}

A message that is not in the archive (sent off-list or not yet received): 20140514162524.113765980-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ@public.gmane.org

#5 lore raw

2014-05-14 09:25, Stephen Hemminger:

Quoted 2 lines

These patches address a number of issues found during development and testing of QoS in Vyatta 5600 router.

Applied for version 1.7.0.

Thanks

Signature · 1 line
Thomas