• Dave Jiang's avatar
    libnvdimm: fix clear poison locking with spinlock and GFP_NOWAIT allocation · b3b454f6
    Dave Jiang authored
    The following warning results from holding a lane spinlock,
    preempt_disable(), or the btt map spinlock and then trying to take the
    reconfig_mutex to walk the poison list and potentially add new entries.
    
    BUG: sleeping function called from invalid context at kernel/locking/mutex.
    c:747
    in_atomic(): 1, irqs_disabled(): 0, pid: 17159, name: dd
    [..]
    Call Trace:
    dump_stack+0x85/0xc8
    ___might_sleep+0x184/0x250
    __might_sleep+0x4a/0x90
    __mutex_lock+0x58/0x9b0
    ? nvdimm_bus_lock+0x21/0x30 [libnvdimm]
    ? __nvdimm_bus_badblocks_clear+0x2f/0x60 [libnvdimm]
    ? acpi_nfit_forget_poison+0x79/0x80 [nfit]
    ? _raw_spin_unlock+0x27/0x40
    mutex_lock_nested+0x1b/0x20
    nvdimm_bus_lock+0x21/0x30 [libnvdimm]
    nvdimm_forget_poison+0x25/0x50 [libnvdimm]
    nvdimm_clear_poison+0x106/0x140 [libnvdimm]
    nsio_rw_bytes+0x164/0x270 [libnvdimm]
    btt_write_pg+0x1de/0x3e0 [nd_btt]
    ? blk_queue_enter+0x30/0x290
    btt_make_request+0x11a/0x310 [nd_btt]
    ? blk_queue_enter+0xb7/0x290
    ? blk_queue_enter+0x30/0x290
    generic_make_request+0x118/0x3b0
    
    A spinlock is introduced to protect the poison list. This allows us to not
    having to acquire the reconfig_mutex for touching the poison list. The
    add_poison() function has been broken out into two helper functions. One to
    allocate the poison entry and the other to apppend the entry. This allows us
    to unlock the poison_lock in non-I/O path and continue to be able to allocate
    the poison entry with GFP_KERNEL. We will use GFP_NOWAIT in the I/O path in
    order to satisfy being in atomic context.
    Reviewed-by: default avatarVishal Verma <vishal.l.verma@intel.com>
    Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
    Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
    b3b454f6
nd-core.h 4.55 KB