On Mon, Aug 14, 2017 at 3:07 PM Martin Pieuchot <m...@openbsd.org> wrote:
>
> I'd like to improve the fairness of the scheduler, with the goal of
> mitigating userland starvations.  For that the kernel needs to have
> a better understanding of the amount of executed time per task.
>
> The smallest interval currently usable on all our architectures for
> such accounting is a tick.  With the current HZ value of 100, this
> smallest interval is 10ms.  I'd like to bump this value to 1000.
>
> The diff below intentionally bump other `hz' value to keep current
> ratios.  We certainly want to call schedclock(), or a similar time
> accounting function, at a higher frequency than 16 Hz.  However this
> will be part of a later diff.
>
> I'd be really interested in test reports.  mlarkin@ raised a good
> question: is your battery lifetime shorter with this diff?
>
> Comments, oks?
>

I'd like to revisit this patch. It makes our armv7 platform more
usable for what it is meant to do, i.e. be a microcontroller. I
imagine on other platforms it would accrue similar benefits as well.

I've tested this patch and found delightfully proportional results.
Currently, at HZ = 100, the minimum latency for a sleep calll from
userspace is about 10ms:

https://ce.gl/baseline.jpg

After the patch, which bumps HZ from 100 --> 1000, we see a tenfold
decrease in this latency:

https://ce.gl/with-mpi-hz-patch.jpg

This signal is generated with gpio(4) ioctl calls from userspace,
e.g.: for(;;) { HI(pin); usleep(1); LO(pin(); usleep(1); }

I'd like to see more folks test and other devs to share their
thoughts: What are the risks associated with bumping HZ globally?
Drawbacks? Reasons for hesitation?

Thanks,
Ian Sutton



> Index: conf/param.c
> ===================================================================
> RCS file: /cvs/src/sys/conf/param.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 param.c
> --- conf/param.c        6 May 2016 19:45:35 -0000       1.37
> +++ conf/param.c        14 Aug 2017 17:03:23 -0000
> @@ -76,7 +76,7 @@
>  # define DST 0
>  #endif
>  #ifndef HZ
> -#define        HZ 100
> +#define        HZ 1000
>  #endif
>  int    hz = HZ;
>  int    tick = 1000000 / HZ;
> Index: kern/kern_clock.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_clock.c,v
> retrieving revision 1.93
> diff -u -p -r1.93 kern_clock.c
> --- kern/kern_clock.c   22 Jul 2017 14:33:45 -0000      1.93
> +++ kern/kern_clock.c   14 Aug 2017 19:50:49 -0000
> @@ -406,12 +406,11 @@ statclock(struct clockframe *frame)
>         if (p != NULL) {
>                 p->p_cpticks++;
>                 /*
> -                * If no schedclock is provided, call it here at ~~12-25 Hz;
> +                * If no schedclock is provided, call it here;
>                  * ~~16 Hz is best
>                  */
>                 if (schedhz == 0) {
> -                       if ((++curcpu()->ci_schedstate.spc_schedticks & 3) ==
> -                           0)
> +                       if ((spc->spc_schedticks & 0x3f) == 0)
>                                 schedclock(p);
>                 }
>         }
> Index: arch/amd64/isa/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/isa/clock.c,v
> retrieving revision 1.25
> diff -u -p -r1.25 clock.c
> --- arch/amd64/isa/clock.c      11 Aug 2017 21:18:11 -0000      1.25
> +++ arch/amd64/isa/clock.c      14 Aug 2017 17:19:35 -0000
> @@ -303,8 +303,8 @@ rtcdrain(void *v)
>  void
>  i8254_initclocks(void)
>  {
> -       stathz = 128;
> -       profhz = 1024;
> +       stathz = 1024;
> +       profhz = 8192;
>
>         isa_intr_establish(NULL, 0, IST_PULSE, IPL_CLOCK, clockintr,
>             0, "clock");
> @@ -321,7 +321,7 @@ rtcstart(void)
>  {
>         static struct timeout rtcdrain_timeout;
>
> -       mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_128_Hz);
> +       mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_1024_Hz);
>         mc146818_write(NULL, MC_REGB, MC_REGB_24HR | MC_REGB_PIE);
>
>         /*
> @@ -577,10 +577,10 @@ setstatclockrate(int arg)
>         if (initclock_func == i8254_initclocks) {
>                 if (arg == stathz)
>                         mc146818_write(NULL, MC_REGA,
> -                           MC_BASE_32_KHz | MC_RATE_128_Hz);
> +                           MC_BASE_32_KHz | MC_RATE_1024_Hz);
>                 else
>                         mc146818_write(NULL, MC_REGA,
> -                           MC_BASE_32_KHz | MC_RATE_1024_Hz);
> +                           MC_BASE_32_KHz | MC_RATE_8192_Hz);
>         }
>  }
>
> Index: arch/armv7/omap/dmtimer.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/armv7/omap/dmtimer.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 dmtimer.c
> --- arch/armv7/omap/dmtimer.c   22 Jan 2015 14:33:01 -0000      1.6
> +++ arch/armv7/omap/dmtimer.c   14 Aug 2017 17:16:01 -0000
> @@ -296,8 +296,8 @@ dmtimer_cpu_initclocks()
>  {
>         struct dmtimer_softc    *sc = dmtimer_cd.cd_devs[1];
>
> -       stathz = 128;
> -       profhz = 1024;
> +       stathz = 1024;
> +       profhz = 8192;
>
>         sc->sc_ticks_per_second = TIMER_FREQUENCY; /* 32768 */
>
> Index: arch/armv7/omap/gptimer.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/armv7/omap/gptimer.c,v
> retrieving revision 1.4
> diff -u -p -r1.4 gptimer.c
> --- arch/armv7/omap/gptimer.c   20 Jun 2014 14:08:11 -0000      1.4
> +++ arch/armv7/omap/gptimer.c   14 Aug 2017 17:15:44 -0000
> @@ -283,8 +283,8 @@ void
>  gptimer_cpu_initclocks()
>  {
>  //     u_int32_t now;
> -       stathz = 128;
> -       profhz = 1024;
> +       stathz = 1024;
> +       profhz = 8192;
>
>         ticks_per_second = TIMER_FREQUENCY;
>
> Index: arch/armv7/sunxi/sxitimer.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/armv7/sunxi/sxitimer.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 sxitimer.c
> --- arch/armv7/sunxi/sxitimer.c 21 Jan 2017 08:26:49 -0000      1.10
> +++ arch/armv7/sunxi/sxitimer.c 14 Aug 2017 17:15:04 -0000
> @@ -189,9 +189,8 @@ sxitimer_attach(struct device *parent, s
>         bus_space_write_4(sxitimer_iot, sxitimer_ioh,
>             TIMER_CTRL(STATTIMER), TIMER_OSC24M);
>
> -       /* 100/1000 or 128/1024 ? */
> -       stathz = 128;
> -       profhz = 1024;
> +       stathz = 1024;
> +       profhz = 8192;
>         sxitimer_setstatclockrate(stathz);
>
>         ival = sxitimer_stat_tpi = freq / stathz;
> Index: arch/i386/isa/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/i386/isa/clock.c,v
> retrieving revision 1.51
> diff -u -p -r1.51 clock.c
> --- arch/i386/isa/clock.c       25 Jan 2017 08:23:50 -0000      1.51
> +++ arch/i386/isa/clock.c       14 Aug 2017 17:19:18 -0000
> @@ -226,8 +226,8 @@ rtcintr(void *arg)
>         if (stathz == 0) {
>                 extern int psratio;
>
> -               stathz = 128;
> -               profhz = 1024;
> +               stathz = 1024;
> +               profhz = 8192;
>                 psratio = profhz / stathz;
>         }
>
> @@ -448,7 +448,7 @@ rtcstart(void)
>  {
>         static struct timeout rtcdrain_timeout;
>
> -       mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_128_Hz);
> +       mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_1024_Hz);
>         mc146818_write(NULL, MC_REGB, MC_REGB_24HR | MC_REGB_PIE);
>
>         /*
> @@ -698,10 +698,10 @@ setstatclockrate(int arg)
>         if (initclock_func == i8254_initclocks) {
>                 if (arg == stathz)
>                         mc146818_write(NULL, MC_REGA,
> -                           MC_BASE_32_KHz | MC_RATE_128_Hz);
> +                           MC_BASE_32_KHz | MC_RATE_1024_Hz);
>                 else
>                         mc146818_write(NULL, MC_REGA,
> -                           MC_BASE_32_KHz | MC_RATE_1024_Hz);
> +                           MC_BASE_32_KHz | MC_RATE_8192_Hz);
>         }
>  }
>
> Index: arch/loongson/dev/glx.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/loongson/dev/glx.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 glx.c
> --- arch/loongson/dev/glx.c     15 Aug 2015 22:25:22 -0000      1.10
> +++ arch/loongson/dev/glx.c     14 Aug 2017 17:06:05 -0000
> @@ -124,7 +124,7 @@ glx_init(pci_chipset_tag_t pc, pcitag_t
>         /*
>          * MFGPT runs on powers of two, adjust the hz value accordingly.
>          */
> -       stathz = hz = 128;
> +       stathz = hz = 1024;
>  }
>
>  uint64_t
> Index: arch/macppc/macppc/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/macppc/clock.c,v
> retrieving revision 1.40
> diff -u -p -r1.40 clock.c
> --- arch/macppc/macppc/clock.c  13 Jun 2015 07:16:36 -0000      1.40
> +++ arch/macppc/macppc/clock.c  14 Aug 2017 17:13:15 -0000
> @@ -302,8 +302,8 @@ cpu_initclocks()
>
>         ticks_per_intr = ticks_per_sec / hz;
>
> -       stathz = 100;
> -       profhz = 1000; /* must be a multiple of stathz */
> +       stathz = 1000;
> +       profhz = 10000; /* must be a multiple of stathz */
>
>         /* init secondary clock to stathz */
>         statint = ticks_per_sec / stathz;
> Index: arch/sparc64/sparc64/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc64/sparc64/clock.c,v
> retrieving revision 1.59
> diff -u -p -r1.59 clock.c
> --- arch/sparc64/sparc64/clock.c        30 Apr 2017 16:45:45 -0000      1.59
> +++ arch/sparc64/sparc64/clock.c        14 Aug 2017 20:00:26 -0000
> @@ -647,8 +647,8 @@ cpu_initclocks(void)
>         if (stathz == 0)
>                 stathz = hz;
>         if (1000000 % stathz) {
> -               printf("cannot get %d Hz statclock; using 100 Hz\n", stathz);
> -               stathz = 100;
> +               printf("cannot get %d Hz statclock; using 1000 Hz\n", stathz);
> +               stathz = 1000;
>         }
>
>         profhz = stathz;                /* always */
> @@ -665,7 +665,7 @@ cpu_initclocks(void)
>         schedint.ih_clr = NULL;
>         schedint.ih_arg = 0;
>         schedint.ih_pending = 0;
> -       schedhz = stathz/4;
> +       schedhz = 16;
>
>         /*
>          * Enable timers
> @@ -867,7 +867,7 @@ statintr(cap)
>         newint = statmin + r;
>
>         if (schedhz)
> -               if ((++ci->ci_schedstate.spc_schedticks & 3) == 0)
> +               if ((++ci->ci_schedstate.spc_schedticks & 0x3f) == 0)
>                         send_softint(-1, PIL_SCHED, &schedint);
>         stxa((vaddr_t)&timerreg_4u.t_timer[1].t_limit, ASI_NUCLEUS,
>              tmr_ustolim(newint)|TMR_LIM_IEN|TMR_LIM_RELOAD);
>

Reply via email to