[Devel] [PATCH vz9 v1 48/63] dm-ploop: use filp per thread
Alexander Atanasov
alexander.atanasov at virtuozzo.com
Fri Jan 24 18:36:22 MSK 2025
For some reason this fixed xfs issues .
I do not know why yet.
To be investigated. And probably reverted.
https://virtuozzo.atlassian.net/browse/VSTOR-91821
Signed-off-by: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
---
drivers/md/dm-ploop-bat.c | 15 ++++++++++++-
drivers/md/dm-ploop-cmd.c | 6 ++++--
drivers/md/dm-ploop-map.c | 41 ++++++++++++++++++++++--------------
drivers/md/dm-ploop-target.c | 8 +++++++
drivers/md/dm-ploop.h | 7 +++++-
5 files changed, 57 insertions(+), 20 deletions(-)
diff --git a/drivers/md/dm-ploop-bat.c b/drivers/md/dm-ploop-bat.c
index afbd43d74c6a..88b1d02b47d5 100644
--- a/drivers/md/dm-ploop-bat.c
+++ b/drivers/md/dm-ploop-bat.c
@@ -482,7 +482,7 @@ int ploop_add_delta(struct ploop *ploop, u32 level, struct file *file, bool is_r
struct rb_root md_root = RB_ROOT;
loff_t file_size;
u32 nr_be;
- int ret;
+ int ret, i;
ret = ploop_check_delta_length(ploop, file, &file_size);
if (ret)
@@ -503,6 +503,19 @@ int ploop_add_delta(struct ploop *ploop, u32 level, struct file *file, bool is_r
ploop_apply_delta_mappings(ploop, deltas, level, &md_root, nr_be);
deltas[level].file = file;
+ deltas[level].mtfile = kcalloc(ploop->nkt_runners, sizeof(*file),
+ GFP_KERNEL);
+ if (!deltas[level].mtfile) {
+ ret = ENOMEM;
+ goto out;
+ }
+ for (i = 0; i < ploop->nkt_runners; i++) {
+ deltas[level].mtfile[i] = file_clone_open(file);
+ if (!deltas[level].mtfile[i]) {
+ ret = ENOMEM;
+ goto out;
+ }
+ }
deltas[level].file_size = file_size;
deltas[level].file_preallocated_area_start = file_size;
deltas[level].nr_be = nr_be;
diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index e080d6afaa7f..50a23212270d 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -316,7 +316,8 @@ static int ploop_grow_relocate_cluster(struct ploop *ploop,
}
spin_lock_irq(&ploop->bat_lock);
- ret = ploop_prepare_reloc_index_wb(ploop, &md, clu, &new_dst);
+ ret = ploop_prepare_reloc_index_wb(ploop, &md, clu, &new_dst,
+ ploop_top_delta(ploop)->file);
spin_unlock_irq(&ploop->bat_lock);
if (ret < 0) {
PL_ERR("reloc: can't prepare it: %d", ret);
@@ -380,7 +381,8 @@ static int ploop_grow_update_header(struct ploop *ploop,
int ret;
/* hdr is in the same page as bat_entries[0] index */
- ret = ploop_prepare_reloc_index_wb(ploop, &md, 0, NULL);
+ ret = ploop_prepare_reloc_index_wb(ploop, &md, 0, NULL,
+ ploop_top_delta(ploop)->file);
if (ret)
return ret;
piwb = md->piwb;
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 4b4facc79aba..7d531564b24c 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -75,6 +75,7 @@ void ploop_index_wb_init(struct ploop_index_wb *piwb, struct ploop *ploop)
void ploop_init_pio(struct ploop *ploop, unsigned int bi_op, struct pio *pio)
{
+ pio->runner_id = 0;
pio->ploop = ploop;
pio->css = NULL;
pio->bi_op = bi_op;
@@ -694,7 +695,7 @@ static int ploop_handle_discard_pio(struct ploop *ploop, struct pio *pio,
punch_hole:
ploop_remap_to_cluster(ploop, pio, dst_clu);
pos = to_bytes(pio->bi_iter.bi_sector);
- ret = ploop_punch_hole(ploop_top_delta(ploop)->file, pos,
+ ret = ploop_punch_hole(ploop_top_delta(ploop)->mtfile[pio->runner_id], pos,
pio->bi_iter.bi_size);
if (ret || ploop->nr_deltas != 1) {
if (ret)
@@ -1080,9 +1081,9 @@ ALLOW_ERROR_INJECTION(ploop_find_dst_clu_bit, ERRNO);
static int ploop_truncate_prealloc_safe(struct ploop *ploop,
struct ploop_delta *delta,
- loff_t len, const char *func)
+ loff_t len, struct file *file,
+ const char *func)
{
- struct file *file = delta->file;
loff_t old_len = delta->file_size;
loff_t new_len = len;
int ret;
@@ -1106,12 +1107,11 @@ static int ploop_truncate_prealloc_safe(struct ploop *ploop,
}
ALLOW_ERROR_INJECTION(ploop_truncate_prealloc_safe, ERRNO);
-static int ploop_allocate_cluster(struct ploop *ploop, u32 *dst_clu)
+static int ploop_allocate_cluster(struct ploop *ploop, u32 *dst_clu, struct file *file)
{
struct ploop_delta *top = ploop_top_delta(ploop);
u32 clu_size = CLU_SIZE(ploop);
loff_t off, pos, end, old_size;
- struct file *file = top->file;
unsigned long flags;
int ret;
@@ -1156,7 +1156,7 @@ static int ploop_allocate_cluster(struct ploop *ploop, u32 *dst_clu)
}
if (end > old_size) {
- ret = ploop_truncate_prealloc_safe(ploop, top, end, __func__);
+ ret = ploop_truncate_prealloc_safe(ploop, top, end, file, __func__);
if (ret) {
ploop_hole_set_bit(*dst_clu, ploop);
return ret;
@@ -1175,7 +1175,7 @@ ALLOW_ERROR_INJECTION(ploop_allocate_cluster, ERRNO);
* in ploop->holes_bitmap and bat_page.
*/
static int ploop_alloc_cluster(struct ploop *ploop, struct ploop_index_wb *piwb,
- u32 clu, u32 *dst_clu)
+ u32 clu, u32 *dst_clu, struct file *file)
{
bool already_alloced = false;
map_index_t *to;
@@ -1198,8 +1198,8 @@ static int ploop_alloc_cluster(struct ploop *ploop, struct ploop_index_wb *piwb,
if (already_alloced)
goto out;
- ret = ploop_allocate_cluster(ploop, dst_clu);
- if (ret < 0)
+ ret = ploop_allocate_cluster(ploop, dst_clu, file);
+ if (unlikely(ret < 0))
goto out;
to = kmap_local_page(piwb->bat_page);
@@ -1332,7 +1332,7 @@ static void ploop_submit_rw_mapped(struct ploop *ploop, struct pio *pio)
pos = to_bytes(pio->bi_iter.bi_sector);
- file = ploop->deltas[pio->level].file;
+ file = ploop->deltas[pio->level].mtfile[pio->runner_id];
/* Don't touch @pio after that */
if (pio->css && !ploop->nokblkcg) {
@@ -1436,14 +1436,14 @@ static int ploop_initiate_cluster_cow(struct ploop *ploop, unsigned int level,
}
ALLOW_ERROR_INJECTION(ploop_submit_cluster_cow, ERRNO);
-static void ploop_submit_cluster_write(struct ploop_cow *cow)
+static void ploop_submit_cluster_write(struct ploop_cow *cow, struct file *file)
{
struct pio *aux_pio = cow->aux_pio;
struct ploop *ploop = cow->ploop;
u32 dst_clu;
int ret;
- ret = ploop_allocate_cluster(ploop, &dst_clu);
+ ret = ploop_allocate_cluster(ploop, &dst_clu, file);
if (unlikely(ret < 0))
goto error;
cow->dst_clu = dst_clu;
@@ -1524,6 +1524,7 @@ static void ploop_submit_cow_index_wb(struct ploop_cow *cow)
static void ploop_process_one_delta_cow(struct ploop *ploop, struct pio *aux_pio)
{
struct ploop_cow *cow;
+ struct file *file;
cow = aux_pio->endio_cb_data;
if (unlikely(aux_pio->bi_status != BLK_STS_OK)) {
@@ -1532,12 +1533,15 @@ static void ploop_process_one_delta_cow(struct ploop *ploop, struct pio *aux_pio
}
/* until type is changed */
INIT_LIST_HEAD(&aux_pio->list);
+
+ file = ploop_top_delta(ploop)->mtfile[aux_pio->runner_id];
+
if (cow->dst_clu == BAT_ENTRY_NONE) {
/*
* Stage #1: assign dst_clu and write data
* to top delta.
*/
- ploop_submit_cluster_write(cow);
+ ploop_submit_cluster_write(cow, file);
} else {
/*
* Stage #2: data is written to top delta.
@@ -1572,6 +1576,7 @@ static bool ploop_locate_new_cluster_and_attach_pio(struct ploop *ploop,
u32 page_id;
int err;
unsigned long flags;
+ struct file *file;
WARN_ON_ONCE(pio->queue_list_id != PLOOP_LIST_DEFERRED);
spin_lock_irqsave(&ploop->bat_lock, flags);
@@ -1596,7 +1601,9 @@ static bool ploop_locate_new_cluster_and_attach_pio(struct ploop *ploop,
piwb = md->piwb;
- err = ploop_alloc_cluster(ploop, piwb, clu, dst_clu);
+ file = ploop_top_delta(ploop)->mtfile[pio->runner_id];
+
+ err = ploop_alloc_cluster(ploop, piwb, clu, dst_clu, file);
if (err) {
pio->bi_status = errno_to_blk_status(err);
clear_bit(MD_DIRTY, &md->status);
@@ -2076,6 +2083,7 @@ int ploop_pio_runner(void *data)
llist_for_each_safe(pos, t, llwork) {
pio = list_entry((struct list_head *)pos, typeof(*pio), list);
INIT_LIST_HEAD(&pio->list);
+ pio->runner_id = worker->runner_id;
switch (pio->queue_list_id) {
case PLOOP_LIST_FLUSH:
WARN_ON_ONCE(1); /* We must not see flushes here */
@@ -2350,7 +2358,8 @@ static void ploop_handle_cleanup(struct ploop *ploop, struct pio *pio)
*/
int ploop_prepare_reloc_index_wb(struct ploop *ploop,
struct md_page **ret_md,
- u32 clu, u32 *dst_clu)
+ u32 clu, u32 *dst_clu,
+ struct file *file)
{
enum piwb_type type = PIWB_TYPE_ALLOC;
u32 page_id = ploop_bat_clu_to_page_nr(clu);
@@ -2380,7 +2389,7 @@ int ploop_prepare_reloc_index_wb(struct ploop *ploop,
* holes_bitmap.
*/
ploop_bat_page_zero_cluster(ploop, piwb, clu);
- err = ploop_alloc_cluster(ploop, piwb, clu, dst_clu);
+ err = ploop_alloc_cluster(ploop, piwb, clu, dst_clu, file);
if (err)
goto out_reset;
}
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index 56539406ce10..e8beacc5841b 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -201,6 +201,10 @@ static void ploop_destroy(struct ploop *ploop)
while (ploop->nr_deltas-- > 0) {
if (ploop->deltas[ploop->nr_deltas].file)
fput(ploop->deltas[ploop->nr_deltas].file);
+ for (i = 0; i < ploop->nkt_runners; i++) {
+ if (ploop->deltas[ploop->nr_deltas].mtfile[i])
+ fput(ploop->deltas[ploop->nr_deltas].mtfile[i]);
+ }
}
WARN_ON(ploop_has_pending_activity(ploop));
WARN_ON(!ploop_empty_htable(ploop->exclusive_pios));
@@ -379,6 +383,10 @@ static struct ploop_worker *ploop_worker_create(struct ploop *ploop,
if (IS_ERR(task))
goto out_err;
worker->task = task;
+ if (*pref == 'r')
+ worker->runner_id = id - 1;
+ else
+ worker->runner_id = 0;
init_llist_head(&worker->work_llist);
wake_up_process(task);
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index ad1033c0898a..9f193afab618 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -42,6 +42,7 @@ struct ploop_pvd_header {
struct ploop_delta {
struct file *file;
+ struct file **mtfile;
loff_t file_size;
loff_t file_preallocated_area_start;
u32 nr_be; /* nr BAT entries (or file length in clus if RAW) */
@@ -150,6 +151,7 @@ struct ploop_worker {
struct ploop *ploop;
struct task_struct *task;
struct llist_head work_llist;
+ unsigned int runner_id;
atomic_t inflight_pios;
struct ploop_worker *next;
};
@@ -310,6 +312,8 @@ struct pio {
void (*complete)(struct pio *me);
void *data;
+ unsigned int runner_id;
+
atomic_t md_inflight;
};
@@ -596,7 +600,8 @@ extern int ploop_rw_page_sync(unsigned rw, struct file *file,
extern void ploop_map_and_submit_rw(struct ploop *ploop, u32 dst_clu,
struct pio *pio, u8 level);
extern int ploop_prepare_reloc_index_wb(struct ploop *ploop,
- struct md_page **ret_md, u32 clu, u32 *dst_clu);
+ struct md_page **ret_md, u32 clu, u32 *dst_clu,
+ struct file *file);
extern void ploop_break_bat_update(struct ploop *ploop, struct md_page *md);
extern void ploop_index_wb_submit(struct ploop *, struct ploop_index_wb *);
extern int ploop_message(struct dm_target *ti, unsigned int argc, char **argv,
--
2.43.0
More information about the Devel
mailing list