9.1 callout behavior
Adrian Chadd
adrian at freebsd.org
Wed Sep 17 00:53:54 UTC 2014
On 16 September 2014 17:38, Adrian Chadd <adrian at freebsd.org> wrote:
> So, it did show up even if I say to run the callout on cpu #0 - any
> kind of load on that CPU and that callwheel still gets run on another
> CPU.
>
> What I next did was compile up KTR:
>
> include GENERIC
> ident TESTING
> options KTR
> options ALQ
> options KTR_ALQ
> options KTR_COMPILE=0xffffffff
>
> .. then enable KTR_CALLOUT, and I see:
>
> 4175 0 884780740167480 precision set for 0xffffffff818194f8: 0.01999997
> 4174 0 884780667893634 callout lock 0xffffffff818194f8 func
> 0xffffffff818191d0 arg 0xffffffff818194f8
> 4149 0 884780455441940 callout 0xffffffff818194f8 finished
> 4148 0 884780455441414 scheduled 0xffffffff818194f8 func
> 0xffffffff818191d0 arg 0xffffffff818194f8 in 561.4a5c984a
> 4147 0 884780455440600 precision set for 0xffffffff818194f8: 0.01999997
> 4132 0 884780373374060 callout lock 0xffffffff818194f8 func
> 0xffffffff818191d0 arg 0xffffffff818194f8
> 4103 0 884780170731868 callout 0xffffffff818194f8 finished
> 4102 0 884780170731468 scheduled 0xffffffff818194f8 func
> 0xffffffff818191d0 arg 0xffffffff818194f8 in 561.25c0f291
> 4101 0 884780170730948 precision set for 0xffffffff818194f8: 0.01999997
> 4086 0 884780089391348 callout lock 0xffffffff818194f8 func
> 0xffffffff818191d0 arg 0xffffffff818194f8
> 4058 0 884779886019688 callout 0xffffffff818194f8 finished
>
> .. and those 561.xxxx values are sbintime values.
>
> The delta looks like it's ~ 142mS, which is in line with what your
> callout routine reports. So the math to calculate the "next" event is
> bumping it along to that value instead of 100mS.
>
> I'm going to update one of these boxes to -HEAD and see if it's still
> a problem there.
So the test case uses callout_reset(), which is the "older" way of doing it.
What callout_reset() does is:
* convert to sbintime_t;
* set the callout precision to 0;
* set C_HARDCLOCK.
Now, C_HARDCLOCK doesn't read the last clock - it reads the last
per-cpu clock value. I have no idea if PCPU_GET(hardclocktime) is
_actually_ going to be equal across all CPUs - and boy if it isn't I'm
not going to fix it - but the point here is it's not going to be
updated very often when the system is idle and not receiving many
interrupts.
When I change the code to use callout_reset_sbt():
callout_reset_sbt(&cp->co, (SBT_1S * 100) / 1000, 0,
ticktock_callback, cp, 0);
.. and
callout_reset_sbt(&c.co, (SBT_1S * 100) / 1000, 0,
ticktock_callback, &c, 0);
To fire at the same interval that you did (hz / 10; so 100mS) then it
worked out perfectly fine.
-a
More information about the freebsd-hackers
mailing list