Skip to content

Commit d95e2c3

Browse files
Hongyu JinMike Snitzer
authored andcommitted
dm verity: Fix IO priority lost when reading FEC and hash
After obtaining the data, verification or error correction process may trigger a new IO that loses the priority of the original IO, that is, the verification of the higher priority IO may be blocked by the lower priority IO. Make the IO used for verification and error correction follow the priority of the original IO. Co-developed-by: Yibin Ding <yibin.ding@unisoc.com> Signed-off-by: Yibin Ding <yibin.ding@unisoc.com> Signed-off-by: Hongyu Jin <hongyu.jin@unisoc.com> Reviewed-by: Eric Biggers <ebiggers@google.com> Reviewed-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@kernel.org>
1 parent e9b2238 commit d95e2c3

2 files changed

Lines changed: 25 additions & 15 deletions

File tree

drivers/md/dm-verity-fec.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ static int fec_decode_rs8(struct dm_verity *v, struct dm_verity_fec_io *fio,
6060
* to the data block. Caller is responsible for releasing buf.
6161
*/
6262
static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index,
63-
unsigned int *offset, struct dm_buffer **buf)
63+
unsigned int *offset, struct dm_buffer **buf,
64+
unsigned short ioprio)
6465
{
6566
u64 position, block, rem;
6667
u8 *res;
@@ -69,7 +70,7 @@ static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index,
6970
block = div64_u64_rem(position, v->fec->io_size, &rem);
7071
*offset = (unsigned int)rem;
7172

72-
res = dm_bufio_read(v->fec->bufio, block, buf);
73+
res = dm_bufio_read_with_ioprio(v->fec->bufio, block, buf, ioprio);
7374
if (IS_ERR(res)) {
7475
DMERR("%s: FEC %llu: parity read failed (block %llu): %ld",
7576
v->data_dev->name, (unsigned long long)rsb,
@@ -121,16 +122,17 @@ static inline unsigned int fec_buffer_rs_index(unsigned int i, unsigned int j)
121122
* Decode all RS blocks from buffers and copy corrected bytes into fio->output
122123
* starting from block_offset.
123124
*/
124-
static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio,
125-
u64 rsb, int byte_index, unsigned int block_offset,
126-
int neras)
125+
static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
126+
struct dm_verity_fec_io *fio, u64 rsb, int byte_index,
127+
unsigned int block_offset, int neras)
127128
{
128129
int r, corrected = 0, res;
129130
struct dm_buffer *buf;
130131
unsigned int n, i, offset;
131132
u8 *par, *block;
133+
struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
132134

133-
par = fec_read_parity(v, rsb, block_offset, &offset, &buf);
135+
par = fec_read_parity(v, rsb, block_offset, &offset, &buf, bio_prio(bio));
134136
if (IS_ERR(par))
135137
return PTR_ERR(par);
136138

@@ -158,7 +160,7 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio,
158160
if (offset >= v->fec->io_size) {
159161
dm_bufio_release(buf);
160162

161-
par = fec_read_parity(v, rsb, block_offset, &offset, &buf);
163+
par = fec_read_parity(v, rsb, block_offset, &offset, &buf, bio_prio(bio));
162164
if (IS_ERR(par))
163165
return PTR_ERR(par);
164166
}
@@ -210,6 +212,7 @@ static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io,
210212
u8 *bbuf, *rs_block;
211213
u8 want_digest[HASH_MAX_DIGESTSIZE];
212214
unsigned int n, k;
215+
struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
213216

214217
if (neras)
215218
*neras = 0;
@@ -248,7 +251,7 @@ static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io,
248251
bufio = v->bufio;
249252
}
250253

251-
bbuf = dm_bufio_read(bufio, block, &buf);
254+
bbuf = dm_bufio_read_with_ioprio(bufio, block, &buf, bio_prio(bio));
252255
if (IS_ERR(bbuf)) {
253256
DMWARN_LIMIT("%s: FEC %llu: read failed (%llu): %ld",
254257
v->data_dev->name,
@@ -377,7 +380,7 @@ static int fec_decode_rsb(struct dm_verity *v, struct dm_verity_io *io,
377380
if (unlikely(r < 0))
378381
return r;
379382

380-
r = fec_decode_bufs(v, fio, rsb, r, pos, neras);
383+
r = fec_decode_bufs(v, io, fio, rsb, r, pos, neras);
381384
if (r < 0)
382385
return r;
383386

drivers/md/dm-verity-target.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static DEFINE_STATIC_KEY_FALSE(use_tasklet_enabled);
5151
struct dm_verity_prefetch_work {
5252
struct work_struct work;
5353
struct dm_verity *v;
54+
unsigned short ioprio;
5455
sector_t block;
5556
unsigned int n_blocks;
5657
};
@@ -294,6 +295,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
294295
int r;
295296
sector_t hash_block;
296297
unsigned int offset;
298+
struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
297299

298300
verity_hash_at_level(v, block, level, &hash_block, &offset);
299301

@@ -307,8 +309,10 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
307309
*/
308310
return -EAGAIN;
309311
}
310-
} else
311-
data = dm_bufio_read(v->bufio, hash_block, &buf);
312+
} else {
313+
data = dm_bufio_read_with_ioprio(v->bufio, hash_block,
314+
&buf, bio_prio(bio));
315+
}
312316

313317
if (IS_ERR(data))
314318
return PTR_ERR(data);
@@ -752,14 +756,16 @@ static void verity_prefetch_io(struct work_struct *work)
752756
hash_block_end = v->hash_blocks - 1;
753757
}
754758
no_prefetch_cluster:
755-
dm_bufio_prefetch(v->bufio, hash_block_start,
756-
hash_block_end - hash_block_start + 1);
759+
dm_bufio_prefetch_with_ioprio(v->bufio, hash_block_start,
760+
hash_block_end - hash_block_start + 1,
761+
pw->ioprio);
757762
}
758763

759764
kfree(pw);
760765
}
761766

762-
static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io)
767+
static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io,
768+
unsigned short ioprio)
763769
{
764770
sector_t block = io->block;
765771
unsigned int n_blocks = io->n_blocks;
@@ -787,6 +793,7 @@ static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io)
787793
pw->v = v;
788794
pw->block = block;
789795
pw->n_blocks = n_blocks;
796+
pw->ioprio = ioprio;
790797
queue_work(v->verify_wq, &pw->work);
791798
}
792799

@@ -829,7 +836,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
829836

830837
verity_fec_init_io(io);
831838

832-
verity_submit_prefetch(v, io);
839+
verity_submit_prefetch(v, io, bio_prio(bio));
833840

834841
submit_bio_noacct(bio);
835842

0 commit comments

Comments
 (0)