Skip to content

Commit e2d5915

Browse files
committed
powerpc/pseries: Make RAS IRQ explicitly dependent on DLPAR WQ
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 <[email protected]> Reported-by: Daniel Henrique Barboza <[email protected]> Tested-by: Jose Ricardo Ziviani <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Reviewed-by: David Gibson <[email protected]>
1 parent ecb101a commit e2d5915

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

arch/powerpc/platforms/pseries/dlpar.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -574,11 +574,26 @@ static ssize_t dlpar_show(struct class *class, struct class_attribute *attr,
574574

575575
static CLASS_ATTR_RW(dlpar);
576576

577-
static int __init pseries_dlpar_init(void)
577+
int __init dlpar_workqueue_init(void)
578578
{
579+
if (pseries_hp_wq)
580+
return 0;
581+
579582
pseries_hp_wq = alloc_workqueue("pseries hotplug workqueue",
580-
WQ_UNBOUND, 1);
583+
WQ_UNBOUND, 1);
584+
585+
return pseries_hp_wq ? 0 : -ENOMEM;
586+
}
587+
588+
static int __init dlpar_sysfs_init(void)
589+
{
590+
int rc;
591+
592+
rc = dlpar_workqueue_init();
593+
if (rc)
594+
return rc;
595+
581596
return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr);
582597
}
583-
machine_device_initcall(pseries, pseries_dlpar_init);
598+
machine_device_initcall(pseries, dlpar_sysfs_init);
584599

arch/powerpc/platforms/pseries/pseries.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,6 @@ static inline unsigned long cmo_get_page_size(void)
9898
return CMO_PageSize;
9999
}
100100

101+
int dlpar_workqueue_init(void);
102+
101103
#endif /* _PSERIES_PSERIES_H */

arch/powerpc/platforms/pseries/ras.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ static int __init init_ras_IRQ(void)
6969
/* Hotplug Events */
7070
np = of_find_node_by_path("/event-sources/hot-plug-events");
7171
if (np != NULL) {
72-
request_event_sources_irqs(np, ras_hotplug_interrupt,
72+
if (dlpar_workqueue_init() == 0)
73+
request_event_sources_irqs(np, ras_hotplug_interrupt,
7374
"RAS_HOTPLUG");
7475
of_node_put(np);
7576
}

0 commit comments

Comments
 (0)