1919#include <linux/module.h>
2020#include <linux/reboot.h>
2121#include <linux/scatterlist.h>
22+ #include <linux/jump_label.h>
2223
2324#define DM_MSG_PREFIX "verity"
2425
@@ -43,6 +44,8 @@ static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE;
4344
4445module_param_named (prefetch_cluster , dm_verity_prefetch_cluster , uint , S_IRUGO | S_IWUSR );
4546
47+ static DEFINE_STATIC_KEY_FALSE (use_tasklet_enabled );
48+
4649struct dm_verity_prefetch_work {
4750 struct work_struct work ;
4851 struct dm_verity * v ;
@@ -287,7 +290,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
287290
288291 verity_hash_at_level (v , block , level , & hash_block , & offset );
289292
290- if (io -> in_tasklet ) {
293+ if (static_branch_unlikely ( & use_tasklet_enabled ) && io -> in_tasklet ) {
291294 data = dm_bufio_get (v -> bufio , hash_block , & buf );
292295 if (data == NULL ) {
293296 /*
@@ -320,7 +323,8 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
320323 if (likely (memcmp (verity_io_real_digest (v , io ), want_digest ,
321324 v -> digest_size ) == 0 ))
322325 aux -> hash_verified = 1 ;
323- else if (io -> in_tasklet ) {
326+ else if (static_branch_unlikely (& use_tasklet_enabled ) &&
327+ io -> in_tasklet ) {
324328 /*
325329 * Error handling code (FEC included) cannot be run in a
326330 * tasklet since it may sleep, so fallback to work-queue.
@@ -553,7 +557,8 @@ static int verity_verify_io(struct dm_verity_io *io)
553557 if (v -> validated_blocks )
554558 set_bit (cur_block , v -> validated_blocks );
555559 continue ;
556- } else if (io -> in_tasklet ) {
560+ } else if (static_branch_unlikely (& use_tasklet_enabled ) &&
561+ io -> in_tasklet ) {
557562 /*
558563 * Error handling code (FEC included) cannot be run in a
559564 * tasklet since it may sleep, so fallback to work-queue.
@@ -598,7 +603,7 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status)
598603 bio -> bi_end_io = io -> orig_bi_end_io ;
599604 bio -> bi_status = status ;
600605
601- if (!io -> in_tasklet )
606+ if (!static_branch_unlikely ( & use_tasklet_enabled ) || ! io -> in_tasklet )
602607 verity_fec_finish_io (io );
603608
604609 bio_endio (bio );
@@ -641,7 +646,7 @@ static void verity_end_io(struct bio *bio)
641646 return ;
642647 }
643648
644- if (io -> v -> use_tasklet ) {
649+ if (static_branch_unlikely ( & use_tasklet_enabled ) && io -> v -> use_tasklet ) {
645650 tasklet_init (& io -> tasklet , verity_tasklet , (unsigned long )io );
646651 tasklet_schedule (& io -> tasklet );
647652 } else {
@@ -949,6 +954,9 @@ static void verity_dtr(struct dm_target *ti)
949954
950955 kfree (v -> signature_key_desc );
951956
957+ if (v -> use_tasklet )
958+ static_branch_dec (& use_tasklet_enabled );
959+
952960 kfree (v );
953961}
954962
@@ -1080,6 +1088,7 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
10801088
10811089 } else if (!strcasecmp (arg_name , DM_VERITY_OPT_TASKLET_VERIFY )) {
10821090 v -> use_tasklet = true;
1091+ static_branch_inc (& use_tasklet_enabled );
10831092 continue ;
10841093
10851094 } else if (verity_is_fec_opt_arg (arg_name )) {
0 commit comments