[Devel] [RFC PATCH vz9 v3 08/11] ploop: convert enospc handling to use lockless lists
Alexander Atanasov
alexander.atanasov at virtuozzo.com
Mon Oct 21 13:13:55 MSK 2024
Signed-off-by: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
---
drivers/md/dm-ploop-map.c | 23 ++++++++++++-----------
drivers/md/dm-ploop-target.c | 3 ++-
drivers/md/dm-ploop.h | 2 +-
3 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index f848c66ab8e7..4bd3e4c557f8 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -144,14 +144,18 @@ 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);
- unsigned long flags;
LIST_HEAD(list);
+ struct llist_node *pos, *t;
+ struct llist_node *enospc_pending = llist_del_all(&ploop->enospc_pios);
- spin_lock_irqsave(&ploop->deferred_lock, flags);
- list_splice_init(&ploop->enospc_pios, &list);
- spin_unlock_irqrestore(&ploop->deferred_lock, flags);
-
- ploop_submit_embedded_pios(ploop, &list);
+ if (enospc_pending) {
+ enospc_pending = llist_reverse_order(enospc_pending);
+ llist_for_each_safe(pos, t, enospc_pending) {
+ struct pio *pio = list_entry((struct list_head *)pos, typeof(*pio), list);
+ list_add(&pio->list, &list);
+ }
+ ploop_submit_embedded_pios(ploop, &list);
+ }
}
void do_ploop_event_work(struct work_struct *ws)
@@ -165,9 +169,7 @@ static bool ploop_try_delay_enospc(struct ploop_rq *prq, struct pio *pio)
{
struct ploop *ploop = pio->ploop;
bool delayed = true;
- unsigned long flags;
- spin_lock_irqsave(&ploop->deferred_lock, flags);
if (unlikely(ploop->wants_suspend)) {
delayed = false;
goto unlock;
@@ -177,10 +179,9 @@ static bool ploop_try_delay_enospc(struct ploop_rq *prq, struct pio *pio)
pr_err_once(PL_FMT("underlying disk is almost full"),
ploop_device_name(ploop));
- ploop->event_enospc = true;
- list_add_tail(&pio->list, &ploop->enospc_pios);
+ WRITE_ONCE(ploop->event_enospc, true);
+ llist_add((struct llist_node *)(&pio->list), &ploop->enospc_pios);
unlock:
- spin_unlock_irqrestore(&ploop->deferred_lock, flags);
if (delayed)
mod_timer(&ploop->enospc_timer, jiffies + PLOOP_ENOSPC_TIMEOUT);
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index b66ae3a9a4b0..3ac9e1f832f5 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -376,7 +376,8 @@ static int ploop_ctr(struct dm_target *ti, unsigned int argc, char **argv)
INIT_LIST_HEAD(&ploop->pios[i]);
INIT_LIST_HEAD(&ploop->resubmit_pios);
- INIT_LIST_HEAD(&ploop->enospc_pios);
+ init_llist_head(&ploop->enospc_pios);
+
INIT_LIST_HEAD(&ploop->cluster_lk_list);
init_llist_head(&ploop->wb_batch_llist);
ploop->bat_entries = RB_ROOT;
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 4a64a06d0713..f7d4a4af3381 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -199,7 +199,7 @@ struct ploop {
struct list_head pios[PLOOP_LIST_COUNT];
struct list_head resubmit_pios; /* After partial IO */
- struct list_head enospc_pios; /* Delayed after ENOSPC */
+ struct llist_head enospc_pios; /* Delayed after ENOSPC */
atomic_t service_pios;
struct wait_queue_head service_wq;
--
2.43.0
More information about the Devel
mailing list