[RHEL7,COMMIT] fs/fuse kio_pcs: throttle async KIO requests

Submitted by Konstantin Khorenko on July 25, 2018, 3:05 p.m.

Details

Message ID 201807251505.w6PF5FF4018609@finist_ce7.work
State New
Series "fs/fuse kio_pcs: throttle async KIO requests"
Headers show

Commit Message

Konstantin Khorenko July 25, 2018, 3:05 p.m.
The commit is pushed to "branch-rh7-3.10.0-862.9.1.vz7.63.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.9.1.vz7.63.2
------>
commit 8c16669653c46432d4a5705697c11a79943418ad
Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
Date:   Wed Jul 25 18:05:15 2018 +0300

    fs/fuse kio_pcs: throttle async KIO requests
    
    Fuse has a mechanism to limit the number of async requests, it's necessary to
    limit resource consumption in the kernel, also it allows us to absorb high I/O
    load. But kio requests ignore this limitation. This patch makes it possible to
    use the common Fuse throttling for the kio.
    
    https://pmc.acronis.com/browse/VSTOR-12335
    
    Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
---
 fs/fuse/dev.c                      |  9 +++++----
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 21 +++++++++++++++++++--
 2 files changed, 24 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index f7aca3094a83..0071a6a9ff11 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -384,8 +384,12 @@  static void flush_bg_queue(struct fuse_conn *fc, struct fuse_iqueue *fiq)
 		struct fuse_req *req;
 
 		req = list_entry(fc->bg_queue.next, struct fuse_req, list);
-		list_del(&req->list);
+		list_del_init(&req->list);
 		fc->active_background++;
+
+		if (fc->kio.op && !fc->kio.op->req_send(fc, req, true, true))
+			continue;
+
 		spin_lock(&fiq->waitq.lock);
 		req->in.h.unique = fuse_get_unique(fiq);
 		queue_request(fiq, req);
@@ -561,9 +565,6 @@  void fuse_request_send_background_locked(struct fuse_conn *fc,
 
 	BUG_ON(!test_bit(FR_BACKGROUND, &req->flags));
 
-	if (fc->kio.op && !fc->kio.op->req_send(fc, req, true, true))
-		return;
-
 	if (!test_bit(FR_WAITING, &req->flags)) {
 		__set_bit(FR_WAITING, &req->flags);
 		atomic_inc(&fc->num_waiting);
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 105869d6f81f..3ff07397820e 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -1068,11 +1068,28 @@  static int kpcs_req_send(struct fuse_conn* fc, struct fuse_req *req, bool bg, bo
 		return 1;
 	}
 
-	__clear_bit(FR_BACKGROUND, &req->flags);
-	__clear_bit(FR_PENDING, &req->flags);
 	/* request_end below will do fuse_put_request() */
 	if (!bg)
 		atomic_inc(&req->count);
+	else if (!lk) {
+		spin_lock(&fc->lock);
+		if (fc->num_background + 1 >= fc->max_background ||
+		    !fc->connected) {
+			spin_unlock(&fc->lock);
+			return 1;
+		}
+		fc->num_background++;
+		fc->active_background++;
+
+		if (fc->num_background == fc->congestion_threshold &&
+		    fc->bdi_initialized) {
+			set_bdi_congested(&fc->bdi, BLK_RW_SYNC);
+			set_bdi_congested(&fc->bdi, BLK_RW_ASYNC);
+		}
+		spin_unlock(&fc->lock);
+	}
+	__clear_bit(FR_PENDING, &req->flags);
+
 	pcs_fuse_submit(pfc, req, lk);
 	if (!bg)
 		wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));