• Sebastian Andrzej Siewior's avatar
    mm: dmapool: add/remove sysfs file outside of the pool lock lock · 01c2965f
    Sebastian Andrzej Siewior authored
    cat /sys/.../pools followed by removal the device leads to:
    |[ INFO: possible circular locking dependency detected ]
    |3.17.0-rc4+ #1498 Not tainted
    |rmmod/2505 is trying to acquire lock:
    | (s_active#28){++++.+}, at: [<c017f754>] kernfs_remove_by_name_ns+0x3c/0x88
    |but task is already holding lock:
    | (pools_lock){+.+.+.}, at: [<c011494c>] dma_pool_destroy+0x18/0x17c
    |which lock already depends on the new lock.
    |the existing dependency chain (in reverse order) is:
    |-> #1 (pools_lock){+.+.+.}:
    |   [<c0114ae8>] show_pools+0x30/0xf8
    |   [<c0313210>] dev_attr_show+0x1c/0x48
    |   [<c0180e84>] sysfs_kf_seq_show+0x88/0x10c
    |   [<c017f960>] kernfs_seq_show+0x24/0x28
    |   [<c013efc4>] seq_read+0x1b8/0x480
    |   [<c011e820>] vfs_read+0x8c/0x148
    |   [<c011ea10>] SyS_read+0x40/0x8c
    |   [<c000e960>] ret_fast_syscall+0x0/0x48
    |-> #0 (s_active#28){++++.+}:
    |   [<c017e9ac>] __kernfs_remove+0x258/0x2ec
    |   [<c017f754>] kernfs_remove_by_name_ns+0x3c/0x88
    |   [<c0114a7c>] dma_pool_destroy+0x148/0x17c
    |   [<c03ad288>] hcd_buffer_destroy+0x20/0x34
    |   [<c03a4780>] usb_remove_hcd+0x110/0x1a4
    The problem is the lock order of pools_lock and kernfs_mutex in
    dma_pool_destroy() vs show_pools() call path.
    This patch breaks out the creation of the sysfs file outside of the
    pools_lock mutex.  The newly added pools_reg_lock ensures that there is no
    race of create vs destroy code path in terms whether or not the sysfs file
    has to be deleted (and was it deleted before we try to create a new one)
    and what to do if device_create_file() failed.
    Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>