lkml.org 
[lkml]   [2022]   [Aug]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.15 19/46] zram: do not lookup algorithm in backends table
    Date
    From: Sergey Senozhatsky <senozhatsky@chromium.org>

    [ Upstream commit dc89997264de565999a1cb55db3f295d3a8e457b ]

    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

    [senozhatsky@chromium.org: add comment]
    Link: https://lkml.kernel.org/r/20220624060606.1014474-1-senozhatsky@chromium.org
    Link: https://lkml.kernel.org/r/20220622023501.517125-1-senozhatsky@chromium.org
    Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
    Cc: Minchan Kim <minchan@kernel.org>
    Cc: Nitin Gupta <ngupta@vflare.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/block/zram/zcomp.c | 11 +++++------
    1 file changed, 5 insertions(+), 6 deletions(-)

    diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
    index 052aa3f65514..0916de952e09 100644
    --- a/drivers/block/zram/zcomp.c
    +++ b/drivers/block/zram/zcomp.c
    @@ -63,12 +63,6 @@ static int zcomp_strm_init(struct zcomp_strm *zstrm, struct zcomp *comp)

    bool zcomp_available_algorithm(const char *comp)
    {
    - int i;
    -
    - i = sysfs_match_string(backends, comp);
    - if (i >= 0)
    - return true;
    -
    /*
    * Crypto does not ignore a trailing new line symbol,
    * so make sure you don't supply a string containing
    @@ -217,6 +211,11 @@ struct zcomp *zcomp_create(const char *compress)
    struct zcomp *comp;
    int error;

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

    --
    2.35.1
    \
     
     \ /
      Last update: 2022-08-14 17:44    [W:4.133 / U:0.236 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site