1. Jan 21, 2019
    • Peter Zijlstra's avatar
      futex: Fix (possible) missed wakeup · b061c38b
      Peter Zijlstra authored
      We must not rely on wake_q_add() to delay the wakeup; in particular
      commit:
      
        1d0dcb3a
      
       ("futex: Implement lockless wakeups")
      
      moved wake_q_add() before smp_store_release(&q->lock_ptr, NULL), which
      could result in futex_wait() waking before observing ->lock_ptr ==
      NULL and going back to sleep again.
      
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Fixes: 1d0dcb3a
      
       ("futex: Implement lockless wakeups")
      Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
      b061c38b
    • Peter Zijlstra's avatar
      sched/wake_q: Fix wakeup ordering for wake_q · 4c4e3731
      Peter Zijlstra authored
      
      
      Notable cmpxchg() does not provide ordering when it fails, however
      wake_q_add() requires ordering in this specific case too. Without this
      it would be possible for the concurrent wakeup to not observe our
      prior state.
      
      Andrea Parri provided:
      
        C wake_up_q-wake_q_add
      
        {
      	int next = 0;
      	int y = 0;
        }
      
        P0(int *next, int *y)
        {
      	int r0;
      
      	/* in wake_up_q() */
      
      	WRITE_ONCE(*next, 1);   /* node->next = NULL */
      	smp_mb();               /* implied by wake_up_process() */
      	r0 = READ_ONCE(*y);
        }
      
        P1(int *next, int *y)
        {
      	int r1;
      
      	/* in wake_q_add() */
      
      	WRITE_ONCE(*y, 1);      /* wake_cond = true */
      	smp_mb__before_atomic();
      	r1 = cmpxchg_relaxed(next, 1, 2);
        }
      
        exists (0:r0=0 /\ 1:r1=0)
      
        This "exists" clause cannot be satisfied according to the LKMM:
      
        Test wake_up_q-wake_q_add Allowed
        States 3
        0:r0=0; 1:r1=1;
        0:r0=1; 1:r1=0;
        0:r0=1; 1:r1=1;
        No
        Witnesses
        Positive: 0 Negative: 3
        Condition exists (0:r0=0 /\ 1:r1=0)
        Observation wake_up_q-wake_q_add Never 0 3
      
      Reported-by: default avatarYongji Xie <elohimes@gmail.com>
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Cc: Davidlohr Bueso <dave@stgolabs.net>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Waiman Long <longman@redhat.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
      4c4e3731
    • Peter Zijlstra's avatar
      sched/wake_q: Document wake_q_add() · e6018c0f
      Peter Zijlstra authored
      
      
      The only guarantee provided by wake_q_add() is that a wakeup will
      happen after it, it does _NOT_ guarantee the wakeup will be delayed
      until the matching wake_up_q().
      
      If wake_q_add() fails the cmpxchg() a concurrent wakeup is pending and
      that can happen at any time after the cmpxchg(). This means we should
      not rely on the wakeup happening at wake_q_up(), but should be ready
      for wake_q_add() to issue the wakeup.
      
      The delay; if provided (most likely); should only result in more efficient
      behaviour.
      
      Reported-by: default avatarYongji Xie <elohimes@gmail.com>
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Cc: Davidlohr Bueso <dave@stgolabs.net>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Waiman Long <longman@redhat.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
      e6018c0f
    • Prateek Sood's avatar
      sched/wait: Fix rcuwait_wake_up() ordering · 6dc080ee
      Prateek Sood authored
      
      
      For some peculiar reason rcuwait_wake_up() has the right barrier in
      the comment, but not in the code.
      
      This mistake has been observed to cause a deadlock in the following
      situation:
      
          P1					P2
      
          percpu_up_read()			percpu_down_write()
            rcu_sync_is_idle() // false
      					  rcu_sync_enter()
      					  ...
            __percpu_up_read()
      
      [S] ,-  __this_cpu_dec(*sem->read_count)
          |   smp_rmb();
      [L] |   task = rcu_dereference(w->task) // NULL
          |
          |				    [S]	    w->task = current
          |					    smp_mb();
          |				    [L]	    readers_active_check() // fail
          `-> <store happens here>
      
      Where the smp_rmb() (obviously) fails to constrain the store.
      
      [ peterz: Added changelog. ]
      
      Signed-off-by: default avatarPrateek Sood <prsood@codeaurora.org>
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Reviewed-by: default avatarAndrea Parri <andrea.parri@amarulasolutions.com>
      Acked-by: default avatarDavidlohr Bueso <dbueso@suse.de>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Fixes: 8f95c90c ("sched/wait, RCU: Introduce rcuwait machinery")
      Link: https://lkml.kernel.org/r/1543590656-7157-1-git-send-email-prsood@codeaurora.org
      
      
      Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
      6dc080ee
  2. Jan 18, 2019
  3. Jan 17, 2019
  4. Jan 16, 2019