[Devel] [PATCH vz9 v1 59/63] dm-ploop: resubmit enospc pios from dispatcher thread
Alexander Atanasov
alexander.atanasov at virtuozzo.com
Fri Jan 24 18:36:33 MSK 2025
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.atanasov at 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
More information about the Devel
mailing list