From: Denis V. Lunev <[email protected]> A write that fails with ENOSPC on the image is held on enospc_pios and retried when enospc_timer fires, so that I/O resumes once space is freed. ploop_enospc_timer() only sets submit_enospc, which only do_ploop_run_work() consumes, and nothing wakes the dispatcher for it. ploop_worker() also goes to sleep with the flag set, as its sleep condition checks the pio lists only.
The held writes are retried only when other I/O reaches the device: on a device whose only I/O is the held writes, the writers stay in D state after the space is freed. Wake the dispatcher from the timer, and keep ploop_worker() awake while submit_enospc is set, so that a wakeup that comes while the dispatcher is busy is not lost. Test and clear the flag with xchg() in do_ploop_run_work(). https://virtuozzo.atlassian.net/browse/VSTOR-154182 Fixes: afc60480b037 ("dm-ploop: resubmit enospc pios from dispatcher thread") Feature: dm-ploop: ploop target driver Signed-off-by: Denis V. Lunev <[email protected]> --- drivers/md/dm-ploop-map.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c index ae3e287604b7..a4e17aa090a6 100644 --- a/drivers/md/dm-ploop-map.c +++ b/drivers/md/dm-ploop-map.c @@ -165,7 +165,9 @@ static void ploop_init_prq_and_embedded_pio(struct ploop *ploop, void ploop_enospc_timer(struct timer_list *timer) { struct ploop *ploop = timer_container_of(ploop, timer, enospc_timer); - ploop->submit_enospc = true; + + WRITE_ONCE(ploop->submit_enospc, true); + wake_up_process(ploop->kt_worker->task); } void do_ploop_event_work(struct work_struct *ws) @@ -2241,10 +2243,8 @@ static void do_ploop_run_work(struct ploop *ploop) current->flags |= PLOOP_PFLAGS; - if (ploop->submit_enospc) { - ploop->submit_enospc = false; + if (xchg(&ploop->submit_enospc, false)) ploop_resubmit_enospc_pios(ploop); - } llembedded_pios = llist_del_all(&ploop->pios[PLOOP_LIST_PREPARE]); @@ -2447,6 +2447,7 @@ int ploop_worker(void *data) llist_empty(&ploop->pios[PLOOP_LIST_DISCARD]) && llist_empty(&ploop->pios[PLOOP_LIST_COW]) && llist_empty(&ploop->llresubmit_pios) && + !READ_ONCE(ploop->submit_enospc) && !ploop->force_md_writeback) { if (kthread_should_stop()) { wait_event_interruptible( -- 2.53.0 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
