[Devel] [PATCH RHEL8 COMMIT] ploop: Introduce resubmitting partially completed pios
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Jun 17 19:01:08 MSK 2021
The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.44
------>
commit 0d296813e06d8a64ee17d691213f7139303271ca
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date: Thu Jun 17 19:01:07 2021 +0300
ploop: Introduce resubmitting partially completed pios
In case of a part of pio was written or read,
we continue its submitting in next iteration.
This will allow to handle ENOSPC in appropriate
way in the future.
Note, that the best place for resubmitting code
is in main kwork, but we can't place it there,
while BAT write is synchronuos.
https://jira.sw.ru/browse/PSBM-127225
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
=====================
Patchset description:
ploop: Allow to resubmit partially completed request
This allows to continue submitting partially completed requests.
https://jira.sw.ru/browse/PSBM-127225
Kirill Tkhai (18):
ploop: Simplify ploop_write_cluster_sync()
ploop: Rename hook->pio, h->pio, ploop_cow::hook->aux_pio
ploop: Rename force_link_inflight_bios
ploop: Introduce separate lock for inflight pios
ploop: Use hlist instead of rbtree
ploop: Always link submitted pios
ploop: Unexport ploop_inflight_bios_ref_switch()
ploop: Refactor submit_pio()
ploop: Introduce ploop_suspend_submitting_pios
ploop: Refactor ploop_ctr()
ploop: Use ploop_call_rw_iter() in submit_delta_read()
ploop: Generalize submit_rw_mapped()
ploop: Kill submit_delta_read()
ploop: Rename submit_rw_mapped()
ploop: Extract submit_rw_mapped() to separate function
ploop: Save level before submitting pio
ploop: Make fsync work be able to run in parallel with main work
ploop: Introduce resubmitting partially completed pios
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
drivers/md/dm-ploop-map.c | 46 ++++++++++++++++++++++++++++++++++++++++++--
drivers/md/dm-ploop-target.c | 1 +
drivers/md/dm-ploop.h | 1 +
3 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 4cb4ebe37f6e..6ba547626b20 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -1000,12 +1000,33 @@ static bool ploop_attach_end_action(struct pio *pio, struct ploop_index_wb *piwb
return true;
}
+static void ploop_queue_resubmit(struct pio *pio)
+{
+ struct ploop *ploop = pio->ploop;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ploop->deferred_lock, flags);
+ list_add_tail(&pio->list, &ploop->resubmit_pios);
+ spin_unlock_irqrestore(&ploop->deferred_lock, flags);
+
+ queue_work(ploop->wq, &ploop->fsync_worker);
+}
+
static void data_rw_complete(struct pio *pio)
{
bool completed;
- if (pio->ret != pio->bi_iter.bi_size)
- pio->bi_status = BLK_STS_IOERR;
+ if (pio->ret != pio->bi_iter.bi_size) {
+ if (pio->ret >= 0) {
+ /* Partial IO */
+ WARN_ON_ONCE(pio->ret == 0);
+ pio_advance(pio, pio->ret);
+ ploop_queue_resubmit(pio);
+ return;
+ }
+
+ pio->bi_status = errno_to_blk_status(pio->ret);
+ }
if (pio->is_data_alloc) {
completed = ploop_data_pio_end(pio);
@@ -1016,6 +1037,11 @@ static void data_rw_complete(struct pio *pio)
pio_endio(pio);
}
+/*
+ * XXX: Keep in mind, data_rw_complete may queue resubmit after partial IO.
+ * Don't use this function from fsync kwork in case of the caller blocks
+ * to wait for completion, since kwork is who resubmits after partial IO.
+ */
static void submit_rw_mapped(struct ploop *ploop, struct pio *pio)
{
unsigned int rw, nr_segs;
@@ -1466,6 +1492,14 @@ static void process_discard_pios(struct ploop *ploop, struct list_head *pios,
process_one_discard_pio(ploop, pio, piwb);
}
+static void process_resubmit_pios(struct ploop *ploop, struct list_head *pios)
+{
+ struct pio *pio;
+
+ while ((pio = pio_list_pop(pios)) != NULL)
+ submit_rw_mapped(ploop, pio);
+}
+
void do_ploop_work(struct work_struct *ws)
{
struct ploop *ploop = container_of(ws, struct ploop, worker);
@@ -1511,6 +1545,7 @@ void do_ploop_work(struct work_struct *ws)
void do_ploop_fsync_work(struct work_struct *ws)
{
struct ploop *ploop = container_of(ws, struct ploop, fsync_worker);
+ LIST_HEAD(resubmit_pios);
LIST_HEAD(flush_pios);
struct file *file;
struct pio *pio;
@@ -1518,8 +1553,15 @@ void do_ploop_fsync_work(struct work_struct *ws)
spin_lock_irq(&ploop->deferred_lock);
list_splice_init(&ploop->flush_pios, &flush_pios);
+ list_splice_init(&ploop->resubmit_pios, &resubmit_pios);
spin_unlock_irq(&ploop->deferred_lock);
+ /*
+ * FIXME: move this to main kwork, after BAT write
+ * will be made async.
+ */
+ process_resubmit_pios(ploop, &resubmit_pios);
+
file = top_delta(ploop)->file;
ret = vfs_fsync(file, 0);
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index 9e173f5d8d0c..5b2235319f1c 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -309,6 +309,7 @@ static int ploop_ctr(struct dm_target *ti, unsigned int argc, char **argv)
INIT_LIST_HEAD(&ploop->deferred_pios);
INIT_LIST_HEAD(&ploop->flush_pios);
INIT_LIST_HEAD(&ploop->discard_pios);
+ INIT_LIST_HEAD(&ploop->resubmit_pios);
INIT_LIST_HEAD(&ploop->cluster_lk_list);
INIT_LIST_HEAD(&ploop->delta_cow_action_list);
ploop->bat_entries = RB_ROOT;
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 533249d8eea8..fe387c981c2c 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -170,6 +170,7 @@ struct ploop {
struct list_head deferred_pios;
struct list_head flush_pios;
struct list_head discard_pios;
+ struct list_head resubmit_pios; /* After partial IO */
struct rw_semaphore ctl_rwsem;
struct ploop_cmd *deferred_cmd;
More information about the Devel
mailing list