@@ -48,6 +48,22 @@ typedef struct queue_table_t {
static queue_table_t *queue_tbl;
+static inline void get_qe_locks(queue_entry_t *qe1, queue_entry_t *qe2)
+{
+ int i;
+
+ while (1) {
+ for (i = 0; i < 10; i++) {
+ LOCK(&qe1->s.lock);
+ if (LOCK_TRY(&qe2->s.lock))
+ return;
+ UNLOCK(&qe1->s.lock);
+ odp_sync_stores();
+ }
+ sched_yield();
+ }
+}
+
queue_entry_t *get_qentry(uint32_t queue_id)
{
return &queue_tbl->queue[queue_id];
@@ -370,11 +386,7 @@ int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr, int sustain)
/* Need two locks for enq operations from ordered queues */
if (origin_qe) {
- LOCK(&origin_qe->s.lock);
- while (!LOCK_TRY(&queue->s.lock)) {
- UNLOCK(&origin_qe->s.lock);
- LOCK(&origin_qe->s.lock);
- }
+ get_qe_locks(origin_qe, queue);
if (odp_unlikely(origin_qe->s.status < QUEUE_STATUS_READY)) {
UNLOCK(&queue->s.lock);
UNLOCK(&origin_qe->s.lock);
To avoid deadlock, especially on unicore systems, force an explicit yield while not holding either lock when attempting to acquire multiple locks for ordered queue processing. This addresses the aspect of Bug https://bugs.linaro.org/show_bug.cgi?id=1879 relating to deadlock in unicore systems. Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org> --- platform/linux-generic/odp_queue.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)