Whamcloud - gitweb
LU-16272 libcfs: cfs_hash_for_each_empty optimization 72/48972/4
authorAlexander Zarochentsev <alexander.zarochentsev@hpe.com>
Thu, 20 Oct 2022 19:23:39 +0000 (22:23 +0300)
committerOleg Drokin <green@whamcloud.com>
Fri, 13 Jan 2023 07:24:59 +0000 (07:24 +0000)
Restarts from bucket 0 in cfs_hash_for_each_empty()
cause excessive cpu consumption while checking first empty
buckets.

HPE-bug-id: LUS-11311
Signed-off-by: Alexander Zarochentsev <alexander.zarochentsev@hpe.com>
Change-Id: Ic03875ea25101052468213043128912ac46daf32
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/48972
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andrew Perepechko <andrew.perepechko@hpe.com>
Reviewed-by: Alexander Boyko <alexander.boyko@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
libcfs/libcfs/hash.c

index 6fb32ad..e4e061b 100644 (file)
@@ -1597,7 +1597,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;
@@ -1620,7 +1620,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;
@@ -1679,13 +1679,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;
 }
 
@@ -1706,7 +1708,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);
@@ -1729,6 +1731,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))
@@ -1740,11 +1743,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);