pmem_submit_bio() handles flush-only bios before and after the data loop. Keep dataless bios out of bio_for_each_segment() so the data path only walks bios that actually carry bvec data.
Signed-off-by: Li Chen <[email protected]> --- Changes in v6: - New patch. drivers/nvdimm/pmem.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 05d3de33e2706..82ee1ddb3a445 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -217,23 +217,29 @@ static void pmem_submit_bio(struct bio *bio) } } - do_acct = blk_queue_io_stat(bio->bi_bdev->bd_disk->queue); - if (do_acct) - start = bio_start_io_acct(bio); - bio_for_each_segment(bvec, bio, iter) { - if (op_is_write(bio_op(bio))) - rc = pmem_do_write(pmem, bvec.bv_page, bvec.bv_offset, - iter.bi_sector, bvec.bv_len); - else - rc = pmem_do_read(pmem, bvec.bv_page, bvec.bv_offset, - iter.bi_sector, bvec.bv_len); - if (rc) { - bio->bi_status = rc; - break; + if (bio_has_data(bio)) { + do_acct = blk_queue_io_stat(bio->bi_bdev->bd_disk->queue); + if (do_acct) + start = bio_start_io_acct(bio); + bio_for_each_segment(bvec, bio, iter) { + if (op_is_write(bio_op(bio))) + rc = pmem_do_write(pmem, bvec.bv_page, + bvec.bv_offset, + iter.bi_sector, + bvec.bv_len); + else + rc = pmem_do_read(pmem, bvec.bv_page, + bvec.bv_offset, + iter.bi_sector, + bvec.bv_len); + if (rc) { + bio->bi_status = rc; + break; + } } + if (do_acct) + bio_end_io_acct(bio, start); } - if (do_acct) - bio_end_io_acct(bio, start); if ((bio->bi_opf & REQ_FUA) && !bio->bi_status) ret = nvdimm_flush(nd_region, bio); -- 2.52.0

