]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: empty IO requests should complete in new context
authorJason Dillaman <dillaman@redhat.com>
Tue, 2 Apr 2019 19:33:00 +0000 (15:33 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 8 Apr 2019 17:20:07 +0000 (13:20 -0400)
This will avoid the possibility of a lock being held by the caller
and having the IO immediately complete back to the calling state
machine.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/io/AioCompletion.cc
src/librbd/io/AioCompletion.h
src/librbd/io/ImageRequest.cc
src/librbd/journal/Replay.cc

index 661cd57255b3d9486f4fcb07c70168e9cd49408c..c106ee11a78a8e2380bdcc637e4b3c37ecbb7796 100644 (file)
@@ -145,11 +145,17 @@ void AioCompletion::set_request_count(uint32_t count) {
 
   ldout(cct, 20) << "pending=" << count << dendl;
   ceph_assert(pending_count == 0);
-  pending_count = count;
-  lock.Unlock();
 
-  // if no pending requests, completion will fire now
-  unblock();
+  if (count > 0) {
+    pending_count = count;
+    lock.Unlock();
+  } else {
+    pending_count = 1;
+    lock.Unlock();
+
+    // ensure completion fires in clean lock context
+    ictx->op_work_queue->queue(new C_AioRequest(this), 0);
+  }
 }
 
 void AioCompletion::complete_request(ssize_t r)
@@ -169,7 +175,7 @@ void AioCompletion::complete_request(ssize_t r)
 
   ldout(cct, 20) << "cb=" << complete_cb << ", "
                  << "pending=" << pending_count << dendl;
-  if (!count && blockers == 0) {
+  if (!count) {
     finalize(rval);
     complete();
   }
index ef0a3c8999bc870012f2f5393d7303211e66e91e..ffc8129c7e6a0187fb2dd1cbffa50e4bfade048c 100644 (file)
@@ -50,7 +50,6 @@ struct AioCompletion {
   void *complete_arg;
   rbd_completion_t rbd_comp;
   uint32_t pending_count;   ///< number of requests
-  uint32_t blockers;
   int ref;
   bool released;
   ImageCtx *ictx;
@@ -106,8 +105,7 @@ struct AioCompletion {
   AioCompletion() : lock("AioCompletion::lock", true, false),
                     state(AIO_STATE_PENDING), rval(0), complete_cb(NULL),
                     complete_arg(NULL), rbd_comp(NULL),
-                    pending_count(0), blockers(1),
-                    ref(1), released(false), ictx(NULL),
+                    pending_count(0), ref(1), released(false), ictx(NULL),
                     aio_type(AIO_TYPE_NONE), m_xlist_item(this),
                     event_notify(false) {
   }
@@ -188,20 +186,6 @@ struct AioCompletion {
     }
   }
 
-  void block() {
-    Mutex::Locker l(lock);
-    ++blockers;
-  }
-  void unblock() {
-    Mutex::Locker l(lock);
-    ceph_assert(blockers > 0);
-    --blockers;
-    if (pending_count == 0 && blockers == 0) {
-      finalize(rval);
-      complete();
-    }
-  }
-
   void set_event_notify(bool s) {
     Mutex::Locker l(lock);
     event_notify = s;
index a86720621c6b1eb7789f1aa8bd46cf7f2240b208..5a74fabf0e96c7d96fb3f53daead53b006db74b6 100644 (file)
@@ -395,7 +395,7 @@ void AbstractImageWriteRequest<I>::send_request() {
     send_object_requests(object_extents, snapc, journal_tid);
   } else {
     // no IO to perform -- fire completion
-    aio_comp->unblock();
+    aio_comp->set_request_count(0);
   }
 
   update_stats(clip_len);
index 25dd61203f7bc26d81aaaa8e16c31ddababd4034..f96153e7edb82344500c3ad3f7e8f206ea6333fc 100644 (file)
@@ -1176,7 +1176,7 @@ bool Replay<I>::clipped_io(uint64_t image_offset, io::AioCompletion *aio_comp) {
     // it wouldn't have been recorded in the journal
     ldout(cct, 5) << ": no-op IO event beyond image size" << dendl;
     aio_comp->get();
-    aio_comp->unblock();
+    aio_comp->set_request_count(0);
     aio_comp->put();
     return true;
   }