When running out of space pios are delayed and retried from a timer. This timer is the only thing that runs in interrupt context and brings requirement to use _irqsave variants, since a complete request processing can be started from the timer. To avoid this set a flag from the timer and process delayed pios from the dispatcher thread. Follow up patches will cleanup flags saving.
https://virtuozzo.atlassian.net/browse/VSTOR-98016 Signed-off-by: Alexander Atanasov <alexander.atana...@virtuozzo.com> --- drivers/md/dm-ploop-map.c | 31 ++++++++++++++++++------------- drivers/md/dm-ploop-target.c | 2 +- drivers/md/dm-ploop.h | 2 ++ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c index 00929455fcf5..98297fb46bb6 100644 --- a/drivers/md/dm-ploop-map.c +++ b/drivers/md/dm-ploop-map.c @@ -151,12 +151,7 @@ static void ploop_init_prq_and_embedded_pio(struct ploop *ploop, void ploop_enospc_timer(struct timer_list *timer) { struct ploop *ploop = from_timer(ploop, timer, enospc_timer); - struct llist_node *enospc_pending = llist_del_all(&ploop->enospc_pios); - - if (enospc_pending) { - enospc_pending = llist_reverse_order(enospc_pending); - ploop_submit_embedded_pios(ploop, enospc_pending); - } + ploop->submit_enospc = true; } void do_ploop_event_work(struct work_struct *ws) @@ -169,12 +164,11 @@ void do_ploop_event_work(struct work_struct *ws) static bool ploop_try_delay_enospc(struct ploop_rq *prq, struct pio *pio) { struct ploop *ploop = pio->ploop; - bool delayed = true; unsigned long flags; if (unlikely(ploop->wants_suspend)) { - delayed = false; - goto unlock; + PL_WARN("dropping pio enospc\n"); + return false; } ploop_init_prq_and_embedded_pio(ploop, prq->rq, prq, pio); @@ -185,13 +179,11 @@ static bool ploop_try_delay_enospc(struct ploop_rq *prq, struct pio *pio) ploop->event_enospc = true; spin_unlock_irqrestore(&ploop->deferred_lock, flags); llist_add((struct llist_node *)(&pio->list), &ploop->enospc_pios); -unlock: - if (delayed) - mod_timer(&ploop->enospc_timer, jiffies + PLOOP_ENOSPC_TIMEOUT); + mod_timer(&ploop->enospc_timer, jiffies + PLOOP_ENOSPC_TIMEOUT); schedule_work(&ploop->event_work); - return delayed; + return true; } static void ploop_prq_endio(struct pio *pio, void *prq_ptr, @@ -2165,6 +2157,14 @@ static inline int ploop_runners_add_work_list(struct ploop *ploop, struct llist_ return 0; } +void ploop_resubmit_enospc_pios(struct ploop *ploop) +{ + struct llist_node *enospc_pending = llist_del_all(&ploop->enospc_pios); + + if (enospc_pending) + ploop_submit_embedded_pios(ploop, llist_reverse_order(enospc_pending)); +} + void do_ploop_run_work(struct ploop *ploop) { LLIST_HEAD(deferred_pios); @@ -2180,6 +2180,11 @@ void do_ploop_run_work(struct ploop *ploop) current->flags |= PF_IO_THREAD|PF_LOCAL_THROTTLE|PF_MEMALLOC_NOIO; + if (ploop->submit_enospc) { + ploop->submit_enospc = false; + ploop_resubmit_enospc_pios(ploop); + } + llembedded_pios = llist_del_all(&ploop->pios[PLOOP_LIST_PREPARE]); lldeferred_pios = llist_del_all(&ploop->pios[PLOOP_LIST_DEFERRED]); diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c index 641950031fe3..f306f0c85ee5 100644 --- a/drivers/md/dm-ploop-target.c +++ b/drivers/md/dm-ploop-target.c @@ -695,7 +695,7 @@ static void ploop_presuspend(struct dm_target *ti) wait_event_interruptible(ploop->dispatcher_wq_data, (!atomic_read(&ploop->kt_worker->inflight_pios))); vfs_fsync(ploop_top_delta(ploop)->file, 0); - ploop_enospc_timer(&ploop->enospc_timer); + ploop_resubmit_enospc_pios(ploop); } static void ploop_presuspend_undo(struct dm_target *ti) diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h index edf9b1448887..43e65e841e4a 100644 --- a/drivers/md/dm-ploop.h +++ b/drivers/md/dm-ploop.h @@ -259,6 +259,7 @@ struct ploop { bool nokblkcg; struct timer_list enospc_timer; + bool submit_enospc; /* timer expired run pios from dispatcher */ bool event_enospc; loff_t prealloc_size; @@ -637,5 +638,6 @@ extern void ploop_disable_writeback_delay(struct ploop *ploop); extern void ploop_enable_writeback_delay(struct ploop *ploop); extern void ploop_should_prealloc(struct ploop *ploop, struct file *file); +extern void ploop_resubmit_enospc_pios(struct ploop *ploop); #endif /* __DM_PLOOP_H */ -- 2.43.0 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel