The intent here is to update the load averages every five seconds.
However:

1. Measuring elapsed time with the UTC clock is unreliable because of
   settimeofday(2).

2. "Call uvm_loadav() no more than once every five seconds", is not
    equivalent to "call uvm_loadav() if the current second is equal
    to zero, modulo five".

   Not hard to imagine edge cases where timeouts are delayed and
   the load averages are not updated.

So, (1) use the monotonic clock, and (2) keep the next uvm_loadav()
call time in a static value.

ok?

Index: uvm_meter.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_meter.c,v
retrieving revision 1.42
diff -u -p -r1.42 uvm_meter.c
--- uvm_meter.c 28 Dec 2020 14:01:23 -0000      1.42
+++ uvm_meter.c 18 Jun 2023 17:11:09 -0000
@@ -87,8 +87,16 @@ void uvmexp_read(struct uvmexp *);
 void
 uvm_meter(void)
 {
-       if ((gettime() % 5) == 0)
+       static time_t next_uvm_loadav;
+       time_t intvl_count, now;
+
+       now = getuptime();
+       if (now >= next_uvm_loadav) {
+               intvl_count = (now - next_uvm_loadav) / 5 + 1;
+               next_uvm_loadav += 5 * intvl_count;
                uvm_loadav(&averunnable);
+       }
+
        if (proc0.p_slptime > (maxslp / 2))
                wakeup(&proc0);
 }

Reply via email to