acpi_addtask() calls malloc() w/ M_NOWAIT (because some calls come from
authorderaadt <deraadt@openbsd.org>
Wed, 2 Feb 2022 04:05:16 +0000 (04:05 +0000)
committerderaadt <deraadt@openbsd.org>
Wed, 2 Feb 2022 04:05:16 +0000 (04:05 +0000)
interrupt context), this however means occasional resource shortage will
result in callbacks registration failing, and unknown consequences for
the task-submitting caller.
Changing this to use pools with a low water mark, decreases the odds
of that problem occuring.
ok kettenis

sys/dev/acpi/acpi.c

index acbaa1b..6644c52 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.407 2022/02/01 18:09:00 deraadt Exp $ */
+/* $OpenBSD: acpi.c,v 1.408 2022/02/02 04:05:16 deraadt Exp $ */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -21,6 +21,7 @@
 #include <sys/buf.h>
 #include <sys/device.h>
 #include <sys/malloc.h>
+#include <sys/pool.h>
 #include <sys/fcntl.h>
 #include <sys/ioccom.h>
 #include <sys/event.h>
@@ -74,6 +75,8 @@ int   acpi_poll_enabled;
 int    acpi_hasprocfvs;
 int    acpi_haspci;
 
+struct pool acpiwqpool;
+
 #define ACPIEN_RETRIES 15
 
 struct aml_node *acpi_pci_match(struct device *, struct pci_attach_args *);
@@ -1007,6 +1010,10 @@ acpi_attach_common(struct acpi_softc *sc, paddr_t base)
        }
        rsdp = (struct acpi_rsdp *)handle.va;
 
+       pool_init(&acpiwqpool, sizeof(struct acpi_taskq), 0, IPL_BIO, 0,
+           "acpiwqpl", NULL);
+       pool_setlowat(&acpiwqpool, 16);
+
        SIMPLEQ_INIT(&sc->sc_tables);
        SIMPLEQ_INIT(&sc->sc_wakedevs);
 #if NACPIPWRRES > 0
@@ -1798,9 +1805,11 @@ acpi_addtask(struct acpi_softc *sc, void (*handler)(void *, int),
        struct acpi_taskq *wq;
        int s;
 
-       wq = malloc(sizeof(*wq), M_DEVBUF, M_ZERO | M_NOWAIT);
-       if (wq == NULL)
+       wq = pool_get(&acpiwqpool, PR_ZERO | PR_NOWAIT);
+       if (wq == NULL) {
+               printf("unable to create task");
                return;
+       }
        wq->handler = handler;
        wq->arg0 = arg0;
        wq->arg1 = arg1;
@@ -1829,7 +1838,7 @@ acpi_dotask(struct acpi_softc *sc)
 
        wq->handler(wq->arg0, wq->arg1);
 
-       free(wq, M_DEVBUF, sizeof(*wq));
+       pool_put(&acpiwqpool, wq);
 
        /* We did something */
        return (1);