Не вдаваясь сначала в источник, я скажу, что вы должны использовать библиотеку wait_event, и вам не нужны мьютексы или другие подобные вещи, о которых заботится ядро. Лично у меня есть только опыт работы с wait_event_interruptible и wake_up_interruptible , но я подозреваю, что все они похожи.
Теперь на источник, который я извлекаю из https://elixir.bootlin.com/linux/latest/source/include/linux/wait.h#L302
#define ___wait_event(wq_head, condition, state, exclusive, ret, cmd) \
({ \
__label__ __out; \
struct wait_queue_entry __wq_entry; \
long __ret = ret; /* explicit shadow */ \
\
init_wait_entry(&__wq_entry, exclusive ? WQ_FLAG_EXCLUSIVE : 0); \
for (;;) { \
long __int = prepare_to_wait_event(&wq_head, &__wq_entry, state);\
\
if (condition) \
break; \
\
if (___wait_is_interruptible(state) && __int) { \
__ret = __int; \
goto __out; \
} \
\
cmd; \
} \
finish_wait(&wq_head, &__wq_entry); \
__out: __ret; \
})
long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state)
{
unsigned long flags;
long ret = 0;
spin_lock_irqsave(&wq_head->lock, flags);
....
spin_unlock_irqrestore(&wq_head->lock, flags);
return ret;
}
Как видно, библиотека ожидания уже использует spin_locks, которые похожи на mutex (хотя и немного отличаются). Хорошая вещь в использовании библиотеки ожидания заключается в том, что для вас автоматически выполняется множество проверок безопасности, чтобы ядро работало и работало, но оно по-прежнему выполняет необходимый блок для ваших данных. Если вам нужно больше примеров использования wait_event_ * и связанных с ним вызовов wake_up_ *, дайте мне знать, и я смогу его получить.