Skip to content
  1. Apr 17, 2021
    • Ali Saidi's avatar
      locking/qrwlock: Fix ordering in queued_write_lock_slowpath() · 84a24bf8
      Ali Saidi authored
      
      
      While this code is executed with the wait_lock held, a reader can
      acquire the lock without holding wait_lock.  The writer side loops
      checking the value with the atomic_cond_read_acquire(), but only truly
      acquires the lock when the compare-and-exchange is completed
      successfully which isn’t ordered. This exposes the window between the
      acquire and the cmpxchg to an A-B-A problem which allows reads
      following the lock acquisition to observe values speculatively before
      the write lock is truly acquired.
      
      We've seen a problem in epoll where the reader does a xchg while
      holding the read lock, but the writer can see a value change out from
      under it.
      
        Writer                                | Reader
        --------------------------------------------------------------------------------
        ep_scan_ready_list()                  |
        |- write_lock_irq()                   |
            |- queued_write_lock_slowpath()   |
      	|- atomic_cond_read_acquire()   |
      				        | read_lock_irqsave(&ep->lock, flags);
           --> (observes value before unlock) |  chain_epi_lockless()
           |                                  |    epi->next = xchg(&ep->ovflist, epi);
           |                                  | read_unlock_irqrestore(&ep->lock, flags);
           |                                  |
           |     atomic_cmpxchg_relaxed()     |
           |-- READ_ONCE(ep->ovflist);        |
      
      A core can order the read of the ovflist ahead of the
      atomic_cmpxchg_relaxed(). Switching the cmpxchg to use acquire
      semantics addresses this issue at which point the atomic_cond_read can
      be switched to use relaxed semantics.
      
      Fixes: b519b56e ("locking/qrwlock: Use atomic_cond_read_acquire() when spinning in qrwlock")
      Signed-off-by: default avatarAli Saidi <alisaidi@amazon.com>
      [peterz: use try_cmpxchg()]
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Reviewed-by: default avatarSteve Capper <steve.capper@arm.com>
      Acked-by: default avatarWill Deacon <will@kernel.org>
      Acked-by: default avatarWaiman Long <longman@redhat.com>
      Tested-by: default avatarSteve Capper <steve.capper@arm.com>
      84a24bf8
  2. Apr 12, 2021
  3. Apr 11, 2021
  4. Apr 10, 2021