[Devel] [PATCH RH8 02/14] dm-qcow2: Simplify parallel clu allocation and md writeback
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Jul 27 11:28:52 MSK 2021
We add qio->link to wbd->submitted_list only for later check,
whether wbd->submitted_list is empty. Use nr_submitted instead.
This will allow to use qio->link for other purposes, while
it's attached to wbd.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
drivers/md/dm-qcow2-map.c | 33 +++++++++++++++------------------
drivers/md/dm-qcow2.h | 2 +-
2 files changed, 16 insertions(+), 19 deletions(-)
diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
index 758b03a02807..01f280848de0 100644
--- a/drivers/md/dm-qcow2-map.c
+++ b/drivers/md/dm-qcow2-map.c
@@ -854,7 +854,6 @@ static struct wb_desc *alloc_wbd(bool needs_prealloced)
goto err;
}
- INIT_LIST_HEAD(&wbd->submitted_list);
INIT_LIST_HEAD(&wbd->completed_list);
INIT_LIST_HEAD(&wbd->dependent_list);
return wbd;
@@ -1357,7 +1356,7 @@ static void do_md_page_write_complete(int ret, struct qcow2 *qcow2,
* parallel data qios, wbd is finalized by last
* completed data qio.
*/
- finalize_wbd = list_empty(&wbd->submitted_list);
+ finalize_wbd = (wbd->nr_submitted == 0);
/*
* We can finish wb only in case of success.
* Otherwise this is done in finalize_wbd()
@@ -1761,7 +1760,7 @@ static loff_t parse_l2(struct qcow2 *qcow2, struct qcow2_map *map,
* but fast zeroing may be useful optimizations on big
* clusters (say, 1Mb).
* In case of md is dirty, WRITE is not delayed. It becomes
- * linked to md->wbd in perform_rw_mapped(), and it runs
+ * referred to md->wbd in perform_rw_mapped(), and it runs
* in parallel with md writeback (accompanying qio).
*/
if (!write && dirty_or_writeback(qcow2, l2->md, l2->index_in_page)) {
@@ -2692,19 +2691,18 @@ static void data_rw_complete(struct qio *qio)
bi_status = BLK_STS_IOERR;
wbd = qio->data;
- if (write && wbd) {
+ if (wbd) {
+ WARN_ON_ONCE(!write);
spin_lock_irqsave(&qcow2->md_pages_lock, flags);
- if (!list_empty(&qio->link)) {
- list_del_init(&qio->link);
- if (wbd->completed) {
- if (wbd->ret != 0)
- bi_status = errno_to_blk_status(wbd->ret);
- /* Last user of wbd? */
- finalize_wbd = list_empty(&wbd->submitted_list);
- } else if (bi_status == BLK_STS_OK) {
- call_endio = false;
- list_add_tail(&qio->link, &wbd->completed_list);
- }
+ wbd->nr_submitted--;
+ if (wbd->completed) {
+ if (wbd->ret != 0)
+ bi_status = errno_to_blk_status(wbd->ret);
+ /* Last user of wbd? */
+ finalize_wbd = (wbd->nr_submitted == 0);
+ } else if (bi_status == BLK_STS_OK) {
+ call_endio = false;
+ list_add_tail(&qio->link, &wbd->completed_list);
}
spin_unlock_irqrestore(&qcow2->md_pages_lock, flags);
}
@@ -2747,12 +2745,11 @@ static void perform_rw_mapped(struct qcow2_map *map, struct qio *qio)
rw = (op_is_write(qio->bi_op) ? WRITE : READ);
qio->complete = data_rw_complete;
qio->data = NULL;
- INIT_LIST_HEAD(&qio->link);
/*
* The idea is to submit L2 update and qio data write in parallel
* for better performance. But since qio_endio() can't be called
- * till both of them are written, we link qio to md to track that.
+ * till both of them are written, we attach qio to md to track that.
* In case of qio is not related to changed indexes, it shouldn't
* wait for md writeback completion.
*
@@ -2763,7 +2760,7 @@ static void perform_rw_mapped(struct qcow2_map *map, struct qio *qio)
if (rw == WRITE && (md->status & MD_DIRTY) &&
test_bit(index_in_page, md->wbd->changed_indexes)) {
spin_lock_irqsave(&qcow2->md_pages_lock, flags);
- list_add(&qio->link, &md->wbd->submitted_list);
+ md->wbd->nr_submitted++;
qio->data = md->wbd;
spin_unlock_irqrestore(&qcow2->md_pages_lock, flags);
}
diff --git a/drivers/md/dm-qcow2.h b/drivers/md/dm-qcow2.h
index 9d4a9f8a1453..817a39356018 100644
--- a/drivers/md/dm-qcow2.h
+++ b/drivers/md/dm-qcow2.h
@@ -62,7 +62,6 @@ struct wb_desc {
* to restore them in case of md writeback fails.
*/
struct page *pe_page;
- struct list_head submitted_list;
struct list_head completed_list;
/*
* These bios want to be dispatched in case of writeback
@@ -70,6 +69,7 @@ struct wb_desc {
* XXX: Possible we need the same for plain struct md_page.
*/
struct list_head dependent_list;
+ int nr_submitted;
bool completed;
int ret;
};
More information about the Devel
mailing list