]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/cache/pwl: fix bug of flush request blocked by deferd IO 40339/head
authorYin Congmin <congmin.yin@intel.com>
Thu, 18 Mar 2021 13:33:07 +0000 (21:33 +0800)
committerJason Dillaman <dillaman@redhat.com>
Tue, 23 Mar 2021 13:54:47 +0000 (09:54 -0400)
Flush requests do not need to be queued behind the defer_io queue,
should be issued immediately. Otherwise, there will be a deadlock
scenario in which dirty data is waiting for flush req, flush req is
waiting for defer_io empty, and defer_io is waiting for dirty data
persistence to release space. So this sometimes occur when the cache
is small but the IO is large or the queue depth is large.

Signed-off-by: Yin Congmin <congmin.yin@intel.com>
(cherry picked from commit 6583182f624386bfbb7375fb227dfb77b0a3209d)

src/librbd/cache/pwl/AbstractWriteLog.cc

index a658b60b2fe4766a92d1b4deeb7d3e00561ed188..76e8e478e2bf7487907ba7e680b871133a1f9f2a 100644 (file)
@@ -818,9 +818,11 @@ void AbstractWriteLog<I>::write(Extents &&image_extents,
 
   ceph_assert(m_initialized);
 
-  /* Split images because PMDK doesn't support allocating too big extent
-   * TODO: If the bluestore allocator is implemented as a library,
-   * the split operation is not necessary
+  /* Split images because PMDK's space management is not perfect, there are
+   * fragment problems. The larger the block size difference of the block,
+   * the easier the fragmentation problem will occur, resulting in the
+   * remaining space can not be allocated in large size. We plan to manage
+   * pmem space and allocation by ourselves in the future.
    */
   Extents split_image_extents;
   uint64_t max_extent_size = get_max_extent();
@@ -1430,6 +1432,11 @@ void AbstractWriteLog<I>::alloc_and_dispatch_io_req(C_BlockIORequestT *req)
     {
       std::lock_guard locker(m_lock);
       dispatch_here = m_deferred_ios.empty();
+      // Only flush req's total_bytes is the max uint64
+      if ((req->image_extents_summary.total_bytes ==
+          std::numeric_limits<uint64_t>::max())) {
+        dispatch_here = true;
+      }
     }
     if (dispatch_here) {
       dispatch_here = req->alloc_resources();