How does the kernel wake up a blocking system call when the process receives a signal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I have a general question about how the kernel wakes up a blocking
system call when a signal is received. For example blocking sleep or
select. According to the man pages, sleep should deschedule the process
for a certain amount of time. The process could also be prematurely
woken up by a signal and in that case, the kernel returns the value of
EINTR. I have looked at the kernel source code and it seems that signals
could be somewhat lost. That is the user does sleep() or select(), a
signal is received but yet the signal is lost and the process remains
descheduled. In the case of sleep, the process would sleep for the
amount of time and select could possibly be blocked forever.

The kernel source code for sys_nanosleep is very simple, it is found in
the file  kernel/timer.c and involves two short functions sys_nanosleep
() and schedule_timeout(). The simplified pseudocode is as follows:

1 sys_nanosleep()
2 {
3  Get user arguments
4  Calculate time in future when the process has to wakeup
5  set state of process to TASK_INTERRUPTIBLE
6  set timer
7  schedule()
8
8  if (woken up by timer)
9      return 0
10 else
11     return EINTR
12 }

When process A sends a signal to process B. The following happens if the
signal is not ignored:
- Process A sets the SIGPENDING flag of process B
- Process A calls wake_up_process() to set the state of process to
TASK_RUNNING.

So in normal case, process B wakes up and starts executing on line 8
above. sys_nanosleep() returns to user-space. When returning to user-
space the code in entry.S gets executed which checks for SIGPENDING flag
and possibly calls the appropriate signal handler in user-space.

The issue I have is that a signal could be lost for sys_nanosleep if
wake_up_process() is called before line 5. In kernel 2.6 there is kernel
preemption and this could happen. According to "linux kernel development"
 book (By Robert Love), the
kernel could be preempted as long as the
process is not holding any
locks which is the case here. So, the process
would sleep for the whole
timeout period.

Thanks
Richard

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux