futex: Rework futex_lock_pi() to use rt_mutex_*_proxy_lock()
authorPeter Zijlstra <peterz@infradead.org>
Wed, 22 Mar 2017 10:35:58 +0000 (11:35 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 23 Mar 2017 18:10:09 +0000 (19:10 +0100)
commitcfafcd117da0216520568c195cb2f6cd1980c4bb
treecce98f12a6bfa27515fb1cabc5bbd6fd55a8459f
parent38d589f2fd08f1296aea3ce62bebd185125c6d81
futex: Rework futex_lock_pi() to use rt_mutex_*_proxy_lock()

By changing futex_lock_pi() to use rt_mutex_*_proxy_lock() all wait_list
modifications are done under both hb->lock and wait_lock.

This closes the obvious interleave pattern between futex_lock_pi() and
futex_unlock_pi(), but not entirely so. See below:

Before:

futex_lock_pi() futex_unlock_pi()
  unlock hb->lock

  lock hb->lock
  unlock hb->lock

  lock rt_mutex->wait_lock
  unlock rt_mutex_wait_lock
    -EAGAIN

  lock rt_mutex->wait_lock
  list_add
  unlock rt_mutex->wait_lock

  schedule()

  lock rt_mutex->wait_lock
  list_del
  unlock rt_mutex->wait_lock

  <idem>
    -EAGAIN

  lock hb->lock

After:

futex_lock_pi() futex_unlock_pi()

  lock hb->lock
  lock rt_mutex->wait_lock
  list_add
  unlock rt_mutex->wait_lock
  unlock hb->lock

  schedule()
  lock hb->lock
  unlock hb->lock
  lock hb->lock
  lock rt_mutex->wait_lock
  list_del
  unlock rt_mutex->wait_lock

  lock rt_mutex->wait_lock
  unlock rt_mutex_wait_lock
    -EAGAIN

  unlock hb->lock

It does however solve the earlier starvation/live-lock scenario which got
introduced with the -EAGAIN since unlike the before scenario; where the
-EAGAIN happens while futex_unlock_pi() doesn't hold any locks; in the
after scenario it happens while futex_unlock_pi() actually holds a lock,
and then it is serialized on that lock.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: juri.lelli@arm.com
Cc: bigeasy@linutronix.de
Cc: xlpang@redhat.com
Cc: rostedt@goodmis.org
Cc: mathieu.desnoyers@efficios.com
Cc: jdesfossez@efficios.com
Cc: dvhart@infradead.org
Cc: bristot@redhat.com
Link: http://lkml.kernel.org/r/20170322104152.062785528@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
kernel/futex.c
kernel/locking/rtmutex.c
kernel/locking/rtmutex_common.h