Module Name: src
Committed By: riastradh
Date: Fri Dec 31 14:22:42 UTC 2021
Modified Files:
src/sys/dev/acpi: acpi.c
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.294 -r1.295 src/sys/dev/acpi/acpi.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/acpi/acpi.c
diff -u src/sys/dev/acpi/acpi.c:1.294 src/sys/dev/acpi/acpi.c:1.295
--- src/sys/dev/acpi/acpi.c:1.294 Mon Dec 20 11:17:40 2021
+++ src/sys/dev/acpi/acpi.c Fri Dec 31 14:22:42 2021
@@ -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 @@ acpi_notify_handler(ACPI_HANDLE handle,
{
struct acpi_softc *sc = acpi_softc;
struct acpi_devnode *ad;
+ ACPI_NOTIFY_HANDLER notify;
KASSERT(sc != NULL);
KASSERT(aux == NULL);
@@ -1189,13 +1191,13 @@ acpi_notify_handler(ACPI_HANDLE handle,
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 @@ acpi_register_notify(struct acpi_devnode
if (ad == NULL || notify == NULL)
goto fail;
- ad->ad_notify = notify;
+ atomic_store_release(&ad->ad_notify, notify);
return true;
@@ -1233,7 +1235,10 @@ void
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();
}
/*