What is the "Waiting Channel" of a process?

In the GNOME System Monitor's Processes tab there is a "Waiting Channel" column. By far the most common values I see here is poll_schedule_timeout , but I also see other values: 0, do_exit, do_wait, futex_wait_queue_me, pipe_wait, __skb_recv_datagram and unix_stream_data_wait.

So what does this "Waiting Channel" column mean? And perhaps what do some of those values in it mean?

Screenshot


The waiting channel is the place in the Kernel where the task is currently waiting. A task has to wait for a Resource, which can be data or processing time. These two include network sockets, hardware, files, and so on; since most of them are just files, in Unix-like systems.

  • 0: The process isn't waiting

  • poll_schedule_timeout

    poll() is a system call1 used to handle I/O. It's similar to select().2

    Applications that use non-blocking I/O use these calls to see if they can read from or write to a file, withouth having to block it. They are often used for input/output streams, which may not be blocked (otherwise, perhaps your mouse would stop to move).

    The waiting channel poll_schedule_timeout indicates that a task is waiting for I/O, either hardware like keyboards and mice, sound devices or even network sockets.

    1. A function in the Kernel
    2. They are defined in <linux/poll.h>. poll was an implementation first seen in System V, select is the BSD UNIX equivalent.
  • futex_wait_queue_me:

    To explain this, we have to look at Locks. A lock is a saved state in the system that indicates that a task works with a resource. There can be, for example, only one task that reads a file. This task would lock the file, any other task1 that tries to read the file would know it's locked, and wait for the lock to go away, before it can access it. The same thing happens for processor time.

    Modern version of Linux (on most architectures) use a Futex (fast userspace mutex) lock in the kernel. Mutex, mutual exclusion, refers to the idea that a common resource can only be accessed by one task at any time. For this, flags in the system are set.

    If a process is waiting for a locked resource, this is called Busy Waiting or "Spinning", refering to the fact that it tries to access it over and over, until it can. A task is said to be blocked when it spins.

    If you can read this, you are obligated to correct at least one mistake in this answer :P

    Futex locks can be thought of as a number in userspace, that can be incremented or decremented by a task (in cases where the resource can be accessed by multiple tasks, this number can become greater than one). This is the number shown in the diagram4.

    These tasks enqueue themselves in the wait queue, a simple queue of tasks that need to do some work, once processing time is available, the tasks do their work and are removed from the queue.

    futex_wait_queue_me enqueues a tasks. It then waits for a signal, a time out or a wakeup. Task that are in this waiting channel are waiting not on the wait queue, they are waiting to be enqueued.


    1. A task can be either a Process3 or a Thread2
    2. A Thread is a sub-section of a Process. Many threads can run parallel
    3. A process is a full-blown program, it consists of one or more threads, though a program can consist of multiple processes as well.
    4. Remember, this is still a very high level view of things, it's not considering the implementation details
  • __skb_recv_datagram

    Wait for some data on a locked network socket.

  • sk_wait_data

    Wait for some data on a network socket.

  • do_exit

    This is the last part of quitting a process. do_exit() calls the schedule() next, to schedule another process. When do_exit() is called, the process is a ZOMBIE.

  • do_wait

    A process is added to the schedulers wait queue.

  • pipe_wait, unix_stream_data_wait

    A Process is waiting for data from a subprocess. This happens, for example, when you run this sort of code:

    echo | sleep 10 && echo hallo              # pipe
    

    or

    cat < hello.c                              # unix data stream
    
  • hrtimer_nanosleep

    The process is sleeping, using the hrtimer_nanosleep() method. This method can be used for a program to sleep for specific intervals of time, with nanosecond accuracy.

These aren't all, but I didn't observe any others. Post a comment if I've missed anything.


The waiting channel value is the name of the kernel function in which the process is currently blocked.

The name is usually related to a system call, which will have a manual page.

  • futex_wait_queue_me is related to futex. It refers to a type of mutex lock (fast userspace mutual exclusion) that is used to schedule many processes work on one processor. The state indicates that your process is enqueued to receive the lock. 2
  • do_wait is related to wait.
  • etc.

If you really want more detailed information you could check the kernel source.

If you type cat /proc/some_pid/stack in a terminal you'll get some output like that one :

[<c0227f4e>] poll_schedule_timeout+0x3e/0x60
[<c022879f>] do_select+0x55f/0x670
[<c0228f40>] core_sys_select+0x140/0x240
[<c0229241>] sys_select+0x31/0xc0
[<c05c9cc4>] syscall_call+0x7/0xb
[<ffffffff>] 0xffffffff

And on the first line you get what's displayed on the system monitor. As far as I know, poll_schedule_timeout indicates that your process is waiting for something.

It deals with asynchronous I/O and polling.

Source(s) : 1. process wait channel (WCHAN) and alarm? - 2. AskUbuntu answer