aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2014-02-26 05:30:30 -0500
committerDavid Vrabel <david.vrabel@citrix.com>2014-03-18 10:40:20 -0400
commitcd979883b9ede90643e019f33cb317933eb867b4 (patch)
treee98a9654826b2396f7b01b65300c0a68946b9e33
parent1429d46df4c538d28460d0b493997006a62a1093 (diff)
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 <sgruszka@redhat.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r--drivers/xen/manage.c16
-rw-r--r--drivers/xen/xen-acpi-processor.c15
-rw-r--r--include/xen/xen-ops.h4
3 files changed, 28 insertions, 7 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 624e8dc24532..fc6c94c0b436 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -46,6 +46,20 @@ struct suspend_info {
46 void (*post)(int cancelled); 46 void (*post)(int cancelled);
47}; 47};
48 48
49static RAW_NOTIFIER_HEAD(xen_resume_notifier);
50
51void xen_resume_notifier_register(struct notifier_block *nb)
52{
53 raw_notifier_chain_register(&xen_resume_notifier, nb);
54}
55EXPORT_SYMBOL_GPL(xen_resume_notifier_register);
56
57void xen_resume_notifier_unregister(struct notifier_block *nb)
58{
59 raw_notifier_chain_unregister(&xen_resume_notifier, nb);
60}
61EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
62
49#ifdef CONFIG_HIBERNATE_CALLBACKS 63#ifdef CONFIG_HIBERNATE_CALLBACKS
50static void xen_hvm_post_suspend(int cancelled) 64static void xen_hvm_post_suspend(int cancelled)
51{ 65{
@@ -152,6 +166,8 @@ static void do_suspend(void)
152 166
153 err = stop_machine(xen_suspend, &si, cpumask_of(0)); 167 err = stop_machine(xen_suspend, &si, cpumask_of(0));
154 168
169 raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
170
155 dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE); 171 dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
156 172
157 if (err) { 173 if (err) {
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c
index 7231859119f1..82358d14ecf1 100644
--- a/drivers/xen/xen-acpi-processor.c
+++ b/drivers/xen/xen-acpi-processor.c
@@ -27,10 +27,10 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/syscore_ops.h>
31#include <linux/acpi.h> 30#include <linux/acpi.h>
32#include <acpi/processor.h> 31#include <acpi/processor.h>
33#include <xen/xen.h> 32#include <xen/xen.h>
33#include <xen/xen-ops.h>
34#include <xen/interface/platform.h> 34#include <xen/interface/platform.h>
35#include <asm/xen/hypercall.h> 35#include <asm/xen/hypercall.h>
36 36
@@ -495,14 +495,15 @@ static int xen_upload_processor_pm_data(void)
495 return rc; 495 return rc;
496} 496}
497 497
498static void xen_acpi_processor_resume(void) 498static int xen_acpi_processor_resume(struct notifier_block *nb,
499 unsigned long action, void *data)
499{ 500{
500 bitmap_zero(acpi_ids_done, nr_acpi_bits); 501 bitmap_zero(acpi_ids_done, nr_acpi_bits);
501 xen_upload_processor_pm_data(); 502 return xen_upload_processor_pm_data();
502} 503}
503 504
504static struct syscore_ops xap_syscore_ops = { 505struct notifier_block xen_acpi_processor_resume_nb = {
505 .resume = xen_acpi_processor_resume, 506 .notifier_call = xen_acpi_processor_resume,
506}; 507};
507 508
508static int __init xen_acpi_processor_init(void) 509static int __init xen_acpi_processor_init(void)
@@ -555,7 +556,7 @@ static int __init xen_acpi_processor_init(void)
555 if (rc) 556 if (rc)
556 goto err_unregister; 557 goto err_unregister;
557 558
558 register_syscore_ops(&xap_syscore_ops); 559 xen_resume_notifier_register(&xen_acpi_processor_resume_nb);
559 560
560 return 0; 561 return 0;
561err_unregister: 562err_unregister:
@@ -574,7 +575,7 @@ static void __exit xen_acpi_processor_exit(void)
574{ 575{
575 int i; 576 int i;
576 577
577 unregister_syscore_ops(&xap_syscore_ops); 578 xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb);
578 kfree(acpi_ids_done); 579 kfree(acpi_ids_done);
579 kfree(acpi_id_present); 580 kfree(acpi_id_present);
580 kfree(acpi_id_cst_present); 581 kfree(acpi_id_cst_present);
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index fb2ea8f26552..2cf47175b12b 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -2,6 +2,7 @@
2#define INCLUDE_XEN_OPS_H 2#define INCLUDE_XEN_OPS_H
3 3
4#include <linux/percpu.h> 4#include <linux/percpu.h>
5#include <linux/notifier.h>
5#include <asm/xen/interface.h> 6#include <asm/xen/interface.h>
6 7
7DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); 8DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
@@ -16,6 +17,9 @@ void xen_mm_unpin_all(void);
16void xen_timer_resume(void); 17void xen_timer_resume(void);
17void xen_arch_resume(void); 18void xen_arch_resume(void);
18 19
20void xen_resume_notifier_register(struct notifier_block *nb);
21void xen_resume_notifier_unregister(struct notifier_block *nb);
22
19int xen_setup_shutdown_event(void); 23int xen_setup_shutdown_event(void);
20 24
21extern unsigned long *xen_contiguous_bitmap; 25extern unsigned long *xen_contiguous_bitmap;