diff options
author | Ankur Arora <ankur.a.arora@oracle.com> | 2017-03-21 18:43:38 -0400 |
---|---|---|
committer | Boris Ostrovsky <boris.ostrovsky@oracle.com> | 2017-03-23 12:00:02 -0400 |
commit | 1914f0cd203c941bba72f9452c8290324f1ef3dc (patch) | |
tree | 6f35f392cbcdb052924e8305b0d5b7fe54677e19 /drivers/xen/xen-acpi-processor.c | |
parent | 1c2593cc8fd5960f8861de1be67135851f884836 (diff) |
xen/acpi: upload PM state from init-domain to Xen
This was broken in commit cd979883b9ed ("xen/acpi-processor:
fix enabling interrupts on syscore_resume"). do_suspend (from
xen/manage.c) and thus xen_resume_notifier never get called on
the initial-domain at resume (it is if running as guest.)
The rationale for the breaking change was that upload_pm_data()
potentially does blocking work in syscore_resume(). This patch
addresses the original issue by scheduling upload_pm_data() to
execute in workqueue context.
Cc: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: stable@vger.kernel.org
Based-on-patch-by: Konrad Wilk <konrad.wilk@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Diffstat (limited to 'drivers/xen/xen-acpi-processor.c')
-rw-r--r-- | drivers/xen/xen-acpi-processor.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index fac0d7b0edf7..23e391d3ec01 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> | ||
30 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
31 | #include <acpi/processor.h> | 32 | #include <acpi/processor.h> |
32 | #include <xen/xen.h> | 33 | #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 | ||
@@ -466,15 +466,33 @@ static int xen_upload_processor_pm_data(void) | |||
466 | return rc; | 466 | return rc; |
467 | } | 467 | } |
468 | 468 | ||
469 | static int xen_acpi_processor_resume(struct notifier_block *nb, | 469 | static void xen_acpi_processor_resume_worker(struct work_struct *dummy) |
470 | unsigned long action, void *data) | ||
471 | { | 470 | { |
471 | int rc; | ||
472 | |||
472 | bitmap_zero(acpi_ids_done, nr_acpi_bits); | 473 | bitmap_zero(acpi_ids_done, nr_acpi_bits); |
473 | return xen_upload_processor_pm_data(); | 474 | |
475 | rc = xen_upload_processor_pm_data(); | ||
476 | if (rc != 0) | ||
477 | pr_info("ACPI data upload failed, error = %d\n", rc); | ||
478 | } | ||
479 | |||
480 | static void xen_acpi_processor_resume(void) | ||
481 | { | ||
482 | static DECLARE_WORK(wq, xen_acpi_processor_resume_worker); | ||
483 | |||
484 | /* | ||
485 | * xen_upload_processor_pm_data() calls non-atomic code. | ||
486 | * However, the context for xen_acpi_processor_resume is syscore | ||
487 | * with only the boot CPU online and in an atomic context. | ||
488 | * | ||
489 | * So defer the upload for some point safer. | ||
490 | */ | ||
491 | schedule_work(&wq); | ||
474 | } | 492 | } |
475 | 493 | ||
476 | struct notifier_block xen_acpi_processor_resume_nb = { | 494 | static struct syscore_ops xap_syscore_ops = { |
477 | .notifier_call = xen_acpi_processor_resume, | 495 | .resume = xen_acpi_processor_resume, |
478 | }; | 496 | }; |
479 | 497 | ||
480 | static int __init xen_acpi_processor_init(void) | 498 | static int __init xen_acpi_processor_init(void) |
@@ -527,7 +545,7 @@ static int __init xen_acpi_processor_init(void) | |||
527 | if (rc) | 545 | if (rc) |
528 | goto err_unregister; | 546 | goto err_unregister; |
529 | 547 | ||
530 | xen_resume_notifier_register(&xen_acpi_processor_resume_nb); | 548 | register_syscore_ops(&xap_syscore_ops); |
531 | 549 | ||
532 | return 0; | 550 | return 0; |
533 | err_unregister: | 551 | err_unregister: |
@@ -544,7 +562,7 @@ static void __exit xen_acpi_processor_exit(void) | |||
544 | { | 562 | { |
545 | int i; | 563 | int i; |
546 | 564 | ||
547 | xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb); | 565 | unregister_syscore_ops(&xap_syscore_ops); |
548 | kfree(acpi_ids_done); | 566 | kfree(acpi_ids_done); |
549 | kfree(acpi_id_present); | 567 | kfree(acpi_id_present); |
550 | kfree(acpi_id_cst_present); | 568 | kfree(acpi_id_cst_present); |