Unrecognized process state output in ps command

processps

Running ps aux in an Ubuntu 18.04 I see some processes having state I, as in…

root         1  0.0  0.0 225520  9144 ?        Ss   10:36   0:02 /sbin/init splash
root         2  0.0  0.0      0     0 ?        S    10:36   0:00 [kthreadd]
root         4  0.0  0.0      0     0 ?        I<   10:36   0:00 [kworker/0:0H]
root         6  0.0  0.0      0     0 ?        I<   10:36   0:00 [mm_percpu_wq]

However this state is not mentioned in ps manpages:

PROCESS STATE CODES
Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state
of a process:

           D    uninterruptible sleep (usually IO)
           R    running or runnable (on run queue)
           S    interruptible sleep (waiting for an event to complete)
           T    stopped by job control signal
           t    stopped by debugger during the tracing
           W    paging (not valid since the 2.6.xx kernel)
           X    dead (should never be seen)
           Z    defunct ("zombie") process, terminated but not reaped by its parent

   For BSD formats and when the stat keyword is used, additional characters may be displayed:

           <    high-priority (not nice to other users)
           N    low-priority (nice to other users)
           L    has pages locked into memory (for real-time and custom IO)
           s    is a session leader
           l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
           +    is in the foreground process group

What is this I state?

Best Answer

It means "Idle"

    /* states beyond TASK_REPORT: */
    "I (idle)",             /* 0x80 */
Reference: What does Linux process state "I" mean in the top output?

Digging more in kernel sources I found that the record for I is TASK_REPORT_IDLE, which is returned from kernel guts (function __get_task_state) when process has status TASK_IDLE, which in fact is a combination of

#define TASK_IDLE   (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)

Also, see this commit to the kernel titled: sched/wait: Introduce TASK_NOLOAD and TASK_IDLE.

Currently people use TASK_INTERRUPTIBLE to idle kthreads and wait for 'work' because TASK_UNINTERRUPTIBLE contributes to the loadavg. Having all idle kthreads contribute to the loadavg is somewhat silly.

Now mostly this works OK, because kthreads have all their signals masked. However there's a few sites where this is causing problems and TASK_UNINTERRUPTIBLE should be used, except for that loadavg issue.

This patch adds TASK_NOLOAD which, when combined with TASK_UNINTERRUPTIBLE avoids the loadavg accounting.

As most of imagined usage sites are loops where a thread wants to idle, waiting for work, a helper TASK_IDLE is introduced.

NOTE: This appears to have been added to the Linux kernel in 4.14-rc3:

sched/debug: Add explicit TASK_IDLE printing

/proc

Given this is coming from the Linux kernel, downstream tools such as ps and top immediately can display this new state, I, without having to be explicitly told, since they derive their information from /proc.

You can see a /proc's state via the /proc/<PID>/stat:

$ cat /proc/10/stat
10 (lru-add-drain) S 2 0 0 0 -1 69247072 ....
                   ^--- state = S = Sleep

References

Related Question