This is useless and more importantly not allowed on the writeback path,
because crypto_alloc_skcipher() allocates memory with GFP_KERNEL, which
can recurse back into the filesystem:
kworker/9:3 D ffff92303f318180 0 20732 2 0x00000080
Workqueue: ceph-msgr ceph_con_workfn [libceph]
ffff923035dd4480 ffff923038f8a0c0 0000000000000001 000000009eb27318
ffff92269eb28000 ffff92269eb27338 ffff923036b145ac ffff923035dd4480
00000000ffffffff ffff923036b145b0 ffffffff951eb4e1 ffff923036b145a8
Call Trace:
[] ? schedule+0x31/0x80
[] ? schedule_preempt_disabled+0xa/0x10
[] ? __mutex_lock_slowpath+0xb4/0x130
[] ? mutex_lock+0x1b/0x30
[] ? xfs_reclaim_inodes_ag+0x233/0x2d0 [xfs]
[] ? move_active_pages_to_lru+0x125/0x270
[] ? radix_tree_gang_lookup_tag+0xc5/0x1c0
[] ? __list_lru_walk_one.isra.3+0x33/0x120
[] ? xfs_reclaim_inodes_nr+0x31/0x40 [xfs]
[] ? super_cache_scan+0x17e/0x190
[] ? shrink_slab.part.38+0x1e3/0x3d0
[] ? shrink_node+0x10a/0x320
[] ? do_try_to_free_pages+0xf4/0x350
[] ? try_to_free_pages+0xea/0x1b0
[] ? __alloc_pages_nodemask+0x61d/0xe60
[] ? cache_grow_begin+0x9d/0x560
[] ? fallback_alloc+0x148/0x1c0
[] ? __crypto_alloc_tfm+0x37/0x130
[] ? __kmalloc+0x1eb/0x580
[] ? crush_choose_firstn+0x3eb/0x470 [libceph]
[] ? __crypto_alloc_tfm+0x37/0x130
[] ? crypto_spawn_tfm+0x39/0x60
[] ? crypto_cbc_init_tfm+0x23/0x40 [cbc]
[] ? __crypto_alloc_tfm+0xcc/0x130
[] ? crypto_skcipher_init_tfm+0x113/0x180
[] ? crypto_create_tfm+0x43/0xb0
[] ? crypto_larval_lookup+0x150/0x150
[] ? crypto_alloc_tfm+0x72/0x120
[] ? ceph_aes_encrypt2+0x67/0x400 [libceph]
[] ? ceph_pg_to_up_acting_osds+0x84/0x5b0 [libceph]
[] ? release_sock+0x40/0x90
[] ? tcp_recvmsg+0x4b4/0xae0
[] ? ceph_encrypt2+0x54/0xc0 [libceph]
[] ? ceph_x_encrypt+0x5d/0x90 [libceph]
[] ? calcu_signature+0x5f/0x90 [libceph]
[] ? ceph_x_sign_message+0x35/0x50 [libceph]
[] ? prepare_write_message_footer+0x5c/0xa0 [libceph]
[] ? ceph_con_workfn+0x2258/0x2dd0 [libceph]
[] ? queue_con_delay+0x33/0xd0 [libceph]
[] ? __submit_request+0x20d/0x2f0 [libceph]
[] ? ceph_osdc_start_request+0x28/0x30 [libceph]
[] ? rbd_queue_workfn+0x2f3/0x350 [rbd]
[] ? process_one_work+0x160/0x410
[] ? worker_thread+0x4d/0x480
[] ? process_one_work+0x410/0x410
[] ? kthread+0xcd/0xf0
[] ? ret_from_fork+0x1f/0x40
[] ? kthread_create_on_node+0x190/0x190
Allocating the cipher along with the key fixes the issue - as long the
key doesn't change, a single cipher context can be used concurrently in
multiple requests.
We still can't take that GFP_KERNEL allocation though. Both
ceph_crypto_key_clone() and ceph_crypto_key_decode() are called from
GFP_NOFS context, so resort to memalloc_noio_{save,restore}() here.
Reported-by: Lucas Stach
Signed-off-by: Ilya Dryomov
Reviewed-by: Sage Weil