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

Reply via email to