summaryrefslogtreecommitdiffstats
path: root/usr.bin/top
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2007-06-15 12:03:07 +0000
committerbde <bde@FreeBSD.org>2007-06-15 12:03:07 +0000
commitc00ecb1e06d1c2e24baea6076a20945eaa7b837b (patch)
tree2f13781d7ecb4d2b975d90082b7534400ea2b6bd /usr.bin/top
parent73c6fd823f55ad9b3332da2e2e97404fd7abb290 (diff)
downloadFreeBSD-src-c00ecb1e06d1c2e24baea6076a20945eaa7b837b.zip
FreeBSD-src-c00ecb1e06d1c2e24baea6076a20945eaa7b837b.tar.gz
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).
Diffstat (limited to 'usr.bin/top')
-rw-r--r--usr.bin/top/machine.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c
index 083055f..b7e03f4 100644
--- a/usr.bin/top/machine.c
+++ b/usr.bin/top/machine.c
@@ -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;
OpenPOWER on IntegriCloud