From 7782740c10c8ee7ba418432e37edbe1106562859 Mon Sep 17 00:00:00 2001 From: Liu Kui Date: Wed, 8 Nov 2023 16:27:18 +0800 Subject: [PATCH] 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 --- 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 @@ -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 -- 2.32.0 (Apple Git-132)