USB isochronous traffic with Rasberry Pi [WAS: Re: USB audio device on Raspberry Pi]
Hans Petter Selasky
hps at selasky.org
Sat May 10 22:17:15 UTC 2014
On 05/10/14 19:14, Ian Lepore wrote:
> On Sat, 2014-05-10 at 15:50 +0200, Hans Petter Selasky wrote:
>> On 05/10/14 14:24, Ian Lepore wrote:
>>> On Sat, 2014-05-10 at 09:51 +0200, Hans Petter Selasky wrote:
>>>> Hi,
>>>>
>>>> I've made one more patch to the DWC OTG driver. Nice if you can test
>>>> that too.
>>>>
>>>> http://svnweb.freebsd.org/changeset/base/265806
>>>>
>>>> BTW: I think I've found what is causing the glitches when using USB
>>>> audio devices:
>>>>
>>>> diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
>>>> index 0490be7..de7f015 100644
>>>> --- a/sys/arm/arm/machdep.c
>>>> +++ b/sys/arm/arm/machdep.c
>>>> @@ -423,7 +423,7 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
>>>> void
>>>> cpu_idle(int busy)
>>>> {
>>>> -
>>>> +#if 0
>>>> CTR2(KTR_SPARE2, "cpu_idle(%d) at %d",
>>>> busy, curcpu);
>>>> #ifndef NO_EVENTTIMERS
>>>> @@ -442,6 +442,7 @@ cpu_idle(int busy)
>>>> #endif
>>>> CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done",
>>>> busy, curcpu);
>>>> +#endif
>>>> }
>>>>
>>>> int
>>>>
>>>>
>>>> It appears that cpu_idle() is going to sleep when there are pending
>>>> interrupts, and then waking up on the next timer IRQ! Can someone
>>>> familiar with these parts of the kernel comment?
>>>>
>>>> Please try for yourself, with and without the patch above, using an USB
>>>> audio device with the RPI-B!
>>>>
>>>> Still when the console is printing, there are significant glitches too
>>>> :-) That's because the TTY layer is synchronously writing data to the
>>>> serial line. That's OK for now.
>>>>
>>>> --HPS
>>>
>>> If there's an interrupt pending when the WaitForInterrupt instruction is
>>> executed, the cpu doesn't go to sleep -- it acts like a nop. I think
>>> the problem might be that the device write that re-enables the interrupt
>>> hasn't yet made it to the device when the cpu clock stops.
>>>
>>> I don't have any usb audio gear to test with, could you please test the
>>> attached patch and see if it fixes the glitches?
>>>
>>> -- Ian
>>>
>>
>> Hi,
>>
>> That code is not used with RPI so it makes no difference.
>
> Doh! We have so much decoy code in freebsd-arm.
>
>> I think we
>> need to do something like they are doing on x86, that the interrupts are
>> enabled the instruction before the sleep instruction. Else we can loose
>> interrupts. Can you write me a correct patch which implements that?
>>
>
> ARM is not x86. From the ARM ARM:
>
> When a processor issues a WFI instruction it can suspend
> execution and enter a low-power state. It can remain in that
> state until the processor detects a reset or one of the
> following WFI wake-up events:
> * an IRQ interrupt, regardless of the value of the CPSR.I bit.
> * an FIQ interrupt, regardless of the value of the CPSR.F bit.
> * an asynchronous abort, regardless of the value of the CPSR.A
> bit.
> * a debug event, when invasive debug is enabled and the debug
> event is permitted.
>
> Not only is enabling interrupts before WFI not necessary, it may be
> completely the wrong thing to do... if there's an interrupt pending it
> will fire as soon as the cpsr.I bit is set, and the handler will run
> before the WFI executes. Depending on what the handler does maybe
> putting the CPU to sleep isn't the right thing to do anymore -- the ISR
> made something runnable that previously wasn't -- but upon return from
> handling the interrupt we'll unconditionally go to sleep until the next
> interrupt instead of returning to the scheduler which would now find new
> non-idle work to do.
>
> Note that in the linux implementation they actually go so far as adding
> a comment to explain that the code doesn't disable interrupts because
> it's expected that the caller has already done so:
>
> https://github.com/torvalds/linux/blob/master/arch/arm/mm/proc-v6.S#L69
>
> I wonder if this is related to some memory ordering trouble I've seen in
> armv7, which I can't fully explain, but the attached patch makes it go
> away (preventing spurious interrupts). It'd be interesting to see if it
> has any effect on this situation.
>
> -- Ian
>
Hi,
This patch makes no difference. Only the disabling of the cpu_idle()
function completely eliminates the problem.
--HPS
More information about the freebsd-arm
mailing list