]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commit
os/bluestore/BlockDevice: fix racy aio_{wake,wait}() on IOContext
authorSage Weil <sage@redhat.com>
Fri, 5 May 2017 18:11:31 +0000 (14:11 -0400)
committerSage Weil <sage@redhat.com>
Fri, 5 May 2017 18:39:30 +0000 (14:39 -0400)
commit1026593173fd783edb92c2e17fa8ceebd049cca4
treefade6f3a841333b883f7a0769556ff72a158a42e
parent5457991143a1606a6eb5b0d7e0bd939f5f88f528
os/bluestore/BlockDevice: fix racy aio_{wake,wait}() on IOContext

Thread 1 (_do_read)                 Thread 2 (_aio_thread)
queues aio
ioc->aio_wait()
  locks ioc->lock
  num_waiting++
                                    finishes aios
                                    ioc->aio_wake
                                      if (num_waiting)
                                        lock ioc->lock (blocks)
  num_running == 0, continue
  ioc->unlock
                                        ioc->lock taken
do_read destroys ioc
                                        use after free, may block forever

The last bit of the race may vary; the key thing is that thread 2 is
taking a lock that thread 1 can destroy; thread 2 doesn't have it pinned
in memory.

Fix this by simplifying the aio_wake, aio_wait.  Since it is mutually
exclusive with a callback completion, we can avoid calling it at all when
a callback in present, and focus on keeping it simple.

Avoid use-after-free by making sure the last decrement happens under
the lock in the aio_wake/wait case.

Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlockDevice.cc
src/os/bluestore/BlockDevice.h
src/os/bluestore/KernelDevice.cc
src/os/bluestore/NVMEDevice.cc