summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWu Bo <bo.wu@vivo.com>2023-11-21 20:51:50 -0700
committerGreg Kroah-Hartman <gregkh@google.com>2023-12-21 19:28:10 +0000
commitb170c5ce81d78ec98212f50b5ae66a3418e24b5e (patch)
tree83ccf23ecaf915e2a8c4172eb7303ebe9ff180be
parentbd56c9e1bb3e60b86c48a1036383c83f37559acc (diff)
downloadcommon-b170c5ce81d78ec98212f50b5ae66a3418e24b5e.tar.gz
UPSTREAM: dm verity: don't perform FEC for failed readahead IO
We found an issue under Android OTA scenario that many BIOs have to do FEC where the data under dm-verity is 100% complete and no corruption. Android OTA has many dm-block layers, from upper to lower: dm-verity dm-snapshot dm-origin & dm-cow dm-linear ufs DM tables have to change 2 times during Android OTA merging process. When doing table change, the dm-snapshot will be suspended for a while. During this interval, many readahead IOs are submitted to dm_verity from filesystem. Then the kverity works are busy doing FEC process which cost too much time to finish dm-verity IO. This causes needless delay which feels like system is hung. After adding debugging it was found that each readahead IO needed around 10s to finish when this situation occurred. This is due to IO amplification: dm-snapshot suspend erofs_readahead // 300+ io is submitted dm_submit_bio (dm_verity) dm_submit_bio (dm_snapshot) bio return EIO bio got nothing, it's empty verity_end_io verity_verify_io forloop range(0, io->n_blocks) // each io->nblocks ~= 20 verity_fec_decode fec_decode_rsb fec_read_bufs forloop range(0, v->fec->rsn) // v->fec->rsn = 253 new_read submit_bio (dm_snapshot) end loop end loop dm-snapshot resume Readahead BIOs get nothing while dm-snapshot is suspended, so all of them will cause verity's FEC. Each readahead BIO needs to verify ~20 (io->nblocks) blocks. Each block needs to do FEC, and every block needs to do 253 (v->fec->rsn) reads. So during the suspend interval(~200ms), 300 readahead BIOs trigger ~1518000 (300*20*253) IOs to dm-snapshot. As readahead IO is not required by userspace, and to fix this issue, it is best to pass readahead errors to upper layer to handle it. Cc: stable@vger.kernel.org Fixes: a739ff3f543a ("dm verity: add support for forward error correction") Bug: 316972624 Link: https://lore.kernel.org/dm-devel/b84fb49-bf63-3442-8c99-d565e134f2@redhat.com Signed-off-by: Wu Bo <bo.wu@vivo.com> Reviewed-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Akilesh Kailash <akailash@google.com> (cherry picked from commit 0193e3966ceeeef69e235975918b287ab093082b) Change-Id: I73560e5660cebdc1997e1f9926cbb8888789eb46
-rw-r--r--drivers/md/dm-verity-target.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 0ca29974b043..901d40a0203f 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -583,7 +583,9 @@ static void verity_end_io(struct bio *bio)
struct dm_verity_io *io = bio->bi_private;
if (bio->bi_status &&
- (!verity_fec_is_enabled(io->v) || verity_is_system_shutting_down())) {
+ (!verity_fec_is_enabled(io->v) ||
+ verity_is_system_shutting_down() ||
+ (bio->bi_opf & REQ_RAHEAD))) {
verity_finish_io(io, bio->bi_status);
return;
}