vlib: Handle race in thread barrier processing
When CLIB_DEBUG is enabled, vlib_foreach_main macro asserts that
vlib_main it currently looks at is safely parked in barrier, by
checkling that vlib_main->parked_at_barrier is not 0.
Unfortunately, the check is racy - workers first increment the
atomic counter to indicate that they have reached the barrier
and _then_ set this_main->parked_at_barrier to 1. For the last
worker to suspend this opens the race - main thread is free
to execute and assert immediately after atomic counter has been
incremented, before worker gets to write to own parked_at_barrier.
Fix this by simply swapping the order of two operations.
Type: fix
Signed-off-by: Alexnader Kabaev <kan@FreeBSD.org>
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
Change-Id: Iae47abd6ca0be1c5413f5ecaefabc64cd7eac2ed
(cherry picked from commit feda545105
)
This commit is contained in:

committed by
Andrew Yourtchenko

parent
f821dd7990
commit
ccdd73e636
@ -416,12 +416,12 @@ vlib_worker_thread_barrier_check (void)
|
|||||||
ed->thread_index = thread_index;
|
ed->thread_index = thread_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
clib_atomic_fetch_add (vlib_worker_threads->workers_at_barrier, 1);
|
|
||||||
if (CLIB_DEBUG > 0)
|
if (CLIB_DEBUG > 0)
|
||||||
{
|
{
|
||||||
vm = vlib_get_main ();
|
vm = vlib_get_main ();
|
||||||
vm->parked_at_barrier = 1;
|
vm->parked_at_barrier = 1;
|
||||||
}
|
}
|
||||||
|
clib_atomic_fetch_add (vlib_worker_threads->workers_at_barrier, 1);
|
||||||
while (*vlib_worker_threads->wait_at_barrier)
|
while (*vlib_worker_threads->wait_at_barrier)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user