Fix: urcu-wait: futex wait: handle spurious futex wakeups
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 22 Jun 2022 20:44:12 +0000 (16:44 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 27 Jun 2022 14:30:13 +0000 (10:30 -0400)
commit71693131550753be0fcd2b2d4175b53c697be5a3
tree22b7848c9df92eb9d482ce2f46a2b91657bce05d
parent879a3e166178d16b2ffedc73899904d52285cfe8
Fix: urcu-wait: futex wait: handle spurious futex wakeups

Observed issue
==============

The urcu-wait urcu_adaptative_busy_wait() implements a futex wait/wakeup
scheme similar to the workqueue code, which has an issue with spurious
wakeups.

A spurious wakeup on urcu_adaptative_busy_wait can cause
urcu_adaptative_busy_wait to reach label skip_futex_wait with a
wait->state state of URCU_WAIT_WAITING, which is unexpected. It would
cause busy-waiting on URCU_WAIT_TEARDOWN state to start early. The
wait-teardown stage is done with URCU_WAIT_ATTEMPTS active attempts,
following by attempts spaced by 10ms sleeps. I do not expect that these
spurious wakeups will cause user-observable effects other than being
slightly less efficient that it should be.

urcu-wait is used by all urcu flavor's synchronize_rcu() to implement
the grace period batching scheme.

This issue will cause spurious unexpected high CPU use, but will not
lead to data corruption.

Cause
=====

From futex(5):

       FUTEX_WAIT
              Returns 0 if the caller was woken up.  Note that a  wake-up  can
              also  be caused by common futex usage patterns in unrelated code
              that happened to have previously used the  futex  word's  memory
              location  (e.g., typical futex-based implementations of Pthreads
              mutexes can cause this under some conditions).  Therefore, call‐
              ers should always conservatively assume that a return value of 0
              can mean a spurious wake-up, and  use  the  futex  word's  value
              (i.e.,  the user-space synchronization scheme) to decide whether
              to continue to block or not.

Solution
========

We therefore need to validate whether the value differs from
URCU_WAIT_WAITING in user-space after the call to FUTEX_WAIT returns 0.

Known drawbacks
===============

None.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I8e9586597f091efc633f3310a68d18b0bd8de1e0
src/urcu-wait.h
This page took 0.02501 seconds and 4 git commands to generate.