From d76f222462f01f03c337d0e2d174d10edb5db004 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Sat, 25 Feb 2017 13:29:54 +0100 Subject: [PATCH] bluestore: the exhausted check in BitMapZone can be lock-less. Before the patch BitMapZone::is_exhausted() required from its callers to acquire appropriate lock. However, fulfilling this condition is not really necessary to use the method correctly while it can significantly hurt performance. The change allows BitMapAreaLeaf::child_check_n_lock() to not acquire the lock while examining zones for being exhausted. Signed-off-by: Radoslaw Zarzynski --- src/os/bluestore/BitAllocator.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/os/bluestore/BitAllocator.cc b/src/os/bluestore/BitAllocator.cc index 9e754bc0ef8..3600295dacb 100644 --- a/src/os/bluestore/BitAllocator.cc +++ b/src/os/bluestore/BitAllocator.cc @@ -421,7 +421,7 @@ BitMapZone::~BitMapZone() */ bool BitMapZone::is_exhausted() { - alloc_assert(check_locked()); + /* BitMapZone::get_used_blocks operates atomically. No need for lock. */ return get_used_blocks() == size(); } @@ -1098,14 +1098,16 @@ BitMapAreaLeaf::~BitMapAreaLeaf() bool BitMapAreaLeaf::child_check_n_lock(BitMapArea *child, int64_t required, bool lock) { - if (lock) { - child->lock_excl(); - } else if (!child->lock_excl_try()) { + /* The exhausted check can be performed without acquiring the lock. This + * is because 1) BitMapZone::is_exhausted() actually operates atomically + * and 2) it's followed by the exclusive, required-aware re-verification. */ + if (child->is_exhausted()) { return false; } - if (child->is_exhausted()) { - child->unlock(); + if (lock) { + child->lock_excl(); + } else if (!child->lock_excl_try()) { return false; } -- 2.47.3