From ba2cce82ba1ba74cd83bb3fd0e47849af4f2a605 Mon Sep 17 00:00:00 2001
From: Mike Snitzer <snitzer@kernel.org>
Date: Mon, 25 Jul 2022 16:52:17 -0400
Subject: [PATCH] dm verity: conditionally enable branching for
"try_verify_in_tasklet"
Git-commit: ba2cce82ba1ba74cd83bb3fd0e47849af4f2a605
Patch-mainline: v6.0-rc1
References: jsc#PED-2765
Use jump_label to limit the need for branching unless the optional
"try_verify_in_tasklet" feature is used.
(Coly Li: rebased for Linux v5.14 based SUSE kernel)
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Coly Li <colyli@suse.de>
---
drivers/md/dm-verity-target.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -20,6 +20,7 @@
#include <linux/reboot.h>
#include <linux/scatterlist.h>
#include <linux/string.h>
+#include <linux/jump_label.h>
#define DM_MSG_PREFIX "verity"
@@ -44,6 +45,8 @@ static unsigned dm_verity_prefetch_clust
module_param_named(prefetch_cluster, dm_verity_prefetch_cluster, uint, S_IRUGO | S_IWUSR);
+static DEFINE_STATIC_KEY_FALSE(use_tasklet_enabled);
+
struct dm_verity_prefetch_work {
struct work_struct work;
struct dm_verity *v;
@@ -288,7 +291,7 @@ static int verity_verify_level(struct dm
verity_hash_at_level(v, block, level, &hash_block, &offset);
- if (io->in_tasklet) {
+ if (static_branch_unlikely(&use_tasklet_enabled) && io->in_tasklet) {
data = dm_bufio_get(v->bufio, hash_block, &buf);
if (data == NULL) {
/*
@@ -321,7 +324,8 @@ static int verity_verify_level(struct dm
if (likely(memcmp(verity_io_real_digest(v, io), want_digest,
v->digest_size) == 0))
aux->hash_verified = 1;
- else if (io->in_tasklet) {
+ else if (static_branch_unlikely(&use_tasklet_enabled) &&
+ io->in_tasklet) {
/*
* Error handling code (FEC included) cannot be run in a
* tasklet since it may sleep, so fallback to work-queue.
@@ -554,7 +558,8 @@ static int verity_verify_io(struct dm_ve
if (v->validated_blocks)
set_bit(cur_block, v->validated_blocks);
continue;
- } else if (io->in_tasklet) {
+ } else if (static_branch_unlikely(&use_tasklet_enabled) &&
+ io->in_tasklet) {
/*
* Error handling code (FEC included) cannot be run in a
* tasklet since it may sleep, so fallback to work-queue.
@@ -599,7 +604,7 @@ static void verity_finish_io(struct dm_v
bio->bi_end_io = io->orig_bi_end_io;
bio->bi_status = status;
- if (!io->in_tasklet)
+ if (!static_branch_unlikely(&use_tasklet_enabled) || !io->in_tasklet)
verity_fec_finish_io(io);
bio_endio(bio);
@@ -642,7 +647,7 @@ static void verity_end_io(struct bio *bi
return;
}
- if (io->v->use_tasklet) {
+ if (static_branch_unlikely(&use_tasklet_enabled) && io->v->use_tasklet) {
tasklet_init(&io->tasklet, verity_tasklet, (unsigned long)io);
tasklet_schedule(&io->tasklet);
} else {
@@ -950,6 +955,9 @@ static void verity_dtr(struct dm_target
kfree(v->signature_key_desc);
+ if (v->use_tasklet)
+ static_branch_dec(&use_tasklet_enabled);
+
kfree(v);
}
@@ -1081,6 +1089,7 @@ static int verity_parse_opt_args(struct
} else if (!strcasecmp(arg_name, DM_VERITY_OPT_TASKLET_VERIFY)) {
v->use_tasklet = true;
+ static_branch_inc(&use_tasklet_enabled);
continue;
} else if (verity_is_fec_opt_arg(arg_name)) {