Uninterruptable Sleep

Another question from usenet read:

I have read that no program can ignore SIGKILL and SIGSTOP. But, a task is in UNINTERRUPTIBLE state when it sleeps blocking all signals. Could someone help me understand the scenario? Isn't it blocking all signals (including SIGKILL and SIGSTOP)?

The kernel performs magic on behalf of processes. At intervals, each process sends a request to the kernel, and the kernel tries to service the request. In the mean time, the kernel prevents the process from continueing, by taking it out of execution, and parking it in a queue. When the kernel has finally serviced the request, it will take the process out of it's parking queue, and put it in another queue, which ultimately permits it to run again.

So, graphically, the process moves like this...


   Executing process requests some service from kernel,
    \   kernel suspends process and moves it to a parking queue
     \ 
      \              Kernel completes the service,
       \             \    kernel moves suspended process to one of the runnable queues
        \             \ 
         \             \               Suspended process moves to top of runnable queue, 
          \             \               \   kernel resumes the process execution
           \             \               \
  Running --;--> Parked --;--> Runnable --;--> Running

Normally, a process spends only a very short time in this 'parking' queue (and there are several of them), and you don't see it in a ps(1) listing

Now, what happens if/when the kernel cannot (for some reason) service the request? Say, for instance, the process asked the kernel to read a particular disk block (as in a file read), but the disk controller has failed. The kernel cannot release the process back to it's runnable state until the read completes, and the read never completes. So, the process stays in the 'parked' queue until the read request completes, and sometimes this means that it stays there until the hardware or software error that prevented the request completion is repaired.

A process in one of these 'parked' queues is marked with the 'D' "Uninterruptible Sleep" state. When the process moves to a runnable queue, ps(1) shows a different state.

Now, when does a process receive signals? It receives signals when it runs. Only when it runs. Any signals pending for the process are kept queued for the process, and only delivered when the process actually runs. The process runs when it gets to the top of a 'runnable' queue, and the scheduler picks it up and restarts it. If the process is not in a 'runnable' queue, it will not be run, and therefore will not receive signals.

A process in one of these 'parking' queues is not runnable. Thus, a parked process cannot receive signals. You can queue up as many SIGKILLs or SIGSTOPs as you like, but until you clear the problem that's keeping the process in the 'D' state, the process can not receive the signals.

The only way to get a 'D' state process to receive it's signals is to clear the condition thats keeping the process in the 'D' state to begin with. With that, the process can then move to 'runnable' and onwards to actually be run, and it will receive the signals when it runs.

Articles: