powerpc/eeh_cache: Fix a possible debugfs deadlock
[ 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: 5ca85ae631
("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>
This commit is contained in:
parent
1c8fe343a7
commit
d261d0bd90
@ -272,8 +272,9 @@ static int eeh_addr_cache_show(struct seq_file *s, void *v)
|
|||||||
{
|
{
|
||||||
struct pci_io_addr_range *piar;
|
struct pci_io_addr_range *piar;
|
||||||
struct rb_node *n;
|
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)) {
|
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);
|
piar = rb_entry(n, struct pci_io_addr_range, rb_node);
|
||||||
|
|
||||||
@ -281,7 +282,7 @@ static int eeh_addr_cache_show(struct seq_file *s, void *v)
|
|||||||
(piar->flags & IORESOURCE_IO) ? "i/o" : "mem",
|
(piar->flags & IORESOURCE_IO) ? "i/o" : "mem",
|
||||||
&piar->addr_lo, &piar->addr_hi, pci_name(piar->pcidev));
|
&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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user