On Thu, Aug 03, 2023 at 10:13:57AM +0200, Martin Pieuchot wrote:
> On 02/08/23(Wed) 14:22, Claudio Jeker wrote:
> > On Mon, Jul 31, 2023 at 10:21:11AM -0500, Scott Cheloha wrote:
> > > On Fri, Jul 28, 2023 at 07:36:41PM -0500, Scott Cheloha wrote:
> > > > claudio@ notes that uvm_loadav() pointlessly walks the allproc list to
> > > > recompute schedstate_percpu.spn_nrun for each CPU.
> > > > 
> > > > We can just use the value instead of recomputing it.
> > > 
> > > Whoops, off-by-one.  The current load averaging code includes the
> > > running thread in the nrun count if it is *not* the idle thread.
> > 
> > Yes, with this the loadavg seems to be consistent and following the number
> > of running processes. The code seems to behave like before (with all its
> > quirks).
> > 
> > OK claudio@, this is a good first step. Now I think this code should later
> > be moved into kern_sched.c or sched_bsd.c and removed from uvm. Not sure why
> > the load calculation is part of memory management...
> > 
> > On top of this I wonder about the per-CPU load calculation. In my opinion
> > it is wrong to skip the calculation if the CPU is idle. Because of this
> > there is no decay for idle CPUs and that feels wrong to me.
> > Do we have a userland utility that reports spc_ldavg?
> 
> I don't understand why the SCHED_LOCK() is needed.  Since I'm really
> against adding new uses for it, could you comment on that?

The question is how sloppy do we want to be. This code looks at
ci_schedstate (spc_idleproc and spc_nrun) and ci_curproc so the be correct
this needs to lock the scheduler. Do we really want that, hell no.
 
> > > Index: uvm_meter.c
> > > ===================================================================
> > > RCS file: /cvs/src/sys/uvm/uvm_meter.c,v
> > > retrieving revision 1.44
> > > diff -u -p -r1.44 uvm_meter.c
> > > --- uvm_meter.c   21 Jun 2023 21:16:21 -0000      1.44
> > > +++ uvm_meter.c   31 Jul 2023 15:20:37 -0000
> > > @@ -102,43 +102,29 @@ uvm_loadav(struct loadavg *avg)
> > >  {
> > >   CPU_INFO_ITERATOR cii;
> > >   struct cpu_info *ci;
> > > - int i, nrun;
> > > - struct proc *p;
> > > - int nrun_cpu[MAXCPUS];
> > > + struct schedstate_percpu *spc;
> > > + u_int i, nrun = 0, nrun_cpu;
> > > + int s;
> > >  
> > > - nrun = 0;
> > > - memset(nrun_cpu, 0, sizeof(nrun_cpu));
> > >  
> > > - LIST_FOREACH(p, &allproc, p_list) {
> > > -         switch (p->p_stat) {
> > > -         case SSTOP:
> > > -         case SSLEEP:
> > > -                 break;
> > > -         case SRUN:
> > > -         case SONPROC:
> > > -                 if (p == p->p_cpu->ci_schedstate.spc_idleproc)
> > > -                         continue;
> > > -         /* FALLTHROUGH */
> > > -         case SIDL:
> > > -                 nrun++;
> > > -                 if (p->p_cpu)
> > > -                         nrun_cpu[CPU_INFO_UNIT(p->p_cpu)]++;
> > > -         }
> > > + SCHED_LOCK(s);
> > > + CPU_INFO_FOREACH(cii, ci) {
> > > +         spc = &ci->ci_schedstate;
> > > +         nrun_cpu = spc->spc_nrun;
> > > +         if (ci->ci_curproc != spc->spc_idleproc)
> > > +                 nrun_cpu++;
> > > +         if (nrun_cpu == 0)
> > > +                 continue;
> > > +         spc->spc_ldavg = (cexp[0] * spc->spc_ldavg +
> > > +             nrun_cpu * FSCALE *
> > > +             (FSCALE - cexp[0])) >> FSHIFT;
> > > +         nrun += nrun_cpu;
> > >   }
> > > + SCHED_UNLOCK(s);
> > >  
> > >   for (i = 0; i < 3; i++) {
> > >           avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
> > >               nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
> > > - }
> > > -
> > > - CPU_INFO_FOREACH(cii, ci) {
> > > -         struct schedstate_percpu *spc = &ci->ci_schedstate;
> > > -
> > > -         if (nrun_cpu[CPU_INFO_UNIT(ci)] == 0)
> > > -                 continue;
> > > -         spc->spc_ldavg = (cexp[0] * spc->spc_ldavg +
> > > -             nrun_cpu[CPU_INFO_UNIT(ci)] * FSCALE *
> > > -             (FSCALE - cexp[0])) >> FSHIFT;
> > >   }
> > >  }
> > >  
> > 
> > -- 
> > :wq Claudio
> > 
> 

-- 
:wq Claudio

Reply via email to