[RHEL7,COMMIT] fuse kio: infinite loop in processing congestion queue

Submitted by Konstantin Khorenko on June 8, 2018, 4:30 p.m.

Details

Message ID 201806081630.w58GUV5P020547@finist_ce7.work
State New
Series "fuse kio: infinite loop in processing congestion queue"
Headers show

Commit Message

Konstantin Khorenko June 8, 2018, 4:30 p.m.
The commit is pushed to "branch-rh7-3.10.0-693.21.1.vz7.50.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.21.1.vz7.50.7
------>
commit cc79c46896440e10e2871dcd48bcb79213c0ae3f
Author: Alexey Kuznetsov <kuznet@virtuozzo.com>
Date:   Fri Jun 8 19:30:31 2018 +0300

    fuse kio: infinite loop in processing congestion queue
    
    Affects: #VSTOR-10928
    
    Signed-off-by: Alexey Kuznetsov <kuznet@virtuozzo.com>
    Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 fs/fuse/kio/pcs/pcs_map.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c
index b8bcda778959..9a05e247fe47 100644
--- a/fs/fuse/kio/pcs/pcs_map.c
+++ b/fs/fuse/kio/pcs/pcs_map.c
@@ -1577,16 +1577,25 @@  void pcs_deaccount_ireq(struct pcs_int_request *ireq, pcs_error_t * err)
 			pcs_cs_deaccount(ireq, csl->cs[i].cslink.cs, 0);
 		}
 
-		do {
+		for (;;) {
 			for (i = csl->nsrv - 1; i >= 0; i--)
 				pcs_cs_wakeup(csl->cs[i].cslink.cs);
 
 			requeue = 0;
 			for (i = csl->nsrv - 1; i >= 0; i--)
 				requeue |= pcs_cs_still_congested(csl->cs[i].cslink.cs);
-		} while (requeue);
+
+			if (!requeue)
+				break;
+
+			for (i = csl->nsrv - 1; i >= 0; i--) {
+				struct pcs_cs * cs = csl->cs[i].cslink.cs;
+				spin_lock(&cs->lock);
+				pcs_cs_activate_cong_queue(cs);
+				spin_unlock(&cs->lock);
+			}
+		};
 	} else {
-		int requeue;
 		struct pcs_cs * rcs = csl->cs[ireq->iochunk.cs_index].cslink.cs;
 
 		if (ireq->flags & IREQ_F_SEQ_READ) {
@@ -1597,11 +1606,16 @@  void pcs_deaccount_ireq(struct pcs_int_request *ireq, pcs_error_t * err)
 
 		pcs_cs_deaccount(ireq, rcs, error);
 
-		do {
+		for (;;) {
 			pcs_cs_wakeup(rcs);
 
-			requeue = pcs_cs_still_congested(rcs);
-		} while (requeue);
+			if (!pcs_cs_still_congested(rcs))
+				break;
+
+			spin_lock(&rcs->lock);
+			pcs_cs_activate_cong_queue(rcs);
+			spin_unlock(&rcs->lock);
+		};
 	}
 	*csl_p = NULL;
 	cslist_put(csl);