From 36b6b602c8783e4f5801b7df3c1c8f659371fed2 Mon Sep 17 00:00:00 2001 From: Alexander Zarochentsev Date: Thu, 20 Oct 2022 22:23:39 +0300 Subject: [PATCH] LU-16272 libcfs: cfs_hash_for_each_empty optimization Restarts from bucket 0 in cfs_hash_for_each_empty() cause excessive cpu consumption while checking first empty buckets. Lustre-change: https://review.whamcloud.com/48972 Lustre-commit: 306a9b666e5ea2882f704d93483355e7e147544f HPE-bug-id: LUS-11311 Signed-off-by: Alexander Zarochentsev Change-Id: Ic03875ea25101052468213043128912ac46daf32 Reviewed-by: Andrew Perepechko Reviewed-by: Alexander Boyko Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/53379 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- libcfs/libcfs/hash.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libcfs/libcfs/hash.c b/libcfs/libcfs/hash.c index 499d06d..5df1505 100644 --- a/libcfs/libcfs/hash.c +++ b/libcfs/libcfs/hash.c @@ -1598,7 +1598,7 @@ EXPORT_SYMBOL(cfs_hash_size_get); */ static int cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, - void *data, int start) + void *data, int *pstart) { struct hlist_node *hnode; struct hlist_node *next = NULL; @@ -1621,7 +1621,7 @@ again: cfs_hash_for_each_bucket(hs, &bd, i) { struct hlist_head *hhead; - if (i < start) + if (pstart && i < *pstart) continue; else if (end > 0 && i >= end) break; @@ -1680,13 +1680,15 @@ again: break; } - if (start > 0 && rc == 0) { - end = start; - start = 0; + if (pstart && *pstart > 0 && rc == 0) { + end = *pstart; + *pstart = 0; goto again; } cfs_hash_unlock(hs, 0); + if (pstart) + *pstart = i; return count; } @@ -1707,7 +1709,7 @@ cfs_hash_for_each_nolock(struct cfs_hash *hs, RETURN(-EOPNOTSUPP); cfs_hash_for_each_enter(hs); - cfs_hash_for_each_relax(hs, func, data, start); + cfs_hash_for_each_relax(hs, func, data, &start); cfs_hash_for_each_exit(hs); RETURN(0); @@ -1730,6 +1732,7 @@ cfs_hash_for_each_empty(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, void *data) { unsigned i = 0; + int start = 0; ENTRY; if (cfs_hash_with_no_lock(hs)) @@ -1741,11 +1744,12 @@ cfs_hash_for_each_empty(struct cfs_hash *hs, return -EOPNOTSUPP; cfs_hash_for_each_enter(hs); - while (cfs_hash_for_each_relax(hs, func, data, 0)) { + while (cfs_hash_for_each_relax(hs, func, data, &start)) { CDEBUG(D_INFO, "Try to empty hash: %s, loop: %u\n", hs->hs_name, i++); } cfs_hash_for_each_exit(hs); + LASSERT(atomic_read(&hs->hs_count) == 0); RETURN(0); } EXPORT_SYMBOL(cfs_hash_for_each_empty); -- 1.8.3.1