On Sun, Jun 18, 2023 at 12:36:07PM -0500, Scott Cheloha wrote:
> On Sun, Jun 18, 2023 at 07:32:56PM +0200, Mark Kettenis wrote:
> > > Date: Sun, 18 Jun 2023 12:27:17 -0500
> > > From: Scott Cheloha <scottchel...@gmail.com>
> > > 
> > > 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?
> > 
> > I really don't see why the calculatin of something vague like the load
> > average warrants complicating the code like this.
> 
> Aren't load averages used to make decisions about thread placement in
> the scheduler?
> 
> Regardless, the code is still wrong.  At minimum you should use
> getuptime(9).

Maybe I misunderstood.  Are you suggesting this?


        now = getuptime();
        if (now >= next_uvm_loadav) {
                next_uvm_loadav = now + 5;
                uvm_loadav(...);
        }

The patch I posted preserves the current behavior.  It is equivalent
to:

        while (next_uvm_loadav <= now)
                next_uvm_loadav += 5;

Changing it to (now + 5) changes the behavior.

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