lkml.org 
[lkml]   [2020]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.9 029/255] powerpc/eeh_cache: Fix a possible debugfs deadlock
    Date
    From: Qian Cai <cai@redhat.com>

    [ Upstream commit fd552e0542b4532483289cce48fdbd27b692984b ]

    Lockdep complains that a possible deadlock below in
    eeh_addr_cache_show() because it is acquiring a lock with IRQ enabled,
    but eeh_addr_cache_insert_dev() needs to acquire the same lock with IRQ
    disabled. Let's just make eeh_addr_cache_show() acquire the lock with
    IRQ disabled as well.

    CPU0 CPU1
    ---- ----
    lock(&pci_io_addr_cache_root.piar_lock);
    local_irq_disable();
    lock(&tp->lock);
    lock(&pci_io_addr_cache_root.piar_lock);
    <Interrupt>
    lock(&tp->lock);

    *** DEADLOCK ***

    lock_acquire+0x140/0x5f0
    _raw_spin_lock_irqsave+0x64/0xb0
    eeh_addr_cache_insert_dev+0x48/0x390
    eeh_probe_device+0xb8/0x1a0
    pnv_pcibios_bus_add_device+0x3c/0x80
    pcibios_bus_add_device+0x118/0x290
    pci_bus_add_device+0x28/0xe0
    pci_bus_add_devices+0x54/0xb0
    pcibios_init+0xc4/0x124
    do_one_initcall+0xac/0x528
    kernel_init_freeable+0x35c/0x3fc
    kernel_init+0x24/0x148
    ret_from_kernel_thread+0x5c/0x80

    lock_acquire+0x140/0x5f0
    _raw_spin_lock+0x4c/0x70
    eeh_addr_cache_show+0x38/0x110
    seq_read+0x1a0/0x660
    vfs_read+0xc8/0x1f0
    ksys_read+0x74/0x130
    system_call_exception+0xf8/0x1d0
    system_call_common+0xe8/0x218

    Fixes: 5ca85ae6318d ("powerpc/eeh_cache: Add a way to dump the EEH address cache")
    Signed-off-by: Qian Cai <cai@redhat.com>
    Reviewed-by: Oliver O'Halloran <oohall@gmail.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20201028152717.8967-1-cai@redhat.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/powerpc/kernel/eeh_cache.c | 5 +++--
    1 file changed, 3 insertions(+), 2 deletions(-)

    diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c
    index 6b50bf15d8c19..bf3270426d82d 100644
    --- a/arch/powerpc/kernel/eeh_cache.c
    +++ b/arch/powerpc/kernel/eeh_cache.c
    @@ -264,8 +264,9 @@ static int eeh_addr_cache_show(struct seq_file *s, void *v)
    {
    struct pci_io_addr_range *piar;
    struct rb_node *n;
    + unsigned long flags;

    - spin_lock(&pci_io_addr_cache_root.piar_lock);
    + spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
    for (n = rb_first(&pci_io_addr_cache_root.rb_root); n; n = rb_next(n)) {
    piar = rb_entry(n, struct pci_io_addr_range, rb_node);

    @@ -273,7 +274,7 @@ static int eeh_addr_cache_show(struct seq_file *s, void *v)
    (piar->flags & IORESOURCE_IO) ? "i/o" : "mem",
    &piar->addr_lo, &piar->addr_hi, pci_name(piar->pcidev));
    }
    - spin_unlock(&pci_io_addr_cache_root.piar_lock);
    + spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);

    return 0;
    }
    --
    2.27.0


    \
     
     \ /
      Last update: 2020-11-17 14:52    [W:4.066 / U:0.368 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site