RTE scheduler fixes
cover RTE scheduler fixes
These patches address a number of issues found during development and testing of QoS in Vyatta 5600 router.
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_sreturn -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_porif (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" );
PATCH 2/3 rte_sched: fix compile if DEBUG enabled
In reply to Stephen HemmingerFix 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); }
PATCH 3/3 rte_sched: fix grinder bug
In reply to Stephen HemmingerThe 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
Thomas Monjalon
Acked-by2014-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