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

Reply via email to