From d6d1d580bbad0ce6f2186f18fbb3293862741cd0 Mon Sep 17 00:00:00 2001 From: claudio Date: Fri, 28 Jul 2023 09:46:13 +0000 Subject: [PATCH] Properly emulate wait_event_interruptible_locked(). This function is called with the wait_queue_head locked, so the code can not use prepare_to_wait()/finish_wait() since these assume the wqh is unlocked. Also the lock needs to be held right up to the schedule()/sleep_finish() call. OK kettenis@ jsg@ --- sys/dev/pci/drm/include/linux/wait.h | 30 ++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/sys/dev/pci/drm/include/linux/wait.h b/sys/dev/pci/drm/include/linux/wait.h index e8b9f0c5c27..4523483ea77 100644 --- a/sys/dev/pci/drm/include/linux/wait.h +++ b/sys/dev/pci/drm/include/linux/wait.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wait.h,v 1.10 2023/07/18 06:58:59 claudio Exp $ */ +/* $OpenBSD: wait.h,v 1.11 2023/07/28 09:46:13 claudio Exp $ */ /* * Copyright (c) 2013, 2014, 2015 Mark Kettenis * Copyright (c) 2017 Martin Pieuchot @@ -159,11 +159,37 @@ do { \ __ret; \ }) +#define __wait_event_intr_locked(wqh, condition) \ +({ \ + struct wait_queue_entry __wq_entry; \ + int __error; \ + \ + init_wait_entry(&__wq_entry, 0); \ + do { \ + KASSERT(!cold); \ + \ + if (list_empty(&__wq_entry.entry)) \ + __add_wait_queue_entry_tail(&wqh, &__wq_entry); \ + set_current_state(TASK_INTERRUPTIBLE); \ + \ + mtx_leave(&(wqh).lock); \ + __error = sleep_finish(0, 1); \ + mtx_enter(&(wqh).lock); \ + if (__error == ERESTART || __error == EINTR) { \ + __error = -ERESTARTSYS; \ + break; \ + } \ + } while (!(condition)); \ + __remove_wait_queue(&(wqh), &__wq_entry); \ + __set_current_state(TASK_RUNNING); \ + __error; \ +}) + #define wait_event_interruptible_locked(wqh, condition) \ ({ \ int __ret = 0; \ if (!(condition)) \ - __ret = __wait_event_intr_timeout(wqh, condition, 0, PCATCH); \ + __ret = __wait_event_intr_locked(wqh, condition); \ __ret; \ }) -- 2.20.1