Although implementation (linux-generic) is using the API calls, it can do short
cuts e.g. ensure that queue_enq will never fail (abort instead of fail) and
then exploit that knowledge. The implementation gets more complex if any "API
call" it uses can fail as specified by the API spec.
> --- a/platform/linux-generic/odp_queue.c
> +++ b/platform/linux-generic/odp_queue.c
> @@ -355,8 +355,8 @@ int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t
> *buf_hdr)
> UNLOCK(&queue->s.lock);
>
> /* Add queue to scheduling */
> - if (sched)
> - schedule_queue(queue);
> + if (sched && schedule_queue(queue))
> + return -1;
For example here, the event has been already inserted to the queue (linked
list) and this last bit activates scheduling if needed. A this point
odp_queue_enq() cannot return "failure" without removing the event from list
first. Otherwise both the user and the queue has ownership of the event. Next
user would free it and the queue (linked list) is corrupted.
>
> return 0;
> }
> @@ -395,8 +395,8 @@ int queue_enq_multi(queue_entry_t *queue,
> odp_buffer_hdr_t *buf_hdr[], int num)
> UNLOCK(&queue->s.lock);
>
> /* Add queue to scheduling */
> - if (sched)
> - schedule_queue(queue);
> + if (sched && schedule_queue(queue))
> + return -1;
>
Same here, too late to just return fail.
> return num; /* All events enqueued */
> }
> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-
> generic/odp_schedule.c
> index 9206d5c..9e20fda 100644
> --- a/platform/linux-generic/odp_schedule.c
> +++ b/platform/linux-generic/odp_schedule.c
> @@ -355,7 +355,10 @@ int schedule_pktio_start(odp_pktio_t pktio, int prio)
>
> pri_queue = pri_set_pktio(pktio, prio);
>
> - odp_queue_enq(pri_queue, odp_buffer_to_event(buf));
> + if (odp_queue_enq(pri_queue, odp_buffer_to_event(buf))) {
> + odp_buffer_free(buf);
> + return -1;
> + }
>
> return 0;
> }
> @@ -365,7 +368,8 @@ void odp_schedule_release_atomic(void)
> if (sched_local.pri_queue != ODP_QUEUE_INVALID &&
> sched_local.num == 0) {
> /* Release current atomic queue */
> - odp_queue_enq(sched_local.pri_queue, sched_local.cmd_ev);
> + if (odp_queue_enq(sched_local.pri_queue, sched_local.cmd_ev))
> + odp_event_free(sched_local.cmd_ev);
If this happens the atomic queue is (silently) deadlocked. Schedule queues
should never fail, just crash/abort.
> sched_local.pri_queue = ODP_QUEUE_INVALID;
> }
> }
> @@ -456,7 +460,8 @@ static int schedule(odp_queue_t *out_queue,
> odp_event_t out_ev[],
> odp_buffer_free(buf);
> } else {
> /* Continue scheduling the pktio */
> - odp_queue_enq(pri_q, ev);
> + if (odp_queue_enq(pri_q, ev))
> + odp_event_free(ev);
Pktio is deadlocked...
> }
>
> continue;
> @@ -487,7 +492,8 @@ static int schedule(odp_queue_t *out_queue,
> odp_event_t out_ev[],
> sched_local.cmd_ev = ev;
> } else {
> /* Continue scheduling the queue */
> - odp_queue_enq(pri_q, ev);
> + if (odp_queue_enq(pri_q, ev))
> + odp_event_free(ev);
Queue is never scheduled again...
-Petri
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp