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....@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 -- 2.32.0 (Apple Git-132)
0001-fs-fuse-make-size-of-qhash-and-limit-of-each-bucket-.patch
Description: 0001-fs-fuse-make-size-of-qhash-and-limit-of-each-bucket-.patch
_______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel