htop icon indicating copy to clipboard operation
htop copied to clipboard

Invalid NICE value on FreeBSD

Open vchimishuk opened this issue 2 years ago • 2 comments

On FreeBSD htop displays weird nice (NI column) values for some processes. Here are three rows which looks invalid to me.

  PID USER       PRI  NI  VIRT   RES S  CPU%▽MEM%   TIME+  Command                                                                                             
   11 root       187  52     0    64 R 395.1  0.0 26h53:03 idle                                                                                                
    2 root       -60 -195     0    64 W   0.0  0.0  0:03.39 clock
    5 root       -60 -195     0    16 S   0.0  0.0  0:00.00 busdma

As you can see their nice value out of range. htop's man page says:

The nice value of a process, from 19 (low priority) to -20 (high priority).

getpriority(2) says almost the same

The prio argument is a value in the range -20 to 20.

So, displayed values are out of range which nice can have.

I've checked htop's source code and can see it does some weird calculations over nice value. Not sure why do we need this code at all, getpriority(2) should return ready to be displayed value.

      if (String_eq("intr", kproc->ki_comm) && (kproc->ki_flag & P_SYSTEM)) {
         proc->nice = 0; //@etosan: intr kernel process (not thread) has weird nice value
      } else if (kproc->ki_pri.pri_class == PRI_TIMESHARE) {
         proc->nice = kproc->ki_nice - NZERO;
      } else if (PRI_IS_REALTIME(kproc->ki_pri.pri_class)) {
         proc->nice = PRIO_MIN - 1 - (PRI_MAX_REALTIME - kproc->ki_pri.pri_level);
      } else {
         proc->nice = PRIO_MAX + 1 + kproc->ki_pri.pri_level - PRI_MIN_IDLE;
      }

https://github.com/htop-dev/htop/blob/main/freebsd/FreeBSDProcessTable.c#L251

top from FreeBSD base displays - in nice column for kernel processes. Should htop follows the same behavior?

vchimishuk avatar Feb 10 '24 23:02 vchimishuk

I think the values technically make sense: The idle process has the lowest priority (i.e. when nothing else can run) while the kernel processes below it have the highest priorities available to immediately run whenever there's work to do.

Also, why hide them? The wording in the documentation could be refined to include the word "usually" before the range. Furthermore the display of the column could be fixed to avoid breakage with these extreme priorities.

BenBE avatar Feb 12 '24 09:02 BenBE

Also, why hide them?

Because it shows some synthetic priority now -- not nice value. And it is even hard to say what the value is. PRI column should be displaying scheduling priority, but they do not match now. I haven't dug into details, but it looks like Linux uses nice value internally for kernel threads but FreeBSD doesn't, what makes their top's output different: - on FreeBSD and some -20..19 value on Linux.

The wording in the documentation could be refined to include the word "usually" before the range.

Do you mean htop's documentation? In this case nice in htop and nice in UNIX-wide sense will not match, it will matter completely different things. Because nice in UNIX cannot be out of -20..19 range.

My understanding is:

  • htop tries to display (calculate manually) process' internal priority instead of nice value. It duplicates PRI column in this sense. And it does it only on FreeBSD and only for some processes (kernel threads without nice value).
  • I'd expect values in top and htop to be equal.
  • nice is not applicable for FreeBSD kernel threads.

vchimishuk avatar Feb 12 '24 10:02 vchimishuk