Skip to content

Commit dc89997

Browse files
sergey-senozhatskyakpm00
authored andcommitted
zram: do not lookup algorithm in backends table
Always use crypto_has_comp() so that crypto can lookup module, call usermodhelper to load the modules, wait for usermodhelper to finish and so on. Otherwise crypto will do all of these steps under CPU hot-plug lock and this looks like too much stuff to handle under the CPU hot-plug lock. Besides this can end up in a deadlock when usermodhelper triggers a code path that attempts to lock the CPU hot-plug lock, that zram already holds. An example of such deadlock: - path A. zram grabs CPU hot-plug lock, execs /sbin/modprobe from crypto and waits for modprobe to finish disksize_store zcomp_create __cpuhp_state_add_instance __cpuhp_state_add_instance_cpuslocked zcomp_cpu_up_prepare crypto_alloc_base crypto_alg_mod_lookup call_usermodehelper_exec wait_for_completion_killable do_wait_for_common schedule - path B. async work kthread that brings in scsi device. It wants to register CPUHP states at some point, and it needs the CPU hot-plug lock for that, which is owned by zram. async_run_entry_fn scsi_probe_and_add_lun scsi_mq_alloc_queue blk_mq_init_queue blk_mq_init_allocated_queue blk_mq_realloc_hw_ctxs __cpuhp_state_add_instance __cpuhp_state_add_instance_cpuslocked mutex_lock schedule - path C. modprobe sleeps, waiting for all aync works to finish. load_module do_init_module async_synchronize_full async_synchronize_cookie_domain schedule [[email protected]: add comment] Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Sergey Senozhatsky <[email protected]> Cc: Minchan Kim <[email protected]> Cc: Nitin Gupta <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent e8da368 commit dc89997

File tree

1 file changed

+5
-6
lines changed

1 file changed

+5
-6
lines changed

drivers/block/zram/zcomp.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,6 @@ static int zcomp_strm_init(struct zcomp_strm *zstrm, struct zcomp *comp)
6363

6464
bool zcomp_available_algorithm(const char *comp)
6565
{
66-
int i;
67-
68-
i = sysfs_match_string(backends, comp);
69-
if (i >= 0)
70-
return true;
71-
7266
/*
7367
* Crypto does not ignore a trailing new line symbol,
7468
* so make sure you don't supply a string containing
@@ -217,6 +211,11 @@ struct zcomp *zcomp_create(const char *compress)
217211
struct zcomp *comp;
218212
int error;
219213

214+
/*
215+
* Crypto API will execute /sbin/modprobe if the compression module
216+
* is not loaded yet. We must do it here, otherwise we are about to
217+
* call /sbin/modprobe under CPU hot-plug lock.
218+
*/
220219
if (!zcomp_available_algorithm(compress))
221220
return ERR_PTR(-EINVAL);
222221

0 commit comments

Comments
 (0)