]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
bluestore, NVMeDevice: use task' own lock for (random) read 14094/head
authorZiye Yang <ziye.yang@intel.com>
Wed, 22 Mar 2017 03:41:00 +0000 (11:41 +0800)
committeroptimistyzy <optimistyzy@gmail.com>
Thu, 23 Mar 2017 02:31:23 +0000 (10:31 +0800)
The reason is that ioc may be reaped in _aio_thread function
with  the following statements:
for (auto &&it : registered_devices)
          it->reap_ioc();

So if we still use ioc's lock for (random) read, it will cause
core dump.

Signed-off-by: optimistyzy <optimistyzy@gmail.com>
src/os/bluestore/NVMEDevice.cc

index 72d9b2d636595fab650c1f969f1caa1bb75eae1a..beddc18f20d2d79a1d056081a17f82824f7eda45 100644 (file)
@@ -106,6 +106,8 @@ struct Task {
   int64_t return_code;
   ceph::coarse_real_clock::time_point start;
   IORequest io_request;
+  std::mutex lock;
+  std::condition_variable cond;
   Task(NVMEDevice *dev, IOCommand c, uint64_t off, uint64_t l, int64_t rc = 0)
     : device(dev), command(c), offset(off), len(l),
       return_code(rc),
@@ -139,6 +141,16 @@ struct Task {
       copied += need_copy;
     }
   }
+
+  void io_wait() {
+    std::unique_lock<std::mutex> l(lock);
+    cond.wait(l);
+  }
+
+  void io_wake() {
+    std::lock_guard<std::mutex> l(lock);
+    cond.notify_all();
+  }
 };
 
 class SharedDriverData {
@@ -782,7 +794,7 @@ void io_complete(void *t, const struct spdk_nvme_cpl *completion)
     } else {
       task->return_code = 0;
       if(!--ctx->num_reading) {
-        ctx->aio_wake();
+        task->io_wake();
       }
     }
   } else {
@@ -969,7 +981,7 @@ int NVMEDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
   driver->queue_task(t);
 
   while(t->return_code > 0) {
-    ioc->aio_wait();
+    t->io_wait();
   }
   pbl->push_back(std::move(p));
   r = t->return_code;
@@ -1035,7 +1047,7 @@ int NVMEDevice::read_random(uint64_t off, uint64_t len, char *buf, bool buffered
   driver->queue_task(t);
 
   while(t->return_code > 0) {
-    ioc.aio_wait();
+    t->io_wait();
   }
   r = t->return_code;
   delete t;