• Ignat Korchagin's avatar
    dm crypt: use GFP_ATOMIC when allocating crypto requests from softirq · d68b2958
    Ignat Korchagin authored
    Commit 39d42fa9 ("dm crypt: add flags to optionally bypass kcryptd
    workqueues") made it possible for some code paths in dm-crypt to be
    executed in softirq context, when the underlying driver processes IO
    requests in interrupt/softirq context.
    
    In this case sometimes when allocating a new crypto request we may get
    a stacktrace like below:
    
    [  210.103008][    C0] BUG: sleeping function called from invalid context at mm/mempool.c:381
    [  210.104746][    C0] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 2602, name: fio
    [  210.106599][    C0] CPU: 0 PID: 2602 Comm: fio Tainted: G        W         5.10.0+ #50
    [  210.108331][    C0] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
    [  210.110212][    C0] Call Trace:
    [  210.110921][    C0]  <IRQ>
    [  210.111527][    C0]  dump_stack+0x7d/0xa3
    [  210.112411][    C0]  ___might_sleep.cold+0x122/0x151
    [  210.113527][    C0]  mempool_alloc+0x16b/0x2f0
    [  210.114524][    C0]  ? __queue_work+0x515/0xde0
    [  210.115553][    C0]  ? mempool_resize+0x700/0x700
    [  210.116586][    C0]  ? crypt_endio+0x91/0x180
    [  210.117479][    C0]  ? blk_update_request+0x757/0x1150
    [  210.118513][    C0]  ? blk_mq_end_request+0x4b/0x480
    [  210.119572][    C0]  ? blk_done_softirq+0x21d/0x340
    [  210.120628][    C0]  ? __do_softirq+0x190/0x611
    [  210.121626][    C0]  crypt_convert+0x29f9/0x4c00
    [  210.122668][    C0]  ? _raw_spin_lock_irqsave+0x87/0xe0
    [  210.123824][    C0]  ? kasan_set_track+0x1c/0x30
    [  210.124858][    C0]  ? crypt_iv_tcw_ctr+0x4a0/0x4a0
    [  210.125930][    C0]  ? kmem_cache_free+0x104/0x470
    [  210.126973][    C0]  ? crypt_endio+0x91/0x180
    [  210.127947][    C0]  kcryptd_crypt_read_convert+0x30e/0x420
    [  210.129165][    C0]  blk_update_request+0x757/0x1150
    [  210.130231][    C0]  blk_mq_end_request+0x4b/0x480
    [  210.131294][    C0]  blk_done_softirq+0x21d/0x340
    [  210.132332][    C0]  ? _raw_spin_lock+0x81/0xd0
    [  210.133289][    C0]  ? blk_mq_stop_hw_queue+0x30/0x30
    [  210.134399][    C0]  ? _raw_read_lock_irq+0x40/0x40
    [  210.135458][    C0]  __do_softirq+0x190/0x611
    [  210.136409][    C0]  ? handle_edge_irq+0x221/0xb60
    [  210.137447][    C0]  asm_call_irq_on_stack+0x12/0x20
    [  210.138507][    C0]  </IRQ>
    [  210.139118][    C0]  do_softirq_own_stack+0x37/0x40
    [  210.140191][    C0]  irq_exit_rcu+0x110/0x1b0
    [  210.141151][    C0]  common_interrupt+0x74/0x120
    [  210.142171][    C0]  asm_common_interrupt+0x1e/0x40
    
    Fix this by allocating crypto requests with GFP_ATOMIC mask in
    interrupt context.
    
    Fixes: 39d42fa9 ("dm crypt: add flags to optionally bypass kcryptd workqueues")
    Cc: stable@vger.kernel.org # v5.9+
    Reported-by: default avatarMaciej S. Szmigiero <mail@maciej.szmigiero.name>
    Signed-off-by: default avatarIgnat Korchagin <ignat@cloudflare.com>
    Acked-by: default avatarMikulas Patocka <mpatocka@redhat.com>
    Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
    d68b2958
dm-crypt.c 91.3 KB