Linux kernel: Will wait_event_interruptible sleep forever when the preemption happens right after prepare_to_wait_event?

260 Views Asked by At

I'm a bit confused when reading the kernel's source code on wait_event_interruptible because it does not look safe when taking into account the preemption.

Here is the main logic of the source code:

1: #define ___wait_event(wq_head, condition, state, exclusive, ret, cmd)        \
2: ({                                       \
3:  __label__ __out;                            \
4:  struct wait_queue_entry __wq_entry;                 \
5:  long __ret = ret;   /* explicit shadow */               \
6:                                      \
7:  init_wait_entry(&__wq_entry, exclusive ? WQ_FLAG_EXCLUSIVE : 0);    \
8:  for (;;) {                              \
9:      long __int = prepare_to_wait_event(&wq_head, &__wq_entry, state);\
10:                                     \
11:     if (condition)                          \
12:         break;                          \
13:                                     \
14:     if (___wait_is_interruptible(state) && __int) {         \
15:         __ret = __int;                      \
16:         goto __out;                     \
17:     }                               \
18:                                     \
19:     cmd;                                \
20: }                                   \
21: finish_wait(&wq_head, &__wq_entry);                 \
22: __out:  __ret;                                  \
23: })

This macro is not wrapped in a preemption-disabling block, and so I think it's possible that the corresponding process could be switched out in line 10. So under the following scenario:

  1. There is only on wakeup for this sleep.
  2. The aforementioned wakeup occurs in another cpu when this code is in line 8.
  3. An interrupt kicked in at line 10, and this process is switched out as the result.

As a result, this process will stay in TASK_INTERRUPTIBLE forever.

I'm wondering if that is the case or did I miss anything?

The linux code I'm looking at: https://elixir.bootlin.com/linux/v5.13.4/source/include/linux/wait.h#L274

1

There are 1 best solutions below

0
tej parkash On

Surely, it would stay hang but next time when process gets schedule and it resumes it would check the condition and would find condition as true and it would break.

Let suppose condition goes bad as other process modified value then it would hang until someone trigger signal to it and this process would check the signal and break out of for loop.