Commit 7a6d3c8b authored by Csaba Henk's avatar Csaba Henk Committed by Miklos Szeredi

fuse: make the number of max background requests and congestion threshold tunable

The practical values for these limits depend on the design of the
filesystem server so let userspace set them at initialization time.
Signed-off-by: default avatarCsaba Henk <csaba@gluster.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent 8e4a718f
...@@ -250,7 +250,7 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req) ...@@ -250,7 +250,7 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
static void flush_bg_queue(struct fuse_conn *fc) static void flush_bg_queue(struct fuse_conn *fc)
{ {
while (fc->active_background < FUSE_MAX_BACKGROUND && while (fc->active_background < fc->max_background &&
!list_empty(&fc->bg_queue)) { !list_empty(&fc->bg_queue)) {
struct fuse_req *req; struct fuse_req *req;
...@@ -280,11 +280,11 @@ __releases(&fc->lock) ...@@ -280,11 +280,11 @@ __releases(&fc->lock)
list_del(&req->intr_entry); list_del(&req->intr_entry);
req->state = FUSE_REQ_FINISHED; req->state = FUSE_REQ_FINISHED;
if (req->background) { if (req->background) {
if (fc->num_background == FUSE_MAX_BACKGROUND) { if (fc->num_background == fc->max_background) {
fc->blocked = 0; fc->blocked = 0;
wake_up_all(&fc->blocked_waitq); wake_up_all(&fc->blocked_waitq);
} }
if (fc->num_background == FUSE_CONGESTION_THRESHOLD && if (fc->num_background == fc->congestion_threshold &&
fc->connected && fc->bdi_initialized) { fc->connected && fc->bdi_initialized) {
clear_bdi_congested(&fc->bdi, READ); clear_bdi_congested(&fc->bdi, READ);
clear_bdi_congested(&fc->bdi, WRITE); clear_bdi_congested(&fc->bdi, WRITE);
...@@ -410,9 +410,9 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc, ...@@ -410,9 +410,9 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
{ {
req->background = 1; req->background = 1;
fc->num_background++; fc->num_background++;
if (fc->num_background == FUSE_MAX_BACKGROUND) if (fc->num_background == fc->max_background)
fc->blocked = 1; fc->blocked = 1;
if (fc->num_background == FUSE_CONGESTION_THRESHOLD && if (fc->num_background == fc->congestion_threshold &&
fc->bdi_initialized) { fc->bdi_initialized) {
set_bdi_congested(&fc->bdi, READ); set_bdi_congested(&fc->bdi, READ);
set_bdi_congested(&fc->bdi, WRITE); set_bdi_congested(&fc->bdi, WRITE);
......
...@@ -25,12 +25,6 @@ ...@@ -25,12 +25,6 @@
/** Max number of pages that can be used in a single read request */ /** Max number of pages that can be used in a single read request */
#define FUSE_MAX_PAGES_PER_REQ 32 #define FUSE_MAX_PAGES_PER_REQ 32
/** Maximum number of outstanding background requests */
#define FUSE_MAX_BACKGROUND 12
/** Congestion starts at 75% of maximum */
#define FUSE_CONGESTION_THRESHOLD (FUSE_MAX_BACKGROUND * 75 / 100)
/** Bias for fi->writectr, meaning new writepages must not be sent */ /** Bias for fi->writectr, meaning new writepages must not be sent */
#define FUSE_NOWRITE INT_MIN #define FUSE_NOWRITE INT_MIN
...@@ -349,6 +343,12 @@ struct fuse_conn { ...@@ -349,6 +343,12 @@ struct fuse_conn {
/** rbtree of fuse_files waiting for poll events indexed by ph */ /** rbtree of fuse_files waiting for poll events indexed by ph */
struct rb_root polled_files; struct rb_root polled_files;
/** Maximum number of outstanding background requests */
unsigned max_background;
/** Number of background requests at which congestion starts */
unsigned congestion_threshold;
/** Number of requests currently in the background */ /** Number of requests currently in the background */
unsigned num_background; unsigned num_background;
......
...@@ -32,6 +32,12 @@ DEFINE_MUTEX(fuse_mutex); ...@@ -32,6 +32,12 @@ DEFINE_MUTEX(fuse_mutex);
#define FUSE_DEFAULT_BLKSIZE 512 #define FUSE_DEFAULT_BLKSIZE 512
/** Maximum number of outstanding background requests */
#define FUSE_DEFAULT_MAX_BACKGROUND 12
/** Congestion starts at 75% of maximum */
#define FUSE_DEFAULT_CONGESTION_THRESHOLD (FUSE_DEFAULT_MAX_BACKGROUND * 3 / 4)
struct fuse_mount_data { struct fuse_mount_data {
int fd; int fd;
unsigned rootmode; unsigned rootmode;
...@@ -517,6 +523,8 @@ void fuse_conn_init(struct fuse_conn *fc) ...@@ -517,6 +523,8 @@ void fuse_conn_init(struct fuse_conn *fc)
INIT_LIST_HEAD(&fc->bg_queue); INIT_LIST_HEAD(&fc->bg_queue);
INIT_LIST_HEAD(&fc->entry); INIT_LIST_HEAD(&fc->entry);
atomic_set(&fc->num_waiting, 0); atomic_set(&fc->num_waiting, 0);
fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
fc->khctr = 0; fc->khctr = 0;
fc->polled_files = RB_ROOT; fc->polled_files = RB_ROOT;
fc->reqctr = 0; fc->reqctr = 0;
...@@ -736,6 +744,12 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) ...@@ -736,6 +744,12 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
else { else {
unsigned long ra_pages; unsigned long ra_pages;
if (arg->minor >= 13) {
if (arg->max_background)
fc->max_background = arg->max_background;
if (arg->congestion_threshold)
fc->congestion_threshold = arg->congestion_threshold;
}
if (arg->minor >= 6) { if (arg->minor >= 6) {
ra_pages = arg->max_readahead / PAGE_CACHE_SIZE; ra_pages = arg->max_readahead / PAGE_CACHE_SIZE;
if (arg->flags & FUSE_ASYNC_READ) if (arg->flags & FUSE_ASYNC_READ)
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
* - add umask flag to input argument of open, mknod and mkdir * - add umask flag to input argument of open, mknod and mkdir
* - add notification messages for invalidation of inodes and * - add notification messages for invalidation of inodes and
* directory entries * directory entries
*
* 7.13
* - make max number of background requests and congestion threshold
* tunables
*/ */
#ifndef _LINUX_FUSE_H #ifndef _LINUX_FUSE_H
...@@ -41,7 +45,7 @@ ...@@ -41,7 +45,7 @@
#define FUSE_KERNEL_VERSION 7 #define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */ /** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 12 #define FUSE_KERNEL_MINOR_VERSION 13
/** The node ID of the root inode */ /** The node ID of the root inode */
#define FUSE_ROOT_ID 1 #define FUSE_ROOT_ID 1
...@@ -427,7 +431,8 @@ struct fuse_init_out { ...@@ -427,7 +431,8 @@ struct fuse_init_out {
__u32 minor; __u32 minor;
__u32 max_readahead; __u32 max_readahead;
__u32 flags; __u32 flags;
__u32 unused; __u16 max_background;
__u16 congestion_threshold;
__u32 max_write; __u32 max_write;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment