Third stage of unbreaking printing of pseudo-nice values (realtime
priorities, etc.) in the NICE field: Use a combination of pri_native and pri_user instead of pri_level to guess the original realtime priority. Using pri_level here has been wrong since 2001/02/12. Using only pri_native here would be correct if the kernel actually initialized it reasonably. (The kernel exports its raw td_base_priority as pri_native, but userland mostly wants a refined base priority). Give up on waiting pri_native to work correctly and only use it when there is nothing better (for kthreads). This should reduce printing of bizarre pseudo-nice values. Bizarre values are still printed if we observe a transient borrowed priority for a kthread (transient borrowing is the main thing that makes the raw td_base_priority almost useless in userland), or if there is a kernel bug. One current kernel bug involves the kernel idprio thread pagezero permanently changing its priority from PRI_MAX_IDLE (255) to PUSER (160). Then the bizarre value "ki-6" is printed instead of "ki31". Here "-6" is PRI_MIN_IDLE - PUSER = -64 truncated to 2 characters. We are observing a transient borrowed priority that has become permanent due to a bug. ps/print.c:priorityr() needs similar changes (including ones in stage 2 here).
This commit is contained in:
parent
553284d74a
commit
e19249f7a7
@ -892,7 +892,28 @@ format_nice(const struct kinfo_proc *pp)
|
||||
case PRI_ITHD:
|
||||
return ("-");
|
||||
case PRI_REALTIME:
|
||||
rtpri = pp->ki_pri.pri_level - PRI_MIN_REALTIME;
|
||||
/*
|
||||
* XXX: the kernel doesn't tell us the original rtprio and
|
||||
* doesn't really know what it was, so to recover it we
|
||||
* must be more chummy with the implementation than the
|
||||
* implementation is with itself. pri_user gives a
|
||||
* constant "base" priority, but is only initialized
|
||||
* properly for user threads. pri_native gives what the
|
||||
* kernel calls the "base" priority, but it isn't constant
|
||||
* since it is changed by priority propagation. pri_native
|
||||
* also isn't properly initialized for all threads, but it
|
||||
* is properly initialized for kernel realtime and idletime
|
||||
* threads. Thus we use pri_user for the base priority of
|
||||
* user threads (it is always correct) and pri_native for
|
||||
* the base priority of kernel realtime and idletime threads
|
||||
* (there is nothing better, and it is usually correct).
|
||||
*
|
||||
* The field width and thus the buffer are too small for
|
||||
* values like "kr31F", but such values shouldn't occur,
|
||||
* and if they do then the tailing "F" is not displayed.
|
||||
*/
|
||||
rtpri = ((pp->ki_flag & P_KTHREAD) ? pp->ki_pri.pri_native :
|
||||
pp->ki_pri.pri_user) - PRI_MIN_REALTIME;
|
||||
snprintf(nicebuf, sizeof(nicebuf), "%sr%d%s",
|
||||
kthread, rtpri, fifo);
|
||||
break;
|
||||
@ -902,7 +923,9 @@ format_nice(const struct kinfo_proc *pp)
|
||||
snprintf(nicebuf, sizeof(nicebuf), "%d", pp->ki_nice - NZERO);
|
||||
break;
|
||||
case PRI_IDLE:
|
||||
rtpri = pp->ki_pri.pri_level - PRI_MIN_IDLE;
|
||||
/* XXX: as above. */
|
||||
rtpri = ((pp->ki_flag & P_KTHREAD) ? pp->ki_pri.pri_native :
|
||||
pp->ki_pri.pri_user) - PRI_MIN_IDLE;
|
||||
snprintf(nicebuf, sizeof(nicebuf), "%si%d%s",
|
||||
kthread, rtpri, fifo);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user