]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/Finisher: call logger without holding the lock
authorMax Kellermann <max.kellermann@ionos.com>
Mon, 7 Oct 2024 19:11:55 +0000 (21:11 +0200)
committerMax Kellermann <max.kellermann@ionos.com>
Thu, 10 Oct 2024 05:31:52 +0000 (07:31 +0200)
The `PerfCounters::inc()` method acquires another lock which can block
the calling thread while holding the `finisher_lock` which can cause a
lot of lock contention.  This can be avoided easily by moving the
`PerfCounters::inc()` call out of the protected code block.

Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
src/common/Finisher.h

index 46a4599b8d000113f696a2bb33a5f630303f5631..81211c822694accd47767dca7311875531fc53dd 100644 (file)
@@ -65,12 +65,15 @@ class Finisher {
  public:
   /// Add a context to complete, optionally specifying a parameter for the complete function.
   void queue(Context *c, int r = 0) {
-    const std::lock_guard l{finisher_lock};
-    bool was_empty = finisher_queue.empty();
-    finisher_queue.push_back(std::make_pair(c, r));
-    if (was_empty) {
-      finisher_cond.notify_one();
+    {
+      const std::lock_guard l{finisher_lock};
+      const bool was_empty = finisher_queue.empty();
+      finisher_queue.push_back(std::make_pair(c, r));
+      if (was_empty) {
+       finisher_cond.notify_one();
+      }
     }
+
     if (logger)
       logger->inc(l_finisher_queue_len);
   }
@@ -86,9 +89,9 @@ class Finisher {
       for (Context *i : ls) {
        finisher_queue.push_back(std::make_pair(i, 0));
       }
-      if (logger)
-       logger->inc(l_finisher_queue_len, ls.size());
     }
+    if (logger)
+      logger->inc(l_finisher_queue_len, ls.size());
     ls.clear();
   }