fuse: make the number of max background requests and congestion threshold tunable
Csaba Henk [Thu, 2 Jul 2009 00:28:41 +0000 (17:28 -0700)]
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: Csaba Henk <csaba@gluster.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>

fs/fuse/dev.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
include/linux/fuse.h

index f58ecbc..b152761 100644 (file)
@@ -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)
 {
-       while (fc->active_background < FUSE_MAX_BACKGROUND &&
+       while (fc->active_background < fc->max_background &&
               !list_empty(&fc->bg_queue)) {
                struct fuse_req *req;
 
@@ -280,11 +280,11 @@ __releases(&fc->lock)
        list_del(&req->intr_entry);
        req->state = FUSE_REQ_FINISHED;
        if (req->background) {
-               if (fc->num_background == FUSE_MAX_BACKGROUND) {
+               if (fc->num_background == fc->max_background) {
                        fc->blocked = 0;
                        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) {
                        clear_bdi_congested(&fc->bdi, READ);
                        clear_bdi_congested(&fc->bdi, WRITE);
@@ -410,9 +410,9 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
 {
        req->background = 1;
        fc->num_background++;
-       if (fc->num_background == FUSE_MAX_BACKGROUND)
+       if (fc->num_background == fc->max_background)
                fc->blocked = 1;
-       if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
+       if (fc->num_background == fc->congestion_threshold &&
            fc->bdi_initialized) {
                set_bdi_congested(&fc->bdi, READ);
                set_bdi_congested(&fc->bdi, WRITE);
index 52b641f..6bcfab0 100644 (file)
 /** Max number of pages that can be used in a single read request */
 #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 */
 #define FUSE_NOWRITE INT_MIN
 
@@ -349,6 +343,12 @@ struct fuse_conn {
        /** rbtree of fuse_files waiting for poll events indexed by ph */
        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 */
        unsigned num_background;
 
index f91ccc4..9aa6f46 100644 (file)
@@ -32,6 +32,12 @@ DEFINE_MUTEX(fuse_mutex);
 
 #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 {
        int fd;
        unsigned rootmode;
@@ -517,6 +523,8 @@ void fuse_conn_init(struct fuse_conn *fc)
        INIT_LIST_HEAD(&fc->bg_queue);
        INIT_LIST_HEAD(&fc->entry);
        atomic_set(&fc->num_waiting, 0);
+       fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
+       fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
        fc->khctr = 0;
        fc->polled_files = RB_ROOT;
        fc->reqctr = 0;
@@ -736,6 +744,12 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
        else {
                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) {
                        ra_pages = arg->max_readahead / PAGE_CACHE_SIZE;
                        if (arg->flags & FUSE_ASYNC_READ)
index cf593bf..b3700f0 100644 (file)
  *  - add umask flag to input argument of open, mknod and mkdir
  *  - add notification messages for invalidation of inodes and
  *    directory entries
+ *
+ * 7.13
+ *  - make max number of background requests and congestion threshold
+ *    tunables
  */
 
 #ifndef _LINUX_FUSE_H
@@ -41,7 +45,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** 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 */
 #define FUSE_ROOT_ID 1
@@ -427,7 +431,8 @@ struct fuse_init_out {
        __u32   minor;
        __u32   max_readahead;
        __u32   flags;
-       __u32   unused;
+       __u16   max_background;
+       __u16   congestion_threshold;
        __u32   max_write;
 };