sched: fix grinder bug
authorStephen Hemminger <stephen@networkplumber.org>
Wed, 14 May 2014 16:25:27 +0000 (09:25 -0700)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Thu, 22 May 2014 14:14:36 +0000 (16:14 +0200)
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 a bug 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.

Signed-off-by: Stephen Hemminger <shemming@brocade.com>
Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>
lib/librte_sched/rte_sched.c

index 0403b7a..2625662 100644 (file)
@@ -2113,12 +2113,12 @@ rte_sched_port_time_resync(struct rte_sched_port *port)
 }
 
 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_port *port, struct rte_mbuf **pkts, uint
        /* 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;
                }
        }