Skip to content
  • John Stultz's avatar
    cpuset: Fix potential deadlock w/ set_mems_allowed · db751fe3
    John Stultz authored
    
    
    After adding lockdep support to seqlock/seqcount structures,
    I started seeing the following warning:
    
    [    1.070907] ======================================================
    [    1.072015] [ INFO: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected ]
    [    1.073181] 3.11.0+ #67 Not tainted
    [    1.073801] ------------------------------------------------------
    [    1.074882] kworker/u4:2/708 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
    [    1.076088]  (&p->mems_allowed_seq){+.+...}, at: [<ffffffff81187d7f>] new_slab+0x5f/0x280
    [    1.077572]
    [    1.077572] and this task is already holding:
    [    1.078593]  (&(&q->__queue_lock)->rlock){..-...}, at: [<ffffffff81339f03>] blk_execute_rq_nowait+0x53/0xf0
    [    1.080042] which would create a new lock dependency:
    [    1.080042]  (&(&q->__queue_lock)->rlock){..-...} -> (&p->mems_allowed_seq){+.+...}
    [    1.080042]
    [    1.080042] but this new dependency connects a SOFTIRQ-irq-safe lock:
    [    1.080042]  (&(&q->__queue_lock)->rlock){..-...}
    [    1.080042] ... which became SOFTIRQ-irq-safe at:
    [    1.080042]   [<ffffffff810ec179>] __lock_acquire+0x5b9/0x1db0
    [    1.080042]   [<ffffffff810edfe5>] lock_acquire+0x95/0x130
    [    1.080042]   [<ffffffff818968a1>] _raw_spin_lock+0x41/0x80
    [    1.080042]   [<ffffffff81560c9e>] scsi_device_unbusy+0x7e/0xd0
    [    1.080042]   [<ffffffff8155a612>] scsi_finish_command+0x32/0xf0
    [    1.080042]   [<ffffffff81560e91>] scsi_softirq_done+0xa1/0x130
    [    1.080042]   [<ffffffff8133b0f3>] blk_done_softirq+0x73/0x90
    [    1.080042]   [<ffffffff81095dc0>] __do_softirq+0x110/0x2f0
    [    1.080042]   [<ffffffff81095fcd>] run_ksoftirqd+0x2d/0x60
    [    1.080042]   [<ffffffff810bc506>] smpboot_thread_fn+0x156/0x1e0
    [    1.080042]   [<ffffffff810b3916>] kthread+0xd6/0xe0
    [    1.080042]   [<ffffffff818980ac>] ret_from_fork+0x7c/0xb0
    [    1.080042]
    [    1.080042] to a SOFTIRQ-irq-unsafe lock:
    [    1.080042]  (&p->mems_allowed_seq){+.+...}
    [    1.080042] ... which became SOFTIRQ-irq-unsafe at:
    [    1.080042] ...  [<ffffffff810ec1d3>] __lock_acquire+0x613/0x1db0
    [    1.080042]   [<ffffffff810edfe5>] lock_acquire+0x95/0x130
    [    1.080042]   [<ffffffff810b3df2>] kthreadd+0x82/0x180
    [    1.080042]   [<ffffffff818980ac>] ret_from_fork+0x7c/0xb0
    [    1.080042]
    [    1.080042] other info that might help us debug this:
    [    1.080042]
    [    1.080042]  Possible interrupt unsafe locking scenario:
    [    1.080042]
    [    1.080042]        CPU0                    CPU1
    [    1.080042]        ----                    ----
    [    1.080042]   lock(&p->mems_allowed_seq);
    [    1.080042]                                local_irq_disable();
    [    1.080042]                                lock(&(&q->__queue_lock)->rlock);
    [    1.080042]                                lock(&p->mems_allowed_seq);
    [    1.080042]   <Interrupt>
    [    1.080042]     lock(&(&q->__queue_lock)->rlock);
    [    1.080042]
    [    1.080042]  *** DEADLOCK ***
    
    The issue stems from the kthreadd() function calling set_mems_allowed
    with irqs enabled. While its possibly unlikely for the actual deadlock
    to trigger, a fix is fairly simple: disable irqs before taking the
    mems_allowed_seq lock.
    
    Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
    Signed-off-by: default avatarPeter Zijlstra <peterz@infradead.org>
    Acked-by: default avatarLi Zefan <lizefan@huawei.com>
    Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: "David S. Miller" <davem@davemloft.net>
    Cc: netdev@vger.kernel.org
    Link: http://lkml.kernel.org/r/1381186321-4906-4-git-send-email-john.stultz@linaro.org
    
    
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    db751fe3