Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[.joined/src/trunk]: .joined/src/sys/dev/acpi acpi(9): Fix memory ordering an...



details:   https://anonhg.NetBSD.org/.joined/src/rev/07ec21e944c3
branches:  trunk
changeset: 359337:07ec21e944c3
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Fri Dec 31 14:22:42 2021 +0000

description:
acpi(9): Fix memory ordering and completion bugs in notifiers.

1. Guarantee everything which happened before acpi_register_notify
   has also happened before the notifier is actually called.

2. On acpi_deregister_notify, don't return until the notifier is
   definitely not running any more on any CPU, using
   AcpiOsWaitEventsComplete.

diffstat:

 sys/dev/acpi/acpi.c |  17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

diffs (70 lines):

diff -r 674069d58658 -r 07ec21e944c3 sys/dev/acpi/acpi.c
--- a/sys/dev/acpi/acpi.c       Fri Dec 31 14:22:26 2021 +0000
+++ b/sys/dev/acpi/acpi.c       Fri Dec 31 14:22:42 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: acpi.c,v 1.294 2021/12/20 11:17:40 skrll Exp $ */
+/*     $NetBSD: acpi.c,v 1.295 2021/12/31 14:22:42 riastradh Exp $     */
 
 /*-
  * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -100,13 +100,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.294 2021/12/20 11:17:40 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.295 2021/12/31 14:22:42 riastradh Exp $");
 
 #include "pci.h"
 #include "opt_acpi.h"
 #include "opt_pcifixup.h"
 
 #include <sys/param.h>
+#include <sys/atomic.h>
 #include <sys/device.h>
 #include <sys/kernel.h>
 #include <sys/kmem.h>
@@ -1146,6 +1147,7 @@
 {
        struct acpi_softc *sc = acpi_softc;
        struct acpi_devnode *ad;
+       ACPI_NOTIFY_HANDLER notify;
 
        KASSERT(sc != NULL);
        KASSERT(aux == NULL);
@@ -1189,13 +1191,13 @@
                if (ad->ad_device == NULL)
                        continue;
 
-               if (ad->ad_notify == NULL)
+               if ((notify = atomic_load_acquire(&ad->ad_notify)) == NULL)
                        continue;
 
                if (ad->ad_handle != handle)
                        continue;
 
-               (*ad->ad_notify)(ad->ad_handle, event, ad->ad_device);
+               (*notify)(ad->ad_handle, event, ad->ad_device);
 
                return;
        }
@@ -1218,7 +1220,7 @@
        if (ad == NULL || notify == NULL)
                goto fail;
 
-       ad->ad_notify = notify;
+       atomic_store_release(&ad->ad_notify, notify);
 
        return true;
 
@@ -1233,7 +1235,10 @@
 acpi_deregister_notify(struct acpi_devnode *ad)
 {
 
-       ad->ad_notify = NULL;
+       atomic_store_relaxed(&ad->ad_notify, NULL);
+
+       /* Wait for any in-flight calls to the notifier to complete.  */
+       AcpiOsWaitEventsComplete();
 }
 
 /*



Home | Main Index | Thread Index | Old Index