[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