0

I know that we can use pthread_cond_init, pthread_cond_wait, and pthread_cond_broadcast to implement thread condition signaling in user space. But how can we implement it in a kernel module that is using kthread?

linux/mutex.h provides locking as discussed in this question. But it does not seem to be associated with any condition variables.

linex/wait.h seems to have condition waiting but it has no documentation so there are too many concerns around it. For example, wake_up_interruptable could have a race condition when used as suggested in examples with no mutex. It seems unlikely that the wait queues could be combined with mutex waits in a way that would implement semantics like pthread_cond_wait, because the thread scheduling functions implementing these different APIs need to be integrated to provide atomic semantics.

How can a kernel module get atomic sleep-and-unlock semantics, like in a normal user-space API, like pthread_cond_wait?

The specific semantics I need are (from the pthread_cond_wait* manpage):

These functions atomically release mutex and cause the calling thread to block on the condition variable cond; atomically here means "atomically with respect to access by another thread to the mutex and then the condition variable". That is, if another thread is able to acquire the mutex after the about-to-block thread has released it, then a subsequent call to pthread_cond_broadcast() or pthread_cond_signal() in that thread shall behave as if it were issued after the about-to-block thread has blocked.

The important requirements are:

  • The condition is a shared structure, and can only be accessed when the mutex is held.
  • Atomicity prevents the condition from becoming true in between the mutex release and thread blocking. Without this, the thread could check the condition (when it's false), then release the mutex, then the condition becomes true (and a signal is generated and propagated), and then the thread falls asleep and misses the signal.

(Here is how pthread_cond_wait is used in a program).

personal_cloud
  • 3,943
  • 3
  • 28
  • 38
  • You are probably looking for *completions*, see documentation under [Documentation/scheduler/completion.txt](https://www.kernel.org/doc/Documentation/scheduler/completion.txt). – Tsyvarev Jul 04 '19 at 06:17
  • @Tsyvarev Thanks for that link. That is an interesting site -- I wonder if it is actually organized somehow. Also I like the way completions will work regardless of ordering of `complete` vs. `wait_for_completion`. However they might be missing support for arbitrary condition expressions, as is normal with a loop using `pthread_cond_wait`. Also the condition itself would often need mutually exclusive access. `complete()` is just a special case. – personal_cloud Jul 04 '19 at 06:29
  • Yes, *completions* provide different abilities than *condition variables*. I realized that after posting the comment. Nevertheless, wait_queues mechanism (and `wait_*` macros) are very powerful. But complete description of that "power" could be very long. Could you add **some code** to the question post, which shows your needs? So the answer would be also accompanied with a *concrete code*. – Tsyvarev Jul 04 '19 at 09:21
  • @Tsyvarev I explained the specific operations that I want my `cond_wait` function to do. This is very standard; I am not trying to do anything tricky here. [Here](https://stackoverflow.com/a/16524148/5896591) is example pthread_cond_wait code -- actually this is pretty much the general example and what I want. Notice how the lock is held during condition evaluation. – personal_cloud Jul 07 '19 at 19:21

0 Answers0