On Mon, 12 Feb 2018 23:13:13 +0100, Maciej S. Szmigiero wrote: > > On 12.02.2018 13:56, Takashi Iwai wrote: > > On Sat, 27 Jan 2018 15:42:59 +0100, > > Maciej S. Szmigiero wrote: > >> > >> The Audigy 2 CA0102 chip (but most likely others from the emu10k1 family, > >> too) has a problem that from time to time it likes to do few DMA reads a > >> bit beyond its normal allocation and gets very confused if these reads get > >> blocked by a IOMMU. > >> > >> For the first (reserved) page this happens multiple times at every > >> playback, for various synth pages it happens randomly, rarely for PCM > >> playback buffers and the page table memory itself. > >> All these reads seem to follow a similar pattern, observed read offsets > >> beyond the allocation end were 0x00, 0x40, 0x80 and 0xc0 (PCI cache line > >> multiples), so it looks like the device tries to accesses up to 256 extra > >> bytes. > >> > >> As a workaround let's widen these DMA allocations by an extra page if we > >> detect that the device is behind a non-passthrough IOMMU (the DMA memory > >> should be relatively plenty on IOMMU systems). > >> > >> Signed-off-by: Maciej S. Szmigiero <mail@xxxxxxxxxxxxxxxxxxxxx> > >> --- > >> Changes from v1: Apply this workaround also to PCM playback buffers since > >> it seems they are affected, too. > > > > Instead of adjusting the allocation size in the caller side, how about > > adding a new helper to wrap around the call of snd_dma_alloc_pages()? > > > > We may need a counterpart to free pages in synth, but it's a single > > place in __synth_free_pages(), so it can be open-coded with some > > proper comments, too. > > I guess you mean adding a new wrapper to the ALSA core somewhere near > snd_dma_alloc_pages() (something named like > snd_dma_dev_alloc_pages_maybe_wider() ?). Well, not a common code but emu10k1 specific, something like int snd_emu10k1_alloc_pages_maybe_wider(emu, size, res) { if (emu->iommu_workaround) size += PAGE_SIZE; return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), size, res); } Also, I wonder what if PAGE_SIZE is over 4k. In that case, we don't necessarily need to increase the size, if the allocated size is larger than the requested one? But iommu_workaround is likely only about x86, so we don't need to care about it much, I guess. Takashi > Since snd_dma_alloc_pages() currently takes only a "struct device" > per-device parameter we wouldn't have a place to store a flag indicating > whether a device needs this workaround (or not) so we would need to > detect it every time this wrapper function gets called - in contrast, > in the current implementation this is done just once at the device > initialization time in snd_emu10k1_detect_iommu(). > > There are only 3 allocations that use snd_dma_alloc_pages() in this > driver that would use this new wrapper function, and each time the > overhead is just a two-line "if" block. > If one excludes synth, since it already uses a helper function to > compute these allocations lengths, that count lowers to only 2 places. > > That's why I think a driver-local change here is enough. > > Also, there is always a possibility to refactor the code into a common > helper if it turns out that there are other sound card with the same > problem. > > > > > thanks, > > > > Takashi > > Thanks, > Maciej > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel