[Devel] [PATCH RHEL9 COMMIT] fs/fuse: make size of qhash and limit of each bucket module parameters

Konstantin Khorenko khorenko at virtuozzo.com
Thu Nov 23 14:16:28 MSK 2023


The commit is pushed to "branch-rh9-5.14.0-284.25.1.vz9.30.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-284.25.1.vz9.30.11
------>
commit a910bb8a9c90b53748c6c0d2e2d844114d9ac86b
Author: Kui Liu <Kui.Liu at acronis.com>
Date:   Thu Nov 16 15:13:46 2023 +0000

    fs/fuse: make size of qhash and limit of each bucket module parameters
    
    Both size of qhash and limit of each bucket can affect performance of
    certain workload significantly. There is no single set of value that'd
    be the best for all workload, we may need to choose a value based on
    workload, so it'd be better make them configurable.
    
    Here we choose the default value to be 16 (qhash size) x 256 (bucket
    limit).
    
    Signed-off-by: Liu Kui <Kui.Liu at acronis.com>
    Acked-by: Alexey Kuznetsov <kuznet at acronis.com>
---
 fs/fuse/dev.c    | 5 ++---
 fs/fuse/fuse_i.h | 6 ++++--
 fs/fuse/inode.c  | 8 ++++++++
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 0023acc35204..8d15f76e0aea 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -367,7 +367,7 @@ void __fuse_request_end( struct fuse_req *req, bool flush_bg)
 
 		bg = true;
 
-		if (atomic_dec_return(&fc->qhash[bkt].num_reqs) < ((2*fc->max_background) / FUSE_QHASH_SIZE)) {
+		if (atomic_dec_return(&fc->qhash[bkt].num_reqs) < fuse_qhash_bucket_len) {
 			if (waitqueue_active(&fc->qhash[bkt].waitq))
 				wake_up(&fc->qhash[bkt].waitq);
 		}
@@ -629,8 +629,7 @@ static int fuse_request_queue_background(struct fuse_req *req)
 			__clear_bit(FR_BACKGROUND, &req->flags);
 			__set_bit(FR_NO_ACCT, &req->flags);
 			if (wait_event_killable_exclusive(fc->qhash[bkt].waitq,
-							  (atomic_read(&fc->qhash[bkt].num_reqs) <
-							   ((2 * fc->max_background) / FUSE_QHASH_SIZE) ||
+							  (atomic_read(&fc->qhash[bkt].num_reqs) < fuse_qhash_bucket_len ||
 							   !READ_ONCE(fc->connected) ||
 							   (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, &ff->ff_state)))))
 				return -EIO;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 487e1125f7e7..1633db46c6ef 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -642,7 +642,7 @@ struct fuse_kio_ops {
 int fuse_register_kio(struct fuse_kio_ops *ops);
 void fuse_unregister_kio(struct fuse_kio_ops *ops);
 
-#define FUSE_QHASH_SIZE 64
+#define FUSE_QHASH_SIZE 128
 
 #include <linux/jhash.h>
 
@@ -659,9 +659,11 @@ static inline unsigned int fuse_qhash_bucket(struct fuse_args * args)
 	return jhash_2words(val & 0xFFFFFFFFU, val >> 32, 0) & (FUSE_QHASH_SIZE - 1);
 }
 #else
+extern unsigned int fuse_qhash_size;
+extern unsigned int fuse_qhash_bucket_len;
 static inline unsigned int fuse_qhash_bucket(void)
 {
-	return jhash_1word(current->pid, 0) & (FUSE_QHASH_SIZE - 1);
+	return jhash_1word(current->pid, 0) & (FUSE_QHASH_SIZE - 1) & (fuse_qhash_size - 1);
 }
 #endif
 
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 33cd8f9944ca..49993e1d20a5 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -54,6 +54,14 @@ MODULE_PARM_DESC(max_user_congthresh,
  "Global limit for the maximum congestion threshold an "
  "unprivileged user can set");
 
+unsigned int fuse_qhash_size = 16;
+module_param(fuse_qhash_size, uint, 0600);
+MODULE_PARM_DESC(fuse_qhash_size, "Number of qhash buckets, must be power of 2");
+
+unsigned int fuse_qhash_bucket_len = 256;
+module_param(fuse_qhash_bucket_len, uint, 0600);
+MODULE_PARM_DESC(fuse_qhash_bucket_len, "Limit of a qhash bucket");
+
 #define FUSE_SUPER_MAGIC 0x65735546
 
 #define FUSE_DEFAULT_BLKSIZE 512


More information about the Devel mailing list