diff mbox

[API-NEXT] linux-generic: queue: yield trying to obtain multiple locks

Message ID 1446219874-30024-1-git-send-email-bill.fischofer@linaro.org
State New
Headers show

Commit Message

Bill Fischofer Oct. 30, 2015, 3:44 p.m. UTC
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(-)
diff mbox

Patch

diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index a27af0b..4251c7c 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -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);