Skip to content

Commit

Permalink
powerpc/pseries: Make RAS IRQ explicitly dependent on DLPAR WQ
Browse files Browse the repository at this point in the history
The hotplug code uses its own workqueue to handle IRQ requests
(pseries_hp_wq), however that workqueue is initialized after
init_ras_IRQ(). That can lead to a kernel panic if any hotplug
interrupts fire after init_ras_IRQ() but before pseries_hp_wq is
initialised. eg:

  UDP-Lite hash table entries: 2048 (order: 0, 65536 bytes)
  NET: Registered protocol family 1
  Unpacking initramfs...
  (qemu) object_add memory-backend-ram,id=mem1,size=10G
  (qemu) device_add pc-dimm,id=dimm1,memdev=mem1
  Unable to handle kernel paging request for data at address 0xf94d03007c421378
  Faulting instruction address: 0xc00000000012d744
  Oops: Kernel access of bad area, sig: 11 [#1]
  LE SMP NR_CPUS=2048 NUMA pSeries
  Modules linked in:
  CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.15.0-rc2-ziviani+ #26
  task:         (ptrval) task.stack:         (ptrval)
  NIP:  c00000000012d744 LR: c00000000012d744 CTR: 0000000000000000
  REGS:         (ptrval) TRAP: 0380   Not tainted  (4.15.0-rc2-ziviani+)
  MSR:  8000000000009033 <SF,EE,ME,IR,DR,RI,LE>  CR: 28088042  XER: 20040000
  CFAR: c00000000012d3c4 SOFTE: 0
  ...
  NIP [c00000000012d744] __queue_work+0xd4/0x5c0
  LR [c00000000012d744] __queue_work+0xd4/0x5c0
  Call Trace:
  [c0000000fffefb90] [c00000000012d744] __queue_work+0xd4/0x5c0 (unreliable)
  [c0000000fffefc70] [c00000000012dce4] queue_work_on+0xb4/0xf0

This commit makes the RAS IRQ registration explicitly dependent on the
creation of the pseries_hp_wq.

Reported-by: Min Deng <mdeng@redhat.com>
Reported-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
Tested-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
  • Loading branch information
mpe committed Jan 8, 2018
1 parent ecb101a commit e2d5915
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
21 changes: 18 additions & 3 deletions arch/powerpc/platforms/pseries/dlpar.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,11 +574,26 @@ static ssize_t dlpar_show(struct class *class, struct class_attribute *attr,

static CLASS_ATTR_RW(dlpar);

static int __init pseries_dlpar_init(void)
int __init dlpar_workqueue_init(void)
{
if (pseries_hp_wq)
return 0;

pseries_hp_wq = alloc_workqueue("pseries hotplug workqueue",
WQ_UNBOUND, 1);
WQ_UNBOUND, 1);

return pseries_hp_wq ? 0 : -ENOMEM;
}

static int __init dlpar_sysfs_init(void)
{
int rc;

rc = dlpar_workqueue_init();
if (rc)
return rc;

return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr);
}
machine_device_initcall(pseries, pseries_dlpar_init);
machine_device_initcall(pseries, dlpar_sysfs_init);

2 changes: 2 additions & 0 deletions arch/powerpc/platforms/pseries/pseries.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,6 @@ static inline unsigned long cmo_get_page_size(void)
return CMO_PageSize;
}

int dlpar_workqueue_init(void);

#endif /* _PSERIES_PSERIES_H */
3 changes: 2 additions & 1 deletion arch/powerpc/platforms/pseries/ras.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ static int __init init_ras_IRQ(void)
/* Hotplug Events */
np = of_find_node_by_path("/event-sources/hot-plug-events");
if (np != NULL) {
request_event_sources_irqs(np, ras_hotplug_interrupt,
if (dlpar_workqueue_init() == 0)
request_event_sources_irqs(np, ras_hotplug_interrupt,
"RAS_HOTPLUG");
of_node_put(np);
}
Expand Down

0 comments on commit e2d5915

Please sign in to comment.