]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/cache/pwl: fix assert in _aio_stop() during shutdown 42950/head
authorYin Congmin <congmin.yin@intel.com>
Wed, 15 Sep 2021 11:23:43 +0000 (11:23 +0000)
committerYin Congmin <congmin.yin@intel.com>
Tue, 2 Nov 2021 01:36:56 +0000 (09:36 +0800)
For wait_for_ops(next_ctx). this next_ctx may run in aio_thread.
Then the next program runs on the aio thread. remove_pool_file()
calls bdev->close(), then calles _aio_stop(), exec aio_thread.join(),
cause assert. Thread can't join itself. Fix it by adding close ctx
to m_work_queue, so close() can run in work queue thread.

At the same time, correct the order of wait_for_ops().
flush_dirty_entries(next_ctx) may call wake_up() and start_op().
so moving wait_for_ops() behind flush_dirty_entries(next_ctx) is more
appropriate.

Fixes: https://tracker.ceph.com/issues/52566
Signed-off-by: Yin Congmin <congmin.yin@intel.com>
src/librbd/cache/pwl/AbstractWriteLog.cc

index 5b7799e664b599ab5cbaae21b600d14a2430bcb9..9f4e567bb138293099996f71c8e9794c0a205e44 100644 (file)
@@ -637,6 +637,14 @@ void AbstractWriteLog<I>::shut_down(Context *on_finish) {
       }
       update_image_cache_state(next_ctx);
     });
+  ctx = new LambdaContext(
+    [this, ctx](int r) {
+      Context *next_ctx = override_ctx(r, ctx);
+      ldout(m_image_ctx.cct, 6) << "waiting for in flight operations" << dendl;
+      // Wait for in progress IOs to complete
+      next_ctx = util::create_async_context_callback(&m_work_queue, next_ctx);
+      m_async_op_tracker.wait_for_ops(next_ctx);
+    });
   ctx = new LambdaContext(
     [this, ctx](int r) {
       Context *next_ctx = override_ctx(r, ctx);
@@ -653,14 +661,6 @@ void AbstractWriteLog<I>::shut_down(Context *on_finish) {
       }
       flush_dirty_entries(next_ctx);
     });
-  ctx = new LambdaContext(
-    [this, ctx](int r) {
-      Context *next_ctx = override_ctx(r, ctx);
-      ldout(m_image_ctx.cct, 6) << "waiting for in flight operations" << dendl;
-      // Wait for in progress IOs to complete
-      next_ctx = util::create_async_context_callback(m_image_ctx, next_ctx);
-      m_async_op_tracker.wait_for_ops(next_ctx);
-    });
   ctx = new LambdaContext(
     [this, ctx](int r) {
       ldout(m_image_ctx.cct, 6) << "Done internal_flush in shutdown" << dendl;