Skip to content

Commit cd97988

Browse files
Stanislaw GruszkaDavid Vrabel
authored andcommitted
xen/acpi-processor: fix enabling interrupts on syscore_resume
syscore->resume() callback is expected to do not enable interrupts, it generates warning like below otherwise: [ 9386.365390] WARNING: CPU: 0 PID: 6733 at drivers/base/syscore.c:104 syscore_resume+0x9a/0xe0() [ 9386.365403] Interrupts enabled after xen_acpi_processor_resume+0x0/0x34 [xen_acpi_processor] ... [ 9386.365429] Call Trace: [ 9386.365434] [<ffffffff81667a8b>] dump_stack+0x45/0x56 [ 9386.365437] [<ffffffff8106921d>] warn_slowpath_common+0x7d/0xa0 [ 9386.365439] [<ffffffff8106928c>] warn_slowpath_fmt+0x4c/0x50 [ 9386.365442] [<ffffffffa0261bb0>] ? xen_upload_processor_pm_data+0x300/0x300 [xen_acpi_processor] [ 9386.365443] [<ffffffff814055fa>] syscore_resume+0x9a/0xe0 [ 9386.365445] [<ffffffff810aef42>] suspend_devices_and_enter+0x402/0x470 [ 9386.365447] [<ffffffff810af128>] pm_suspend+0x178/0x260 On xen_acpi_processor_resume() we call various procedures, which are non atomic and can enable interrupts. To prevent the issue introduce separate resume notify called after we enable interrupts on resume and before we call other drivers resume callbacks. Signed-off-by: Stanislaw Gruszka <[email protected]> Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
1 parent 1429d46 commit cd97988

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

drivers/xen/manage.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ struct suspend_info {
4646
void (*post)(int cancelled);
4747
};
4848

49+
static RAW_NOTIFIER_HEAD(xen_resume_notifier);
50+
51+
void xen_resume_notifier_register(struct notifier_block *nb)
52+
{
53+
raw_notifier_chain_register(&xen_resume_notifier, nb);
54+
}
55+
EXPORT_SYMBOL_GPL(xen_resume_notifier_register);
56+
57+
void xen_resume_notifier_unregister(struct notifier_block *nb)
58+
{
59+
raw_notifier_chain_unregister(&xen_resume_notifier, nb);
60+
}
61+
EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
62+
4963
#ifdef CONFIG_HIBERNATE_CALLBACKS
5064
static void xen_hvm_post_suspend(int cancelled)
5165
{
@@ -152,6 +166,8 @@ static void do_suspend(void)
152166

153167
err = stop_machine(xen_suspend, &si, cpumask_of(0));
154168

169+
raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
170+
155171
dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
156172

157173
if (err) {

drivers/xen/xen-acpi-processor.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727
#include <linux/init.h>
2828
#include <linux/module.h>
2929
#include <linux/types.h>
30-
#include <linux/syscore_ops.h>
3130
#include <linux/acpi.h>
3231
#include <acpi/processor.h>
3332
#include <xen/xen.h>
33+
#include <xen/xen-ops.h>
3434
#include <xen/interface/platform.h>
3535
#include <asm/xen/hypercall.h>
3636

@@ -495,14 +495,15 @@ static int xen_upload_processor_pm_data(void)
495495
return rc;
496496
}
497497

498-
static void xen_acpi_processor_resume(void)
498+
static int xen_acpi_processor_resume(struct notifier_block *nb,
499+
unsigned long action, void *data)
499500
{
500501
bitmap_zero(acpi_ids_done, nr_acpi_bits);
501-
xen_upload_processor_pm_data();
502+
return xen_upload_processor_pm_data();
502503
}
503504

504-
static struct syscore_ops xap_syscore_ops = {
505-
.resume = xen_acpi_processor_resume,
505+
struct notifier_block xen_acpi_processor_resume_nb = {
506+
.notifier_call = xen_acpi_processor_resume,
506507
};
507508

508509
static int __init xen_acpi_processor_init(void)
@@ -555,7 +556,7 @@ static int __init xen_acpi_processor_init(void)
555556
if (rc)
556557
goto err_unregister;
557558

558-
register_syscore_ops(&xap_syscore_ops);
559+
xen_resume_notifier_register(&xen_acpi_processor_resume_nb);
559560

560561
return 0;
561562
err_unregister:
@@ -574,7 +575,7 @@ static void __exit xen_acpi_processor_exit(void)
574575
{
575576
int i;
576577

577-
unregister_syscore_ops(&xap_syscore_ops);
578+
xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb);
578579
kfree(acpi_ids_done);
579580
kfree(acpi_id_present);
580581
kfree(acpi_id_cst_present);

include/xen/xen-ops.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define INCLUDE_XEN_OPS_H
33

44
#include <linux/percpu.h>
5+
#include <linux/notifier.h>
56
#include <asm/xen/interface.h>
67

78
DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
@@ -16,6 +17,9 @@ void xen_mm_unpin_all(void);
1617
void xen_timer_resume(void);
1718
void xen_arch_resume(void);
1819

20+
void xen_resume_notifier_register(struct notifier_block *nb);
21+
void xen_resume_notifier_unregister(struct notifier_block *nb);
22+
1923
int xen_setup_shutdown_event(void);
2024

2125
extern unsigned long *xen_contiguous_bitmap;

0 commit comments

Comments
 (0)