• Dan Streetman's avatar
    mm/zswap: use workqueue to destroy pool · 200867af
    Dan Streetman authored
    Add a work_struct to struct zswap_pool, and change __zswap_pool_empty to
    use the workqueue instead of using call_rcu().
    
    When zswap destroys a pool no longer in use, it uses call_rcu() to
    perform the destruction/freeing.  Since that executes in softirq
    context, it must not sleep.  However, actually destroying the pool
    involves freeing the per-cpu compressors (which requires locking the
    cpu_add_remove_lock mutex) and freeing the zpool, for which the
    implementation may sleep (e.g.  zsmalloc calls kmem_cache_destroy, which
    locks the slab_mutex).  So if either mutex is currently taken, or any
    other part of the compressor or zpool implementation sleeps, it will
    result in a BUG().
    
    It's not easy to reproduce this when changing zswap's params normally.
    In testing with a loaded system, this does not fail:
    
      $ cd /sys/module/zswap/parameters
      $ echo lz4 > compressor ; echo zsmalloc > zpool
    
    nor does this:
    
      $ while true ; do
      > echo lzo > compressor ; echo zbud > zpool
      > sleep 1
      > echo lz4 > compressor ; echo zsmalloc > zpool
      > sleep 1
      > done
    
    although it's still possible either of those might fail, depending on
    whether anything else besides zswap has locked the mutexes.
    
    However, changing a parameter with no delay immediately causes the
    schedule while atomic BUG:
    
      $ while true ; do
      > echo lzo > compressor ; echo lz4 > compressor
      > done
    
    This is essentially the same as Yu Zhao's proposed patch to zsmalloc,
    but moved to zswap, to cover compressor and zpool freeing.
    
    Fixes: f1c54846 ("zswap: dynamic pool creation")
    Signed-off-by: default avatarDan Streetman <ddstreet@ieee.org>
    Reported-by: default avatarYu Zhao <yuzhao@google.com>
    Reviewed-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
    Cc: Minchan Kim <minchan@kernel.org>
    Cc: Dan Streetman <dan.streetman@canonical.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    200867af
zswap.c 32.3 KB