[Devel] [PATCH vz9 v1 06/63] dm-ploop: convert enospc handling to use lockless lists
Alexander Atanasov
alexander.atanasov at virtuozzo.com
Fri Jan 24 18:35:40 MSK 2025
https://virtuozzo.atlassian.net/browse/VSTOR-91820
Signed-off-by: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
---
drivers/md/dm-ploop-map.c | 21 +++++++++++++--------
drivers/md/dm-ploop-target.c | 3 ++-
drivers/md/dm-ploop.h | 2 +-
3 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 5fb98740f32e..08d5391aa9d3 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -143,14 +143,19 @@ 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);
+ 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);
- ploop_submit_embedded_pios(ploop, &list);
+ list_add(&pio->list, &list);
+ }
+ ploop_submit_embedded_pios(ploop, &list);
+ }
}
void do_ploop_event_work(struct work_struct *ws)
@@ -166,7 +171,6 @@ static bool ploop_try_delay_enospc(struct ploop_rq *prq, struct pio *pio)
bool delayed = true;
unsigned long flags;
- spin_lock_irqsave(&ploop->deferred_lock, flags);
if (unlikely(ploop->wants_suspend)) {
delayed = false;
goto unlock;
@@ -176,10 +180,11 @@ 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));
+ spin_lock_irqsave(&ploop->deferred_lock, flags);
ploop->event_enospc = true;
- list_add_tail(&pio->list, &ploop->enospc_pios);
-unlock:
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);
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 b640bf275473..da5d8cfcf8ca 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -198,7 +198,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