@@ -46,7 +46,7 @@ static unsigned int dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE
46
46
47
47
module_param_named (prefetch_cluster , dm_verity_prefetch_cluster , uint , 0644 );
48
48
49
- static DEFINE_STATIC_KEY_FALSE (use_tasklet_enabled );
49
+ static DEFINE_STATIC_KEY_FALSE (use_bh_wq_enabled );
50
50
51
51
struct dm_verity_prefetch_work {
52
52
struct work_struct work ;
@@ -299,7 +299,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
299
299
300
300
verity_hash_at_level (v , block , level , & hash_block , & offset );
301
301
302
- if (static_branch_unlikely (& use_tasklet_enabled ) && io -> in_tasklet ) {
302
+ if (static_branch_unlikely (& use_bh_wq_enabled ) && io -> in_bh ) {
303
303
data = dm_bufio_get (v -> bufio , hash_block , & buf );
304
304
if (data == NULL ) {
305
305
/*
@@ -327,15 +327,14 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
327
327
328
328
r = verity_hash (v , verity_io_hash_req (v , io ),
329
329
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 );
331
331
if (unlikely (r < 0 ))
332
332
goto release_ret_r ;
333
333
334
334
if (likely (memcmp (verity_io_real_digest (v , io ), want_digest ,
335
335
v -> digest_size ) == 0 ))
336
336
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 ) {
339
338
/*
340
339
* Error handling code (FEC included) cannot be run in a
341
340
* tasklet since it may sleep, so fallback to work-queue.
@@ -576,7 +575,7 @@ static int verity_verify_io(struct dm_verity_io *io)
576
575
struct bio * bio = dm_bio_from_per_bio_data (io , v -> ti -> per_io_data_size );
577
576
unsigned int b ;
578
577
579
- if (static_branch_unlikely (& use_tasklet_enabled ) && io -> in_tasklet ) {
578
+ if (static_branch_unlikely (& use_bh_wq_enabled ) && io -> in_bh ) {
580
579
/*
581
580
* Copy the iterator in case we need to restart
582
581
* verification in a work-queue.
@@ -616,7 +615,7 @@ static int verity_verify_io(struct dm_verity_io *io)
616
615
continue ;
617
616
}
618
617
619
- r = verity_hash_init (v , req , & wait , !io -> in_tasklet );
618
+ r = verity_hash_init (v , req , & wait , !io -> in_bh );
620
619
if (unlikely (r < 0 ))
621
620
return r ;
622
621
@@ -635,8 +634,7 @@ static int verity_verify_io(struct dm_verity_io *io)
635
634
if (v -> validated_blocks )
636
635
set_bit (cur_block , v -> validated_blocks );
637
636
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 ) {
640
638
/*
641
639
* Error handling code (FEC included) cannot be run in a
642
640
* 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)
690
688
bio -> bi_end_io = io -> orig_bi_end_io ;
691
689
bio -> bi_status = status ;
692
690
693
- if (!static_branch_unlikely (& use_tasklet_enabled ) || !io -> in_tasklet )
691
+ if (!static_branch_unlikely (& use_bh_wq_enabled ) || !io -> in_bh )
694
692
verity_fec_finish_io (io );
695
693
696
694
bio_endio (bio );
@@ -700,11 +698,28 @@ static void verity_work(struct work_struct *w)
700
698
{
701
699
struct dm_verity_io * io = container_of (w , struct dm_verity_io , work );
702
700
703
- io -> in_tasklet = false;
701
+ io -> in_bh = false;
704
702
705
703
verity_finish_io (io , errno_to_blk_status (verity_verify_io (io )));
706
704
}
707
705
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
+
708
723
static void verity_end_io (struct bio * bio )
709
724
{
710
725
struct dm_verity_io * io = bio -> bi_private ;
@@ -717,8 +732,13 @@ static void verity_end_io(struct bio *bio)
717
732
return ;
718
733
}
719
734
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
+ }
722
742
}
723
743
724
744
/*
@@ -885,7 +905,7 @@ static void verity_status(struct dm_target *ti, status_type_t type,
885
905
args ++ ;
886
906
if (v -> validated_blocks )
887
907
args ++ ;
888
- if (v -> use_tasklet )
908
+ if (v -> use_bh_wq )
889
909
args ++ ;
890
910
if (v -> signature_key_desc )
891
911
args += DM_VERITY_ROOT_HASH_VERIFICATION_OPTS ;
@@ -912,7 +932,7 @@ static void verity_status(struct dm_target *ti, status_type_t type,
912
932
DMEMIT (" " DM_VERITY_OPT_IGN_ZEROES );
913
933
if (v -> validated_blocks )
914
934
DMEMIT (" " DM_VERITY_OPT_AT_MOST_ONCE );
915
- if (v -> use_tasklet )
935
+ if (v -> use_bh_wq )
916
936
DMEMIT (" " DM_VERITY_OPT_TASKLET_VERIFY );
917
937
sz = verity_fec_status_table (v , sz , result , maxlen );
918
938
if (v -> signature_key_desc )
@@ -1031,8 +1051,8 @@ static void verity_dtr(struct dm_target *ti)
1031
1051
1032
1052
kfree (v -> signature_key_desc );
1033
1053
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 );
1036
1056
1037
1057
kfree (v );
1038
1058
@@ -1166,8 +1186,8 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
1166
1186
continue ;
1167
1187
1168
1188
} 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 );
1171
1191
continue ;
1172
1192
1173
1193
} 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)
1338
1358
}
1339
1359
1340
1360
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 );
1342
1362
if (IS_ERR (v -> tfm )) {
1343
1363
ti -> error = "Cannot initialize hash function" ;
1344
1364
r = PTR_ERR (v -> tfm );
@@ -1463,7 +1483,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1463
1483
v -> bufio = dm_bufio_client_create (v -> hash_dev -> bdev ,
1464
1484
1 << v -> hash_dev_block_bits , 1 , sizeof (struct buffer_aux ),
1465
1485
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 );
1467
1487
if (IS_ERR (v -> bufio )) {
1468
1488
ti -> error = "Cannot initialize dm-bufio" ;
1469
1489
r = PTR_ERR (v -> bufio );
@@ -1482,7 +1502,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1482
1502
* reducing wait times when reading from a dm-verity device.
1483
1503
*
1484
1504
* 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
1486
1506
* will fall-back to using it for error handling (or if the bufio cache
1487
1507
* doesn't have required hashes).
1488
1508
*/
0 commit comments