Is it a good idea to use a usb-serial adapter for PPS input? Yes, it is.

Ian Lepore ian at freebsd.org
Tue Sep 10 15:54:15 UTC 2019


On Tue, 2019-09-10 at 17:40 +0300, Konstantin Belousov wrote:
> On Mon, Sep 09, 2019 at 04:19:48PM -0600, Ian Lepore wrote:
> > On Mon, 2019-09-09 at 19:45 +0300, Konstantin Belousov wrote:
> > > [...]
> > > Still the question is why your system have the negative impact from
> > > reducing the number of timehands.  Interrupt should never interrupt
> > > tc_windup() because it is protected by spinlock.  Silly question, are
> > > spinlocks functional on this machine ?
> > > 
> > 
> > <dropping usb@ from the cc, since this is purely arm stuff>
> > 
> > Yep, spinlocks work fine.
> > 
> > The problem sequence that happens, as I remember it, is that the system
> > is sleeping in cpu_idle() which has stopped the single core with the
> > WFI (wait-for-interrupt) instruction.  The wakeup from WFI is an
> > eventtimer event that was scheduled to handle state->nexthard to keep
> > the timecounter updated.  As part of handling that event, the system
> > calls the timecounter's tc_poll_pps function (which is dmtpps_poll() in
> > arm/ti/am335x/am335x_dmtpps.c).  That captures the pps event time using
> > the current timehands, then schedules a taskqueue task to finish
> > processing the captured data.  By the time the taskqueue task runs,
> > tc_windup() has been called more times than there are timehands, so
> > pps_event() rejects the data because th->th_generation captured in
> > dmtpps_poll() does not match th_generation in that set of timehands
> > anymore.
> 
> Is it really needed to schedule task for pps_event() ?
> 
> We don't for tc_windup(), and pps_event() is quite similar.
> And for pps_event(), we might use same opportunistic locking as
> for tc_windup().
> 

I think it is not necessary anymore, and I should fix that.  It was
necessary when the code was originally written.  The call to
pps_event() has to be protected by a mutex because the same data is
accessed via ioctl().

The timecounter polling routine is called in primary interrupt context
where sleeping is not allowed, so the old way to structure a hardware-
capture driver was to do the pps_capture() (which doesn't need mutex
protection) in the polling routine called from a filter handler and
defer the pps_event() processing to context where sleeping is allowed.

In May 2015 I committed some changes to the pps api stuff that allows
using a spin mutex, so I could change the kind of mutex used by the
driver and eliminate the taskqueue stuff completely.

-- Ian



More information about the freebsd-arm mailing list