diff options
author | Andy Lutomirski <luto@kernel.org> | 2020-12-04 08:07:06 +0300 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2020-12-09 11:37:43 +0300 |
commit | e45cdc71d1fa5ac3a57b23acc31eb959e4f60135 (patch) | |
tree | a49ce2b7a17945b7c43cb9d5e34d881bcd5d4735 /net/dccp | |
parent | 758c9373d84168dc7d039cf85a0e920046b17b41 (diff) | |
download | linux-e45cdc71d1fa5ac3a57b23acc31eb959e4f60135.tar.xz |
membarrier: Execute SYNC_CORE on the calling thread
membarrier()'s MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE is documented as
syncing the core on all sibling threads but not necessarily the calling
thread. This behavior is fundamentally buggy and cannot be used safely.
Suppose a user program has two threads. Thread A is on CPU 0 and thread B
is on CPU 1. Thread A modifies some text and calls
membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE).
Then thread B executes the modified code. If, at any point after
membarrier() decides which CPUs to target, thread A could be preempted and
replaced by thread B on CPU 0. This could even happen on exit from the
membarrier() syscall. If this happens, thread B will end up running on CPU
0 without having synced.
In principle, this could be fixed by arranging for the scheduler to issue
sync_core_before_usermode() whenever switching between two threads in the
same mm if there is any possibility of a concurrent membarrier() call, but
this would have considerable overhead. Instead, make membarrier() sync the
calling CPU as well.
As an optimization, this avoids an extra smp_mb() in the default
barrier-only mode and an extra rseq preempt on the caller.
Fixes: 70216e18e519 ("membarrier: Provide core serializing command, *_SYNC_CORE")
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://lore.kernel.org/r/250ded637696d490c69bef1877148db86066881c.1607058304.git.luto@kernel.org
Diffstat (limited to 'net/dccp')
0 files changed, 0 insertions, 0 deletions