From 5cdd039a6bcecae79d1fad0f2b4d52ad43c8e6d5 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Thu, 3 Sep 2015 10:16:39 -0500 Subject: linux-generic: schedule: fix race condition in ordered locks Correct race condition that arises due to attempt to permit ordered locks to be reusable. For now, ordered locks can only be used once per scheduled event. Signed-off-by: Bill Fischofer Reviewed-and-Tested-by: Maxim Uvarov Signed-off-by: Maxim Uvarov --- platform/linux-generic/include/odp_queue_internal.h | 6 +++++- platform/linux-generic/odp_queue.c | 8 +------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h index 48576bc..0f30965 100644 --- a/platform/linux-generic/include/odp_queue_internal.h +++ b/platform/linux-generic/include/odp_queue_internal.h @@ -193,8 +193,12 @@ static inline void reorder_enq(queue_entry_t *queue, static inline void order_release(queue_entry_t *origin_qe, int count) { + uint64_t sync = odp_atomic_load_u64(&origin_qe->s.sync_out); + origin_qe->s.order_out += count; - odp_atomic_fetch_add_u64(&origin_qe->s.sync_out, count); + if (sync < origin_qe->s.order_out) + odp_atomic_fetch_add_u64(&origin_qe->s.sync_out, + origin_qe->s.order_out - sync); } static inline int reorder_deq(queue_entry_t *queue, diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c index 15abd93..ac933da 100644 --- a/platform/linux-generic/odp_queue.c +++ b/platform/linux-generic/odp_queue.c @@ -999,12 +999,6 @@ void odp_schedule_order_unlock(odp_schedule_order_lock_t *lock ODP_UNUSED) if (!origin_qe) return; - /* Get a new sync order for reusability, and release the lock. Note - * that this must be done in this sequence to prevent race conditions - * where the next waiter could lock and unlock before we're able to - * get a new sync order since that would cause order inversion on - * subsequent locks we may perform in this ordered context. - */ - *sync = odp_atomic_fetch_inc_u64(&origin_qe->s.sync_in); + /* Release the ordered lock */ odp_atomic_fetch_inc_u64(&origin_qe->s.sync_out); } -- cgit v1.2.3