Skip to content

Commit 25ced46

Browse files
committed
lookup without holding the lock during registration
global_lock is a source of contention when multiple threads/cores are adding stats concurrently, e.g. when a volume is being created so every core has to create a set of volume stats. This contention is mostly redundant as every directory in the root and the entire sub-tree under it is only modified by the core that owns it. While a better solution would be to have a separate lock for each of these sub-trees, we can reduce the contention by holding the lock for a shorter period of time. One of the suspected long locked periods is lookup for duplicate entry done in register_item(): this walks the list, which is O(N) and can be expensive for the "namespaces" directory with 10K entries. Based on the above, we lookup for duplicates without holding a lock, unless looking up in the root directory. List modification as well as item initialization is still done under lock to make sure the fuse interface always finds the directory and the item in a consistent state. Issue: LBM1-19873 Signed-off-by: Anton Eidelman <anton@lightbitslabs.com>
1 parent 2723db2 commit 25ced46

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

src/procstat.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -779,17 +779,32 @@ static int register_item(struct procstat_context *context,
779779
struct procstat_item *item,
780780
struct procstat_directory *parent)
781781
{
782-
pthread_mutex_lock(&context->global_lock);
783-
if (parent) {
782+
if (likely(parent)) {
784783
struct procstat_item *duplicate;
784+
bool locked = false;
785+
786+
if (unlikely(root_directory(context, parent))) {
787+
/* Only root directory can be modified concurrently by different threads */
788+
pthread_mutex_lock(&context->global_lock);
789+
locked = true;
790+
}
785791

786792
duplicate = lookup_item_locked(parent, procstat_item_name(item), item->name_hash);
787-
if (duplicate) {
788-
pthread_mutex_unlock(&context->global_lock);
793+
if (unlikely(duplicate)) {
794+
if (locked)
795+
pthread_mutex_unlock(&context->global_lock);
789796
return EEXIST;
790797
}
798+
799+
if (likely(!locked))
800+
pthread_mutex_lock(&context->global_lock);
801+
791802
list_add_tail(&item->entry, &parent->children);
803+
} else {
804+
pthread_mutex_lock(&context->global_lock);
792805
}
806+
807+
793808
item->flags |= STATS_ENTRY_FLAG_REGISTERED;
794809
item->refcnt = 1;
795810
item->parent = parent;

0 commit comments

Comments
 (0)