From: Hongyu Jin <[email protected]>

After obtaining the data, verification or error correction process may
trigger a new I/O that loses the priority of the original I/O, that is,
the verification of the higher priority IO may be blocked by the lower
priority IO.

Make the I/O of verification and error correction follow the
priority of original I/O.

Co-developed-by: Yibin Ding <[email protected]>
Signed-off-by: Yibin Ding <[email protected]>
Signed-off-by: Hongyu Jin <[email protected]>
---
 drivers/md/dm-verity-fec.c    | 20 +++++++++++++++-----
 drivers/md/dm-verity-target.c | 12 ++++++++----
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
index 49db19e537f9..a9e5402e3d43 100644
--- a/drivers/md/dm-verity-fec.c
+++ b/drivers/md/dm-verity-fec.c
@@ -18,6 +18,12 @@ bool verity_fec_is_enabled(struct dm_verity *v)
        return v->fec && v->fec->dev;
 }
 
+static inline struct dm_verity_io *verity_io(struct dm_verity *v, struct 
dm_verity_fec_io *fio)
+{
+       return (struct dm_verity_io *)
+               ((char *)fio + sizeof(struct dm_verity_fec_io) - 
v->ti->per_io_data_size);
+}
+
 /*
  * Return a pointer to dm_verity_fec_io after dm_verity_io and its variable
  * length fields.
@@ -60,7 +66,8 @@ static int fec_decode_rs8(struct dm_verity *v, struct 
dm_verity_fec_io *fio,
  * to the data block. Caller is responsible for releasing buf.
  */
 static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index,
-                          unsigned int *offset, struct dm_buffer **buf)
+                          unsigned int *offset, struct dm_buffer **buf,
+                          unsigned short ioprio)
 {
        u64 position, block, rem;
        u8 *res;
@@ -69,7 +76,7 @@ static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int 
index,
        block = div64_u64_rem(position, v->fec->io_size, &rem);
        *offset = (unsigned int)rem;
 
-       res = dm_bufio_read(v->fec->bufio, block, buf, IOPRIO_DEFAULT);
+       res = dm_bufio_read(v->fec->bufio, block, buf, ioprio);
        if (IS_ERR(res)) {
                DMERR("%s: FEC %llu: parity read failed (block %llu): %ld",
                      v->data_dev->name, (unsigned long long)rsb,
@@ -129,8 +136,10 @@ static int fec_decode_bufs(struct dm_verity *v, struct 
dm_verity_fec_io *fio,
        struct dm_buffer *buf;
        unsigned int n, i, offset;
        u8 *par, *block;
+       struct dm_verity_io *io = verity_io(v, fio);
+       struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
 
-       par = fec_read_parity(v, rsb, block_offset, &offset, &buf);
+       par = fec_read_parity(v, rsb, block_offset, &offset, &buf, 
bio_prio(bio));
        if (IS_ERR(par))
                return PTR_ERR(par);
 
@@ -158,7 +167,7 @@ static int fec_decode_bufs(struct dm_verity *v, struct 
dm_verity_fec_io *fio,
                if (offset >= v->fec->io_size) {
                        dm_bufio_release(buf);
 
-                       par = fec_read_parity(v, rsb, block_offset, &offset, 
&buf);
+                       par = fec_read_parity(v, rsb, block_offset, &offset, 
&buf, bio_prio(bio));
                        if (IS_ERR(par))
                                return PTR_ERR(par);
                }
@@ -210,6 +219,7 @@ static int fec_read_bufs(struct dm_verity *v, struct 
dm_verity_io *io,
        u8 *bbuf, *rs_block;
        u8 want_digest[HASH_MAX_DIGESTSIZE];
        unsigned int n, k;
+       struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
 
        if (neras)
                *neras = 0;
@@ -248,7 +258,7 @@ static int fec_read_bufs(struct dm_verity *v, struct 
dm_verity_io *io,
                        bufio = v->bufio;
                }
 
-               bbuf = dm_bufio_read(bufio, block, &buf, IOPRIO_DEFAULT);
+               bbuf = dm_bufio_read(bufio, block, &buf, bio_prio(bio));
                if (IS_ERR(bbuf)) {
                        DMWARN_LIMIT("%s: FEC %llu: read failed (%llu): %ld",
                                     v->data_dev->name,
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 4758bfe2c156..8cbf81fc0031 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -51,6 +51,7 @@ static DEFINE_STATIC_KEY_FALSE(use_tasklet_enabled);
 struct dm_verity_prefetch_work {
        struct work_struct work;
        struct dm_verity *v;
+       unsigned short ioprio;
        sector_t block;
        unsigned int n_blocks;
 };
@@ -294,6 +295,7 @@ static int verity_verify_level(struct dm_verity *v, struct 
dm_verity_io *io,
        int r;
        sector_t hash_block;
        unsigned int offset;
+       struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
 
        verity_hash_at_level(v, block, level, &hash_block, &offset);
 
@@ -308,7 +310,7 @@ static int verity_verify_level(struct dm_verity *v, struct 
dm_verity_io *io,
                        return -EAGAIN;
                }
        } else
-               data = dm_bufio_read(v->bufio, hash_block, &buf, 
IOPRIO_DEFAULT);
+               data = dm_bufio_read(v->bufio, hash_block, &buf, bio_prio(bio));
 
        if (IS_ERR(data))
                return PTR_ERR(data);
@@ -720,13 +722,14 @@ static void verity_prefetch_io(struct work_struct *work)
 no_prefetch_cluster:
                dm_bufio_prefetch(v->bufio, hash_block_start,
                                  hash_block_end - hash_block_start + 1,
-                                 IOPRIO_DEFAULT);
+                                 pw->ioprio);
        }
 
        kfree(pw);
 }
 
-static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io 
*io)
+static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io 
*io,
+                                  unsigned short ioprio)
 {
        sector_t block = io->block;
        unsigned int n_blocks = io->n_blocks;
@@ -754,6 +757,7 @@ static void verity_submit_prefetch(struct dm_verity *v, 
struct dm_verity_io *io)
        pw->v = v;
        pw->block = block;
        pw->n_blocks = n_blocks;
+       pw->ioprio = ioprio;
        queue_work(v->verify_wq, &pw->work);
 }
 
@@ -796,7 +800,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
 
        verity_fec_init_io(io);
 
-       verity_submit_prefetch(v, io);
+       verity_submit_prefetch(v, io, bio_prio(bio));
 
        submit_bio_noacct(bio);
 
-- 
2.34.1


Reply via email to