From cc09084618100d69399991a2bba105875b6045eb Mon Sep 17 00:00:00 2001 From: "xianrong.zhou" Date: Fri, 17 Apr 2020 15:56:08 +0800 Subject: [PATCH] dm verity: don't prefetch hash blocks for already-verified data mainline inclusion from mainline-5.6-rc1 commit 0a531c5a39a71279e0a98097562bf14b5a43529e category: bugfix bugzilla: 29444 CVE: NA --------------------------- Try to skip prefetching hash blocks that won't be needed due to the "check_at_most_once" option being enabled and the corresponding data blocks already having been verified. Since prefetching operates on a range of data blocks, do this by just trimming the two ends of the range. This doesn't skip every unneeded hash block, since data blocks in the middle of the range could also be unneeded, and hash blocks are still prefetched in large clusters as controlled by dm_verity_prefetch_cluster. But it can still help a lot. In a test on Android Q launching 91 apps every 15s repeated 21 times, prefetching was only done for 447177/4776629 = 9.36% of data blocks. Tested-by: ruxian.feng Co-developed-by: yuanjiong.gao Signed-off-by: yuanjiong.gao Signed-off-by: xianrong.zhou [EB: simplified the 'while' loops and improved the commit message] Signed-off-by: Eric Biggers Signed-off-by: Mike Snitzer Signed-off-by: Sun Ke Reviewed-by: Hou Tao Signed-off-by: Yang Yingliang --- drivers/md/dm-verity-target.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index e3599b43f9eb..50ab1af8ac8a 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -611,8 +611,22 @@ static void verity_prefetch_io(struct work_struct *work) static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io) { + sector_t block = io->block; + unsigned int n_blocks = io->n_blocks; struct dm_verity_prefetch_work *pw; + if (v->validated_blocks) { + while (n_blocks && test_bit(block, v->validated_blocks)) { + block++; + n_blocks--; + } + while (n_blocks && test_bit(block + n_blocks - 1, + v->validated_blocks)) + n_blocks--; + if (!n_blocks) + return; + } + pw = kmalloc(sizeof(struct dm_verity_prefetch_work), GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); @@ -621,8 +635,8 @@ static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io) INIT_WORK(&pw->work, verity_prefetch_io); pw->v = v; - pw->block = io->block; - pw->n_blocks = io->n_blocks; + pw->block = block; + pw->n_blocks = n_blocks; queue_work(v->verify_wq, &pw->work); } -- GitLab