All of lore.kernel.org
 help / color / mirror / Atom feed
From: Clemens Ladisch <clemens@ladisch.de>
To: Monty Montgomery <xiphmont@gmail.com>
Cc: Takashi Iwai <tiwai@suse.de>, alsa-devel@alsa-project.org
Subject: Re: UHCI dropped audio samples / DMA starvation fix
Date: Wed, 04 Apr 2012 22:54:34 +0200	[thread overview]
Message-ID: <4F7CB50A.5090701@ladisch.de> (raw)
In-Reply-To: <CACrD=+9OSMrf1ghQdvQ7xP7gpXUvT2jkgNh+1qQ5Efem7wsZaA@mail.gmail.com>

Monty Montgomery wrote:
> UHCI overlaps sending on the USB bus with DMAing the data from memory.
> It does not have all the data it needs to transmit a complete packet
> before it begins doing so.  If the data it needs is in a dirty cache
> line on a CPU, the flush triggers after DMA is already started; the
> UHCI host controller has to wait for the flush before accessing it,

I've heard that the latest Intel architecture allows DMA to and from(?)
the L3 cache.

> and if the flush happens too late, UHCI aborts the packet.  This is
> happening regularly on all the UHCI controllers I've tried thusfar.
>
> My guess is that this issue never attracted much attention because a)
> every one knows isoch transfers are 'unreliable'

FireWire controllers show how this is done: read entire packets into a
FIFO, and do this several frames before sending.  (Whether that works in
practice depends on how big the FIFO is, and if the FIFO is shared with
asynchronous packets to be transmitted.)

I've never heard of a USB controller being advertized as having a big
FIFO.

The UHCI spec says:
| The Host Controller processes the schedule one entry at a time (this
| discussion does not preclude prefetching of schedule entries).
but then:
| The Host Controller fetches the next entry from the Frame List when
| the millisecond allotted to the current frame expires.

... so it is not actually possible to prefetch packets in a useful way.

The EHCI spec does not mention prefetching; the v1.1 addendum ("Energy-
efficient extensions") defines a mechanism to allow prefetching, but
this is not support by Linux.

> The fix for usbaudio is dead easy.  Call:
>
> clflush_cache_range(urb->transfer_buffer, urb->transfer_buffer_length);

... if you happen to be on an x86 architecture ...

> as the last step of prepare_playback_urb() and
> prepare_nodata_playback_urb().  This completely corrects the DMA
> starvation behavior on my machines here.
>
> Note that the clflush_cache_range() has nothing to do with
> maintaining coherency.

And this is the problem with portability; all the portable functions in
<asm/cacheflush.h> are NOPs on cache-coherent architectures.

It might be possible to define a new function like
flush_coherent_dcache_range_for_faster_dma().  Maybe this should be
called from into usb_hcd_map_urb_for_dma() or from the arch
implementation of dma_map_*() for DMA_TO_DEVICE.  For the latter, this
might be implemented as a new DMA attribute.

> Unfortunately, the URB abstraction gives us no reliable way to do it
> in the HCD, because other drivers don't necessarily pass a valid
> CPU-side buffer address when using URB_NO_TRANSFER_DMA_MAP.

But the USB API requires this (any HCD might use PIO or use its own
double-buffering scheme).

> Should I whip up some patches for usb audio for 2.6.x and 3.3.x

It easily fixes an actual problem, so yes, it's definitely stable-worthy.


Regards,
Clemens

  reply	other threads:[~2012-04-04 20:54 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-04 19:43 UHCI dropped audio samples / DMA starvation fix Monty Montgomery
2012-04-04 20:54 ` Clemens Ladisch [this message]
2012-04-04 21:35   ` Monty Montgomery

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F7CB50A.5090701@ladisch.de \
    --to=clemens@ladisch.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=tiwai@suse.de \
    --cc=xiphmont@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.