get_cyclecount(9) deprecation

Bruce Evans brde at optusnet.com.au
Fri Mar 18 08:10:04 UTC 2011


On Thu, 17 Mar 2011, Jung-uk Kim wrote:

> Both get_cyclecount(9) and cpu_ticks() do almost exactly the same
> thing now assuming set_cputicker() is called with a correct function
> before get_cyclecount() is used, which is true for x86, at least.
> The only difference is get_cyclecount() may be inlined but I don't
> see much gain from the current uses.
>
> Please review the patch.  Note I didn't really remove get_cyclecount()
> just because some random third-party module may use it as it is a
> documented feature while cpu_ticks is an internal KPI.
>
> What do you think?

I like this idea, but see some minor problems:
- cpu_ticks() API needs to become more public and stable, and guarantee to
   use the ticker with the highest frequency
- it is hard to see when set_cputicker() is called, but on i386 it is
   called very early so there seem to be no problems with the dummy
   timecounter.  It is called from init_TSC() which is called from
   startrtclock() which is called from machdep.c:cpu_startup() just
   after the garbage "Good morning" comment which was originally just
   banal since it preceeded its code (the printf that prints the copyright
   message).  The ordering of this is now highly obfuscated, and in fact
   there is now the following enormous amount of code between the printf
   and its comment:

% enum sysinit_sub_id {
% 	SI_SUB_DUMMY		= 0x0000000,	/* not executed; for linker*/
% 	SI_SUB_DONE		= 0x0000001,	/* processed*/
% 	SI_SUB_TUNABLES		= 0x0700000,	/* establish tunable values */
% 	SI_SUB_COPYRIGHT	= 0x0800001,	/* first use of console*/
   	       ^^^^^^^^^ prints the copyright
% 	SI_SUB_SETTINGS		= 0x0880000,	/* check and recheck settings */
% 	SI_SUB_MTX_POOL_STATIC	= 0x0900000,	/* static mutex pool */
% 	SI_SUB_LOCKMGR		= 0x0980000,	/* lockmgr locks */
% 	SI_SUB_VM		= 0x1000000,	/* virtual memory system init*/
% 	SI_SUB_KMEM		= 0x1800000,	/* kernel memory*/
% 	SI_SUB_KVM_RSRC		= 0x1A00000,	/* kvm operational limits*/
% 	SI_SUB_WITNESS		= 0x1A80000,	/* witness initialization */
% 	SI_SUB_MTX_POOL_DYNAMIC	= 0x1AC0000,	/* dynamic mutex pool */
% 	SI_SUB_LOCK		= 0x1B00000,	/* various locks */
% 	SI_SUB_EVENTHANDLER	= 0x1C00000,	/* eventhandler init */
% 	SI_SUB_VNET_PRELINK	= 0x1E00000,	/* vnet init before modules */
% 	SI_SUB_KLD		= 0x2000000,	/* KLD and module setup */
% 	SI_SUB_CPU		= 0x2100000,	/* CPU resource(s)*/
   	       ^^^ calls cpu_startup()

   but there seem to be no slow operations (like device initialization) in
   there, so cpu_startup() seems to be called early enough.

   The function names for clock initialization are almost equally rotted:
   - the realtime clock was originally the i8254, and startrtclock()
     started it.  Now startrtclock() doesn't touch either the the realtime
     clock (the timecounter) or the i8254.  It only calls init_TSC().  This
     might as well be called directly.  The i8254 is now initialized (only?)
     by i8254, which is called much earlier, from init386(), so that DELAY()
     works when called early from console drivers.  The same care should be
     taken with initializing the TSC for early use, and would be essential
     if the i8254 support in DELAY() were removed.
   - the correct interface for attaching the realtime clock now seems to be
     cpu_initclocks().  This is now used for the TSC (init_TSC_tc()).  But
     the i8254 is now attached as a timecounter in attimer_attach().
- set_cputicker() has various races and implementation bugs:
   - it has no visible locking.  This may be safe when it is called at boot
     time.  It is also called from tsc_levels_changed().  BTW, these calls
     still don't know about P-state invariance.  They always pass the
     parameter saying that the ticker is variable.  This despite the
     invariance variable being checked to lines after the call that passes
     a hard-coded for variance.
   - the call to set_cputicker() after machdep.tsc_freq changes the ticker
     freqency is missing.  This is a feature if the ticker is variable,
     since the dynamic ticker calibration code can be more accurate than
     a fixed setting, and would undo any fixed setting.  But this code is
     buggy...
- set cputicker() has some design bugs.  It assumes that the tick frequency
   is the same across all CPUs, but the TSC is per-CPU.  I have an old SMP
   system with CPUs of different frequency that can demonstrate bugs from
   this.

Bruce


More information about the freebsd-hackers mailing list