ploop did vfs_sync(...) from interrupt context which is wrong. It worked for xfs/ext4 due to the request is offloaded to journaling which runs in different threads.
Fix this by offloading sync and respective pio endio to some of the worker threads https://virtuozzo.atlassian.net/browse/VSTOR-98792 Signed-off-by: Alexander Atanasov <alexander.atana...@virtuozzo.com> --- drivers/md/dm-ploop-map.c | 38 ++++++++++++++++++++++++++++++++++---- drivers/md/dm-ploop.h | 3 ++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c index 7efbaedd69e0..f6fc453f7464 100644 --- a/drivers/md/dm-ploop-map.c +++ b/drivers/md/dm-ploop-map.c @@ -21,6 +21,7 @@ #include "dm-rq.h" static inline int ploop_runners_add_work(struct ploop *ploop, struct pio *pio); +static inline int ploop_runners_add_work_offload(struct ploop *ploop, struct pio *pio); static void ploop_bat_write_complete(struct pio *pio, void *piwb_ptr, blk_status_t bi_status); @@ -213,6 +214,21 @@ static void ploop_prq_endio(struct pio *pio, void *prq_ptr, dm_complete_request(rq, bi_status); } +static void ploop_wrkr_pio_endio(struct pio *pio) +{ + ploop_endio_t endio_cb = pio->endio_cb; + void *endio_cb_data = pio->endio_cb_data; + bool free_on_endio = pio->free_on_endio; + struct file *file; + + file = ploop_top_delta(pio->ploop)->file; + vfs_fsync(file, 1); + endio_cb(pio, endio_cb_data, pio->bi_status); + if (free_on_endio) { + ploop_free_pio(pio->ploop, pio); + } +} + static void ploop_do_pio_endio(struct pio *pio) { ploop_endio_t endio_cb = pio->endio_cb; @@ -224,10 +240,9 @@ static void ploop_do_pio_endio(struct pio *pio) /* REQ_FUA requires us to flush all before pio is completed */ if (pio->bi_op & REQ_FUA) { - struct file *file; - - file = ploop_top_delta(pio->ploop)->file; - vfs_fsync(file, 1); + pio->queue_list_id = PLOOP_LIST_ENDPIO; + ploop_runners_add_work_offload(pio->ploop, pio); + return; } endio_cb(pio, endio_cb_data, pio->bi_status); @@ -2129,6 +2144,18 @@ static inline int ploop_runners_add_work(struct ploop *ploop, struct pio *pio) return 0; } +static inline int ploop_runners_add_work_offload(struct ploop *ploop, struct pio *pio) +{ + struct ploop_worker *wrkr; + + wrkr = READ_ONCE(ploop->last_used_runner)->next; + WRITE_ONCE(ploop->last_used_runner, wrkr); + llist_add((struct llist_node *)(&pio->list), &wrkr->work_llist); + wake_up_process(wrkr->task); + + return 0; +} + static inline int ploop_runners_add_work_list(struct ploop *ploop, struct llist_node *list) { struct llist_node *pos, *t; @@ -2346,6 +2373,9 @@ int ploop_pio_runner(void *data) case PLOOP_LIST_WRITEBACK: /* Write back pio */ ploop_submit_rw_mapped(ploop, pio); break; + case PLOOP_LIST_ENDPIO: + ploop_wrkr_pio_endio(pio); + continue; default: WARN_ON_ONCE(1); } diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h index 43e65e841e4a..06d95c525c90 100644 --- a/drivers/md/dm-ploop.h +++ b/drivers/md/dm-ploop.h @@ -145,6 +145,7 @@ enum { /* Following to be used as a list id only */ PLOOP_LIST_WRITEBACK, PLOOP_LIST_FLUSHPIO, + PLOOP_LIST_ENDPIO, }; struct ploop_worker { @@ -310,7 +311,7 @@ struct pio { #define PLOOP_REF_INDEX_INVALID 2 unsigned int ref_index:2; - u8 queue_list_id:3; /* id in ploop->pios */ + u8 queue_list_id; /* id in ploop->pios */ struct ploop_index_wb *piwb; -- 2.43.0 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel