getting 'load average' info from inside a kernel module

Konstantin Belousov kostikbel at gmail.com
Thu Dec 18 08:48:15 UTC 2014


On Wed, Dec 17, 2014 at 02:06:26PM -0600, Robert Bonomi wrote:
> 
> originally sent to -questions, where it was suggested that -hackers was more
> likely to produce some useful info.
> 
> > Subject: getting 'load averages' (or something similar) from inside a _kernel_
> >
> >   I'm trying to get the current 'runnable processes' count from inside a 
> > kernel loadable module for BSD 8.4, so I can tweak it's behavior depending
> > on the current activity level.  All I've found so far is what's in 'man 9 
> > runqueue', and it is *badly* out-of-sync with the 8.4 kernel code. <snarl>
> > <wry grin>   e.g., the external arrays at the beginning of the synopisis
> > are shown as being of type 'struct rq' -- but there *ISN"T* any defined 
> > struct 'rq'; it seems to be named 'runq', at least in /usr/include/sys/runq.h
> >
> > Then the cr*p gets deeper -- trying to make heads or tails out of how to
> > get a count of runnable processes from the _arrays_ (of unknown size) 
> > described on the 'man 9 runqueue' page info has me defeated. 
> > Looking at '/usr/include/sys/runq.h', it appears that 'struct runq' is
> > a single item with an array of queues (by 'nice' level), and a bitmap of
> > which array elements have non-zero length queues.
> >
> > I'm perfectly willing to brute-force the data out of the queue lists, *IF*
> > there's some reasonable, _current_, descriptive info of the format/usage
> > of those kernel structures.
> 
> if 'man 9 runqueue' is 'mostly' correct -- reality just being 'runq' instead 
> of 'rq' -- then 'how to find out' how mamy elements are in those 'unknown size'
> arrays is the missing element.  *OR* if those four items are _not_ arrays,
> but simple structs -- given the array of queueheads in the 'runq' struct,
> I can probably decipher the rest.
> >
> > Alternatively, is there a way to directly access the 'sysctl' MIB data in
> > kernel memory.  sysctl(3) is out -- it's in 'libc', and not available to 
> > kernel modules.  Pointers to descriptions of the kernel in-memory data for
> > that MIB would be a big help.   Or 'where to ask', if there's a better place.
> 
> I'm willing to 'count processes' in the run queues each time I query -- an
> 'instantenous' value is fine for my purposes, I can derive whatever 'avrage
> over time' I need. :))

You are writing a kernel module, so why did not you looked at the kernel
sources ?  Look at the implementation of the sysctl for which you want
the kernel analog, and do the same.

AFAIU, you want vm.loadavg, which is floating-point recoded
representation of the fixed-point values from averunnable array. Look at
sys/kern/kern_synch.c and sys/vm/vm_meter.c (honestly, I only checked
HEAD).


More information about the freebsd-hackers mailing list