Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 3 Sep 2016 16:41:58 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        John Baldwin <jhb@freebsd.org>
Cc:        FreeBSD-arch Arch <freebsd-arch@freebsd.org>
Subject:   Re: pause_ms() wrapper
Message-ID:  <20160903152718.O1061@besplex.bde.org>
In-Reply-To: <2960854.iLOY0Gxipb@ralph.baldwin.cx>
References:  <2960854.iLOY0Gxipb@ralph.baldwin.cx>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 2 Sep 2016, John Baldwin wrote:

> Figuring out the 3 arguments required for pause_sbt() can be a bit
> non-obvious (at least to me).  To that end, I'd like to have a simple
> wrapper around pause_sbt() that accepts milliseconds.  It would align
> itself on hardclock similar to the hz-based wrapper.  OTOH, we could
> change the implementation at some point to use something more resaonable
> in terms of precision, etc.  However, most of the time when I want to
> sleep for N milliseconds (or N microseconds) due to some hardware spec,
> I don't really have a strong opinion on the precision.  Having all the
> callers try to figure out a precision would seem to inevitably result
> in inconsistencies.  To start with I'd like to just add this:

I complained to mav about the difficult of controlling precision.  The
defaults work poorly.  There are too many too complicated options to
override the defaults, but not enough not complicated enough to do what
I want.  E.g., the 5% default error is too large for long timeouts,
but there is no way to reduce it for long timeouts -- the options only
allow you to increase it further.

> #define	pause_ms(wmesg, msecs)						\
> 	pause_sbt((wmesg), SBT_1MS * (msecs), 0, C_HARDCLOCK)

Here C_HARDCLOCK is supposed to give compatibility with old periodic
hardclock.  It doesn't do that.  With a requested timeout of n ticks,
old periodic hardclock gives a timeout of 1 fractional ticks (average
1/2) and n-1 full ticks and it was possible to sync with or predict
when the ticks would occur and adjust n up or down by 1 to compenstae
the fractional tick.  C_HARDCLOCK with a requested timeout of n ticks
gives a timeout of at least n ticks, extended by the system's best attempt
to not much more than N%, where N defaults to 5 but can be changed by the
sysadmin.  This magic 5 and the sysctl are not documented in any man page.

Often, 5% is much more accuracy that needed, but asking for less is
even more complicated than asking for more.  First you have to do
something to avoid the default having precedence.  For some APIs,
C_HARDCLOCK is the default 'flags' is 0, so you have to use C_PREL()
to avoid it.  C_PREL(32) gives a tiny percentages so allows the 'pr'
parameter (0 here) to dominate.  The 2 precision parameters mostly
give complications by getting in each other's way.

> Which you can use as 'pause_ms("pcieflr", 100);'.
>
> Are there any objections?  Do people want other wrappers?  Should we
> use more nuanced math similar to what was done in r296775?

There should also be a wrapper for the usual case of setting up a callout,
with a good name like "timeout".  callout_reset() was already too
complicated and badly named (it is more related to times than calls,
and more related to [re]starting than resetting (clearing)).  But it is
trivial compared with callout_reset_sbt_on().

I don't actually like the macro.  Most callout functions are already
macros several layers deep leading to callout_reset_sbt_on().  This
was painful to debug with ddb.

r296775 has no effect for most uses.  The error is usually 5%.  I think
sloppiness on the old scaling usually gave much smaller errors.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160903152718.O1061>