sysctl questions

Milan Obuch freebsd-hackers at dino.sk
Sat Oct 19 17:45:03 UTC 2019


On Sat, 19 Oct 2019 10:35:31 -0600
Ian Lepore <ian at freebsd.org> wrote:

> On Sat, 2019-10-19 at 13:45 +0200, Milan Obuch wrote:
> > Hi,
> > 
> > I am working on AXI XADC driver on Zynq based Zybo Z7 board. I
> > created simple PL design to be able to use this core IP. Looking in
> > some other ADC driver I desided to use sysctl API to report
> > measurements. So I did create mib entry in attach function like this
> > 
> >     snprintf(pinbuf, sizeof(inum), "%d", i);
> > 
> >     inpN_node = SYSCTL_ADD_NODE(ctx, inp_tree, OID_AUTO, inum,
> >         CTLFLAG_RD, NULL, "ADC input");
> >     inpN_tree = SYSCTL_CHILDREN(inpN_node);
> > 
> >     SYSCTL_ADD_PROC(ctx, inpN_tree, OID_AUTO, "read",
> >         CTLFLAG_RD | CTLTYPE_UINT, &axi_xadc_inputs[i], 0,
> >         axi_xadc_read_proc, "IU", "Read ADC input");
> > 
> > where inum is string, i is integer - input number. Top node for my
> > mib entries is dev.adc.0.ain. When the above snippet is run for i
> > from 0 up to Ninputs - 1, sysctl shows them in opposite order, i. e.
> > 
> > # sysctl dev.adc.0.ain
> > dev.adc.0.ain.3.read: <some value>
> > dev.adc.0.ain.2.read: <some value>
> > dev.adc.0.ain.1.read: <some value>
> > dev.adc.0.ain.0.read: <some value>
> > 
> > Why it is so? It looks for me a bit counter intuitive, I like the
> > nodes be ordered the way I decide, not the other way so... so I am
> > just calling the initialisation snippet for i starting with Ninput
> > - 1 down to 0 and it works the way I want.
> >   
> 
> The sysctl oid entries are stored in an SLIST and each new entry is
> added to the head of the list, so when sysctl(8) walks the list of
> children of a given oid, they get displayed in reverse order of how
> they were added.
>

Thanks for explanation. This basically confirms my understanding, so
nodes should be added in reverse order to be displayed right. That's
easy.

> > Other thing I do not understand is my axi_xadc_read_proc is called
> > *twice* per node. My procedure is short:
> >   
> 
> This happens because sysctl(8) makes two calls per value retrieved. 
> The first call has req->oldptr set to NULL which makes the sysctl
> machinery return the length of the return value without returning the
> value itself.  Sysctl(8) then allocates a buffer of the right length
> and makes another call with req->oldptr pointing to the allocated
> buffer to actually retrieve the value.
> 
> When there is some cost to returning the value (such as an expensive
> or time-consuming hardware operation), you can check whether oldptr is
> NULL or not before doing the expensive work.  For an example, see the
> ads111x_sysctl_voltage() function in sys/dev/iicbus/ads111x.c
> 

Thanks for example. In my case it probably doesn't matter, but it is
good to know it is intentional, so if necessary, there is a way to cope
with this.

Regards,
Milan


More information about the freebsd-hackers mailing list