Tested-by: Brian Brooks <[email protected]>

On 08/15 15:21:41, Petri Savolainen wrote:
> Empty queues are kept in scheduler priority queues for
> performance reasons. The scheduler moved to the next priority
> queue after seeing an empty queue, which resulted sometimes
> scheduler to return zero events, although there were events
> available deeper in the priority queue.
> 
> This patch keeps scheduler scheduling a priority queue until an
> event is found or the queue is empty (over empty or destroyed
> queues).
> 
> This fixes bug https://bugs.linaro.org/show_bug.cgi?id=2457
> 
> Signed-off-by: Petri Savolainen <[email protected]>
> ---
>  platform/linux-generic/odp_schedule.c | 24 +++++++++++++++++++-----
>  1 file changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/platform/linux-generic/odp_schedule.c 
> b/platform/linux-generic/odp_schedule.c
> index 8405423..e08de54 100644
> --- a/platform/linux-generic/odp_schedule.c
> +++ b/platform/linux-generic/odp_schedule.c
> @@ -552,7 +552,7 @@ static int do_schedule(odp_queue_t *out_queue, 
> odp_event_t out_ev[],
>  
>               id = (sched_local.thr + offset) & (QUEUES_PER_PRIO - 1);
>  
> -             for (j = 0; j < QUEUES_PER_PRIO; j++, id++) {
> +             for (j = 0; j < QUEUES_PER_PRIO;) {
>                       odp_queue_t  pri_q;
>                       int num;
>                       int grp;
> @@ -562,14 +562,23 @@ static int do_schedule(odp_queue_t *out_queue, 
> odp_event_t out_ev[],
>                       if (id >= QUEUES_PER_PRIO)
>                               id = 0;
>  
> -                     if (odp_unlikely((sched->pri_mask[i] & (1 << id)) == 0))
> +                     /* No queues created for this priority queue */
> +                     if (odp_unlikely((sched->pri_mask[i] & (1 << id))
> +                         == 0)) {
> +                             j++;
> +                             id++;
>                               continue;
> +                     }
>  
>                       pri_q = sched->pri_queue[i][id];
>                       ev    = odp_queue_deq(pri_q);
>  
> -                     if (ev == ODP_EVENT_INVALID)
> +                     /* Priority queue empty */
> +                     if (ev == ODP_EVENT_INVALID) {
> +                             j++;
> +                             id++;
>                               continue;
> +                     }
>  
>                       buf       = odp_buffer_from_event(ev);
>                       sched_cmd = odp_buffer_addr(buf);
> @@ -584,6 +593,9 @@ static int do_schedule(odp_queue_t *out_queue, 
> odp_event_t out_ev[],
>                                */
>                               if (odp_queue_enq(pri_q, ev))
>                                       ODP_ABORT("schedule failed\n");
> +
> +                             j++;
> +                             id++;
>                               continue;
>                       }
>  
> @@ -600,13 +612,15 @@ static int do_schedule(odp_queue_t *out_queue, 
> odp_event_t out_ev[],
>                                                      max_deq);
>  
>                       if (num < 0) {
> -                             /* Destroyed queue */
> +                             /* Destroyed queue. Continue scheduling the same
> +                              * priority queue. */
>                               sched_cb_queue_destroy_finalize(qi);
>                               continue;
>                       }
>  
>                       if (num == 0) {
> -                             /* Remove empty queue from scheduling */
> +                             /* Remove empty queue from scheduling. Continue
> +                              * scheduling the same priority queue. */
>                               continue;
>                       }
>  
> -- 
> 2.8.1
> 

Reply via email to