Messages in this thread | | | From | "Maciej S. Szmigiero" <> | Subject | Re: [PATCH v2 5/5] ALSA: emu10k1: add a IOMMU workaround | Date | Wed, 14 Feb 2018 00:04:19 +0100 |
| |
On 13.02.2018 06:00, Takashi Iwai wrote: > 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@maciej.szmigiero.name> >>>> --- >>>> 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); > }
Okay, I have added a function like the one above to the driver and used it instead to make the relevant allocations.
> 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.
For completeness, I have added a check to the allocation function described above whether rounding the allocation size up to the nearest page size already covers the necessary extra memory space.
> > Takashi >
Maciej
| |