summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTobias Heider <tobhe@cvs.openbsd.org>2024-07-12 10:01:29 +0000
committerTobias Heider <tobhe@cvs.openbsd.org>2024-07-12 10:01:29 +0000
commit44fdba670412b4e62a08a130183c663ec0feff3c (patch)
treeb755c4ab8f66ae3b7c3ef6c8602bf7990b0519ec /sys
parent8886fa6021409e7022b9eb62b0d1b77e94cc64c3 (diff)
Add pool to allocate individual rtkit task arguments instead of passing a
shared argument. This fixes a race condition where a message could overwrite rtkep->msg of a previously scheduled task resulting in a refcounting error later on causing the screen to stay dark after waking up from suspend. ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/drm/apple/apldcp.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/sys/dev/pci/drm/apple/apldcp.c b/sys/dev/pci/drm/apple/apldcp.c
index c27bcd72859..6ab379c6b5f 100644
--- a/sys/dev/pci/drm/apple/apldcp.c
+++ b/sys/dev/pci/drm/apple/apldcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apldcp.c,v 1.1 2024/01/22 18:54:01 kettenis Exp $ */
+/* $OpenBSD: apldcp.c,v 1.2 2024/07/12 10:01:28 tobhe Exp $ */
/*
* Copyright (c) 2023 Mark Kettenis <kettenis@openbsd.org>
*
@@ -18,6 +18,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/pool.h>
#include <machine/intr.h>
#include <machine/bus.h>
@@ -103,14 +104,19 @@ apldcp_activate(struct device *self, int act)
#include <arm64/dev/rtkit.h>
+struct apple_rtkit_task {
+ struct apple_rtkit_ep *rtkep;
+ struct task task;
+ uint64_t msg;
+};
+
struct apple_rtkit_ep {
struct apple_rtkit *rtk;
uint8_t ep;
-
- struct task task;
- uint64_t msg;
};
+static struct pool rtktask_pool;
+
struct apple_rtkit {
struct rtkit_state *state;
struct apple_rtkit_ep ep[64];
@@ -170,10 +176,12 @@ apple_rtkit_logmap(void *cookie, bus_addr_t addr)
void
apple_rtkit_do_recv(void *arg)
{
- struct apple_rtkit_ep *rtkep = arg;
+ struct apple_rtkit_task *rtktask = arg;
+ struct apple_rtkit_ep *rtkep = rtktask->rtkep;
struct apple_rtkit *rtk = rtkep->rtk;
- rtk->ops->recv_message(rtk->cookie, rtkep->ep, rtkep->msg);
+ rtk->ops->recv_message(rtk->cookie, rtkep->ep, rtktask->msg);
+ pool_put(&rtktask_pool, rtktask);
}
void
@@ -181,9 +189,15 @@ apple_rtkit_recv(void *cookie, uint64_t msg)
{
struct apple_rtkit_ep *rtkep = cookie;
struct apple_rtkit *rtk = rtkep->rtk;
+ struct apple_rtkit_task *rtktask;
- rtkep->msg = msg;
- task_add(rtk->tq, &rtkep->task);
+ rtktask = pool_get(&rtktask_pool, PR_NOWAIT | PR_ZERO);
+ KASSERT(rtktask != NULL);
+
+ rtktask->rtkep = rtkep;
+ rtktask->msg = msg;
+ task_set(&rtktask->task, apple_rtkit_do_recv, rtktask);
+ task_add(rtk->tq, &rtktask->task);
}
int
@@ -195,8 +209,6 @@ apple_rtkit_start_ep(struct apple_rtkit *rtk, uint8_t ep)
rtkep = &rtk->ep[ep];
rtkep->rtk = rtk;
rtkep->ep = ep;
- task_set(&rtkep->task, apple_rtkit_do_recv, rtkep);
-
error = rtkit_start_endpoint(rtk->state, ep, apple_rtkit_recv, rtkep);
return -error;
}
@@ -239,6 +251,9 @@ devm_apple_rtkit_init(struct device *dev, void *cookie,
return ERR_PTR(ENOMEM);
}
+ pool_init(&rtktask_pool, sizeof(struct apple_rtkit_task), 0, IPL_TTY,
+ 0, "apldcp_rtkit", NULL);
+
rk = malloc(sizeof(*rk), M_DEVBUF, M_WAITOK | M_ZERO);
rk->rk_cookie = rtk;
rk->rk_dmat = pdev->dmat;