|
|
887953 |
From c1d83132c4b2d49eb922fb7fe42952856aeff83d Mon Sep 17 00:00:00 2001
|
|
|
887953 |
From: Raghavendra G <rgowdapp@redhat.com>
|
|
|
887953 |
Date: Sat, 8 Sep 2018 19:53:07 +0530
|
|
|
887953 |
Subject: [PATCH 371/385] performance/write-behind: remove the request from wip
|
|
|
887953 |
queue in wb_fulfill_request
|
|
|
887953 |
|
|
|
887953 |
The bug is very similar to bz 1379655 and the fix too very similar to
|
|
|
887953 |
commit a8b2a981881221925bb5edfe7bb65b25ad855c04.
|
|
|
887953 |
|
|
|
887953 |
Before this patch, a request is removed from wip queue only when ref
|
|
|
887953 |
count of request hits 0. Though, wb_fulfill_request does an unref,
|
|
|
887953 |
it need not be the last unref and hence the request may survive in
|
|
|
887953 |
wip queue till the last unref. Let,
|
|
|
887953 |
|
|
|
887953 |
T1: the time at which wb_fulfill_request is invoked
|
|
|
887953 |
T2: the time at which last unref is done on request
|
|
|
887953 |
|
|
|
887953 |
Let's consider a case of T2 > T1. In the time window between T1 and
|
|
|
887953 |
T2, any other request (waiter) conflicting with request in liability
|
|
|
887953 |
queue (blocker - basically a write which has been lied) is blocked
|
|
|
887953 |
from winding. If T2 happens to be when wb_do_unwinds is invoked, no
|
|
|
887953 |
further processing of request list happens and "waiter" would get
|
|
|
887953 |
blocked forever. An example imaginary sequence of events is given
|
|
|
887953 |
below:
|
|
|
887953 |
|
|
|
887953 |
1. A write request w1 is picked up for winding in __wb_pick_winds
|
|
|
887953 |
and w1 is moved to wip queue. Let's call this
|
|
|
887953 |
invocation of wb_process_queue by wb_writev as PQ1. Note w1 is not
|
|
|
887953 |
unwound.
|
|
|
887953 |
|
|
|
887953 |
2. A dependent write (w2) hits write-behind and is unwound followed by
|
|
|
887953 |
a flush (f1) request. Since the liability queue
|
|
|
887953 |
of inode is not empty, w2 and f1 are not picked for unwinding. Let's call
|
|
|
887953 |
the invocation of wb_process_queue by wb_flush as PQ2. Note that
|
|
|
887953 |
invocation of wb_process_queue by w2 doesn't wind w2 instead
|
|
|
887953 |
unwinds it after which we hit PQ2
|
|
|
887953 |
|
|
|
887953 |
3. PQ2 continues and picks w1 for fulfilling and invokes
|
|
|
887953 |
wb_fulfill. As part of successful wb_fulfill_cbk,
|
|
|
887953 |
wb_fulfill_request (w1) is invoked. But, w1 is not freed (and hence
|
|
|
887953 |
not removed from wip queue) as w1 is not unwound _yet_ and a
|
|
|
887953 |
ref remains (PQ1 has not invoked wb_do_unwinds _yet_).
|
|
|
887953 |
|
|
|
887953 |
4. wb_fulfill_cbk (triggered by PQ2) invokes a wb_process_queue (let's
|
|
|
887953 |
say PQ3). w2 is not picked up for winding in PQ3 as w1 is still in wip
|
|
|
887953 |
queue. At this time, PQ2 and PQ3 are complete.
|
|
|
887953 |
|
|
|
887953 |
5. PQ1 continues, unwinds w1 and does last unref on w1 and w1 is freed
|
|
|
887953 |
(and removed from wip queue). Since PQ1 didn't invoke
|
|
|
887953 |
wb_fulfill on any other write requests, there won't be any future
|
|
|
887953 |
codepaths that would invoke wb_process_queue and w2 is stuck
|
|
|
887953 |
forever. This will prevent f2 too and hence close syscall is hung
|
|
|
887953 |
|
|
|
887953 |
With this fix, w1 is removed from liability queue in step 3 above and
|
|
|
887953 |
PQ3 winds w2 in step 4 (as there are no requests conflicting with w2
|
|
|
887953 |
in liability queue during execution of PQ3). Once w2 is complete, f1
|
|
|
887953 |
is resumed.
|
|
|
887953 |
|
|
|
887953 |
>Change-Id: Ia972fad0858dc4abccdc1227cb4d880f85b3b89b
|
|
|
887953 |
>Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
|
|
|
887953 |
>Fixes: bz#1626787
|
|
|
887953 |
|
|
|
887953 |
Change-Id: Ia972fad0858dc4abccdc1227cb4d880f85b3b89b
|
|
|
887953 |
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
|
|
|
887953 |
BUG: 1626780
|
|
|
887953 |
upstream patch: https://review.gluster.org/21123
|
|
|
887953 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/149775
|
|
|
887953 |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
887953 |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
887953 |
---
|
|
|
887953 |
xlators/performance/write-behind/src/write-behind.c | 1 +
|
|
|
887953 |
1 file changed, 1 insertion(+)
|
|
|
887953 |
|
|
|
887953 |
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
|
|
|
887953 |
index ca1cb63..478985a 100644
|
|
|
887953 |
--- a/xlators/performance/write-behind/src/write-behind.c
|
|
|
887953 |
+++ b/xlators/performance/write-behind/src/write-behind.c
|
|
|
887953 |
@@ -725,6 +725,7 @@ __wb_fulfill_request (wb_request_t *req)
|
|
|
887953 |
*/
|
|
|
887953 |
}
|
|
|
887953 |
|
|
|
887953 |
+ list_del_init (&req->wip);
|
|
|
887953 |
__wb_request_unref (req);
|
|
|
887953 |
}
|
|
|
887953 |
|
|
|
887953 |
--
|
|
|
887953 |
1.8.3.1
|
|
|
887953 |
|