@@ -46,7 +46,7 @@ static unsigned int dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE
4646
4747module_param_named (prefetch_cluster , dm_verity_prefetch_cluster , uint , 0644 );
4848
49- static DEFINE_STATIC_KEY_FALSE (use_tasklet_enabled );
49+ static DEFINE_STATIC_KEY_FALSE (use_bh_wq_enabled );
5050
5151struct dm_verity_prefetch_work {
5252 struct work_struct work ;
@@ -299,7 +299,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
299299
300300 verity_hash_at_level (v , block , level , & hash_block , & offset );
301301
302- if (static_branch_unlikely (& use_tasklet_enabled ) && io -> in_tasklet ) {
302+ if (static_branch_unlikely (& use_bh_wq_enabled ) && io -> in_bh ) {
303303 data = dm_bufio_get (v -> bufio , hash_block , & buf );
304304 if (data == NULL ) {
305305 /*
@@ -327,15 +327,14 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
327327
328328 r = verity_hash (v , verity_io_hash_req (v , io ),
329329 data , 1 << v -> hash_dev_block_bits ,
330- verity_io_real_digest (v , io ), !io -> in_tasklet );
330+ verity_io_real_digest (v , io ), !io -> in_bh );
331331 if (unlikely (r < 0 ))
332332 goto release_ret_r ;
333333
334334 if (likely (memcmp (verity_io_real_digest (v , io ), want_digest ,
335335 v -> digest_size ) == 0 ))
336336 aux -> hash_verified = 1 ;
337- else if (static_branch_unlikely (& use_tasklet_enabled ) &&
338- io -> in_tasklet ) {
337+ else if (static_branch_unlikely (& use_bh_wq_enabled ) && io -> in_bh ) {
339338 /*
340339 * Error handling code (FEC included) cannot be run in a
341340 * tasklet since it may sleep, so fallback to work-queue.
@@ -576,7 +575,7 @@ static int verity_verify_io(struct dm_verity_io *io)
576575 struct bio * bio = dm_bio_from_per_bio_data (io , v -> ti -> per_io_data_size );
577576 unsigned int b ;
578577
579- if (static_branch_unlikely (& use_tasklet_enabled ) && io -> in_tasklet ) {
578+ if (static_branch_unlikely (& use_bh_wq_enabled ) && io -> in_bh ) {
580579 /*
581580 * Copy the iterator in case we need to restart
582581 * verification in a work-queue.
@@ -616,7 +615,7 @@ static int verity_verify_io(struct dm_verity_io *io)
616615 continue ;
617616 }
618617
619- r = verity_hash_init (v , req , & wait , !io -> in_tasklet );
618+ r = verity_hash_init (v , req , & wait , !io -> in_bh );
620619 if (unlikely (r < 0 ))
621620 return r ;
622621
@@ -635,8 +634,7 @@ static int verity_verify_io(struct dm_verity_io *io)
635634 if (v -> validated_blocks )
636635 set_bit (cur_block , v -> validated_blocks );
637636 continue ;
638- } else if (static_branch_unlikely (& use_tasklet_enabled ) &&
639- io -> in_tasklet ) {
637+ } else if (static_branch_unlikely (& use_bh_wq_enabled ) && io -> in_bh ) {
640638 /*
641639 * Error handling code (FEC included) cannot be run in a
642640 * tasklet since it may sleep, so fallback to work-queue.
@@ -690,7 +688,7 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status)
690688 bio -> bi_end_io = io -> orig_bi_end_io ;
691689 bio -> bi_status = status ;
692690
693- if (!static_branch_unlikely (& use_tasklet_enabled ) || !io -> in_tasklet )
691+ if (!static_branch_unlikely (& use_bh_wq_enabled ) || !io -> in_bh )
694692 verity_fec_finish_io (io );
695693
696694 bio_endio (bio );
@@ -700,11 +698,28 @@ static void verity_work(struct work_struct *w)
700698{
701699 struct dm_verity_io * io = container_of (w , struct dm_verity_io , work );
702700
703- io -> in_tasklet = false;
701+ io -> in_bh = false;
704702
705703 verity_finish_io (io , errno_to_blk_status (verity_verify_io (io )));
706704}
707705
706+ static void verity_bh_work (struct work_struct * w )
707+ {
708+ struct dm_verity_io * io = container_of (w , struct dm_verity_io , bh_work );
709+ int err ;
710+
711+ io -> in_bh = true;
712+ err = verity_verify_io (io );
713+ if (err == - EAGAIN || err == - ENOMEM ) {
714+ /* fallback to retrying with work-queue */
715+ INIT_WORK (& io -> work , verity_work );
716+ queue_work (io -> v -> verify_wq , & io -> work );
717+ return ;
718+ }
719+
720+ verity_finish_io (io , errno_to_blk_status (err ));
721+ }
722+
708723static void verity_end_io (struct bio * bio )
709724{
710725 struct dm_verity_io * io = bio -> bi_private ;
@@ -717,8 +732,13 @@ static void verity_end_io(struct bio *bio)
717732 return ;
718733 }
719734
720- INIT_WORK (& io -> work , verity_work );
721- queue_work (io -> v -> verify_wq , & io -> work );
735+ if (static_branch_unlikely (& use_bh_wq_enabled ) && io -> v -> use_bh_wq ) {
736+ INIT_WORK (& io -> bh_work , verity_bh_work );
737+ queue_work (system_bh_wq , & io -> bh_work );
738+ } else {
739+ INIT_WORK (& io -> work , verity_work );
740+ queue_work (io -> v -> verify_wq , & io -> work );
741+ }
722742}
723743
724744/*
@@ -885,7 +905,7 @@ static void verity_status(struct dm_target *ti, status_type_t type,
885905 args ++ ;
886906 if (v -> validated_blocks )
887907 args ++ ;
888- if (v -> use_tasklet )
908+ if (v -> use_bh_wq )
889909 args ++ ;
890910 if (v -> signature_key_desc )
891911 args += DM_VERITY_ROOT_HASH_VERIFICATION_OPTS ;
@@ -912,7 +932,7 @@ static void verity_status(struct dm_target *ti, status_type_t type,
912932 DMEMIT (" " DM_VERITY_OPT_IGN_ZEROES );
913933 if (v -> validated_blocks )
914934 DMEMIT (" " DM_VERITY_OPT_AT_MOST_ONCE );
915- if (v -> use_tasklet )
935+ if (v -> use_bh_wq )
916936 DMEMIT (" " DM_VERITY_OPT_TASKLET_VERIFY );
917937 sz = verity_fec_status_table (v , sz , result , maxlen );
918938 if (v -> signature_key_desc )
@@ -1031,8 +1051,8 @@ static void verity_dtr(struct dm_target *ti)
10311051
10321052 kfree (v -> signature_key_desc );
10331053
1034- if (v -> use_tasklet )
1035- static_branch_dec (& use_tasklet_enabled );
1054+ if (v -> use_bh_wq )
1055+ static_branch_dec (& use_bh_wq_enabled );
10361056
10371057 kfree (v );
10381058
@@ -1166,8 +1186,8 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
11661186 continue ;
11671187
11681188 } else if (!strcasecmp (arg_name , DM_VERITY_OPT_TASKLET_VERIFY )) {
1169- v -> use_tasklet = true;
1170- static_branch_inc (& use_tasklet_enabled );
1189+ v -> use_bh_wq = true;
1190+ static_branch_inc (& use_bh_wq_enabled );
11711191 continue ;
11721192
11731193 } else if (verity_is_fec_opt_arg (arg_name )) {
@@ -1338,7 +1358,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
13381358 }
13391359
13401360 v -> tfm = crypto_alloc_ahash (v -> alg_name , 0 ,
1341- v -> use_tasklet ? CRYPTO_ALG_ASYNC : 0 );
1361+ v -> use_bh_wq ? CRYPTO_ALG_ASYNC : 0 );
13421362 if (IS_ERR (v -> tfm )) {
13431363 ti -> error = "Cannot initialize hash function" ;
13441364 r = PTR_ERR (v -> tfm );
@@ -1463,7 +1483,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
14631483 v -> bufio = dm_bufio_client_create (v -> hash_dev -> bdev ,
14641484 1 << v -> hash_dev_block_bits , 1 , sizeof (struct buffer_aux ),
14651485 dm_bufio_alloc_callback , NULL ,
1466- v -> use_tasklet ? DM_BUFIO_CLIENT_NO_SLEEP : 0 );
1486+ v -> use_bh_wq ? DM_BUFIO_CLIENT_NO_SLEEP : 0 );
14671487 if (IS_ERR (v -> bufio )) {
14681488 ti -> error = "Cannot initialize dm-bufio" ;
14691489 r = PTR_ERR (v -> bufio );
@@ -1482,7 +1502,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
14821502 * reducing wait times when reading from a dm-verity device.
14831503 *
14841504 * Also as required for the "try_verify_in_tasklet" feature: WQ_HIGHPRI
1485- * allows verify_wq to preempt softirq since verification in tasklet
1505+ * allows verify_wq to preempt softirq since verification in BH workqueue
14861506 * will fall-back to using it for error handling (or if the bufio cache
14871507 * doesn't have required hashes).
14881508 */
0 commit comments