The fallback S/G buffer allocation for x86 used the addresses deduced
from the page allocations blindly. It broke the allocations on IOMMU
and made us to work around with a hackish DMA ops check.
For cleaning up those messes, this patch switches to the proper DMA
mapping API usages with the standard sg-table instead.
By introducing the sg-table, the address table isn't needed, but for
keeping the original allocation sizes for freeing, replace it with the
array keeping the number of pages.
The get_addr callback is changed to use the existing one for
non-contiguous buffers. (Also it's the reason sg_table is put at the
beginning of struct snd_dma_sg_fallback.)
And finally, the hackish workaround that checks the DMA ops is
dropped now.
Link: https://patch.msgid.link/20240912155227.4078-3-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The x86 WC page allocation assumes incorrectly the DMA address
directly taken from the page. Also it checks the DMA ops
inappropriately for switching to the own method.
This patch rewrites the stuff to use the proper DMA mapping API
instead.
Link: https://patch.msgid.link/20240912155227.4078-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Since recently in the commit e469e2045f ("ALSA: memalloc: Let IOMMU
handle S/G primarily"), the SG buffer allocation code was modified to
use the standard DMA code primarily and the fallback is applied only
limitedly. This made the Xen PV specific workarounds we took in the
commit 53466ebdec ("ALSA: memalloc: Workaround for Xen PV") rather
superfluous.
It was a hackish workaround for the regression at that time, and it
seems that it's causing another issues (reportedly memory
corruptions). So it's better to clean it up, after all.
Link: https://lore.kernel.org/20240906184209.25423-1-ariadne@ariadne.space
Cc: Ariadne Conill <ariadne@ariadne.space>
Link: https://patch.msgid.link/20240910113100.32542-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The definition of struct snd_malloc_ops was moved out to
memalloc_local.h since there was another code for S/G buffer
allocation referring to the struct. But since the code change to use
non-contiguous allocators, it's solely referred in memalloc.c, hence
it makes little sense to have a separate header file.
Let's move it back to memalloc.c.
Link: https://patch.msgid.link/20240910113141.32618-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The recent changes in IOMMU made the non-contiguous page allocations
as default, hence we can simply use the standard DMA allocation for
the S/G pages as well. In this patch, we simplify the code by trying
the standard DMA allocation at first, instead of
dma_alloc_noncontiguous().
For the case without IOMMU, we still need to manage the S/G pages
manually, so we keep the same fallback routines like before.
The fallback types (SNDRV_DMA_TYPE_DEV_SG_FALLBACK & co) are dropped /
folded into SNDRV_DMA_TYPE_DEV_SG and co now. The allocation via the
standard DMA call overrides the type accordingly, hence we don't have
to have extra fallback types any longer. OTOH, SNDRV_DMA_TYPE_DEV_SG
is no longer an alias but became its own type back again.
Note that this patch requires another prerequisite fix for memmalloc
helper to use the DMA API for WC pages on x86.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=219087
Link: https://patch.msgid.link/20240801064808.31205-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The memalloc helper used a house-made code for allocation of WC pages
on x86, since the standard DMA API doesn't cover it well. Meanwhile,
the manually allocated pages won't work together with IOMMU, resulting
in faults, so we should switch to the DMA API in that case, instead.
This patch tries to switch back to DMA API for WC pages on x86, but
with some additional tweaks that are missing.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=219087
Link: https://patch.msgid.link/20240801064808.31205-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
We change recently the memalloc helper to use
dma_alloc_noncontiguous() and the fallback to get_pages(). Although
lots of issues with IOMMU (or non-IOMMU) have been addressed, but
there seems still a regression on Xen PV. Interestingly, the only
proper way to work is use dma_alloc_coherent(). The use of
dma_alloc_coherent() for SG buffer was dropped as it's problematic on
IOMMU systems. OTOH, Xen PV has a different way, and it's fine to use
the dma_alloc_coherent().
This patch is a workaround for Xen PV. It consists of the following
changes:
- For Xen PV, use only the fallback allocation without
dma_alloc_noncontiguous()
- In the fallback allocation, use dma_alloc_coherent();
the DMA address from dma_alloc_coherent() is returned in get_addr
ops
- The DMA addresses are stored in an array; the first entry stores the
number of allocated pages in lower bits, which are referred at
releasing pages again
Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Fixes: a8d302a0b7 ("ALSA: memalloc: Revive x86-specific WC page allocations again")
Fixes: 9736a32513 ("ALSA: memalloc: Don't fall back for SG-buffer with IOMMU")
Link: https://lore.kernel.org/r/87tu256lqs.wl-tiwai@suse.de
Link: https://lore.kernel.org/r/20230125153104.5527-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
While not quite as bogus as for the dma-coherent allocations that were
fixed earlier, GFP_COMP for these allocations has no benefits for
the dma-direct case, and can't be supported at all by dma dma-iommu
backend which splits up allocations into smaller orders. Due to an
oversight in ffcb754584 that flag stopped being cleared for all
dma allocations, but only got rejected for coherent ones.
Start fixing this by not requesting __GFP_COMP in the sound code, which
is the only place that did this.
Fixes: ffcb754584 ("dma-mapping: reject __GFP_COMP in dma_alloc_attrs")
Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Reported-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Tested-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
This looks like a relatively calm development cycle; there have been
only few changes in ALSA and ASoC core sides while we get lots of
device-specific fixes and updates as usual. Most of commits are about
ASoC, including Intel SOF/AVS and many device tree updates.
Below are some highlights:
Core:
- Improvement in memalloc helper for fallback allocations
- More cleanups of ASoC DAPM code
ASoC:
- Factoring out of mapping hw_params onto SoundWire configuration
- The ever ongoing overhauls of the Intel DSP code continue, including
support for loading libraries and probes with IPC4 on SOF.
- Support for more sample formats on JZ4740
- Lots of device tree conversions and fixups
- Support for Allwinner D1, a range of AMD and Intel systems, Mediatek
systems with multiple DMICs, Nuvoton NAU8318, NXP fsl_rpmsg and
i.MX93, Qualcomm AudioReach Enable, MFC and SAL, RealTek RT1318 and
Rockchip RK3588
ALSA:
- Addition of PCM kselftest; still minimalistic but can be extended
in future
- Fixes for corner-case XRUNs with USB-audio implicit feedback mode
- Usual device-specific quirk updates for USB- and HD-audio
- FireWire DICE updates
Also, this PR also contains a few cross-tree updates:
- Some OMAP board file updates for removal of relevant OMAP platforms
- A new I2C API update for I2C probe API adaption
- A DRM update for the further hdmi-codec updates
-----BEGIN PGP SIGNATURE-----
iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmOR6TEOHHRpd2FpQHN1
c2UuZGUACgkQLtJE4w1nLE9p4w/8CoC/jEVFoOFVeH4/ur3MSGv93iDlPlA9sg1B
BMtUEsa+yUtlPjZfw/ZdnUvWGGkvSTIAA3Tyc+yrx+WYAJeoWsL6vpkjQcoKBFLV
oOo/dLROqeK6kS3cir0Z5VzaTg29XNz7iwe2wMp2q0irjbVZVy0+TUa2bzNOAdbs
Hupu5Vwx2lKINSKjWVbN+3g4LiMW+VyEavNZf7bZNxI5h/4p1oaOj/lJrsHCEX5y
rj1+d4EJntaFHToPf+4YkrMjLji0Yj9qsIWeXWy0Q5aUCyNr4zA3LrSszyM5cYfC
dBPPrFatvXt+N0SVTURX7VnKgYzLlG8TNwXPUJbfnTGzvXHzd5q08MHWm2ZyF2tf
3wDR+Lrw97WLWvGKQjHpg1ZFWmqSTC6D+9ihGCNRq0pMW6EtmxHtkDxhD45WF1Wq
UQJNYHWbpSQye+wwio1/JZCZ55x89utapaRXD9cTZCDoCBKOcaUsr71hNt56HL/3
5dT6fx1pJwyaR+SPJg7DQlnPGnm4J8cJhwi+WuHME9IECjO10b9o5ThcxaNWY3W7
ysVCk2jLJHOZTG4FDun5mEqyWEmnjrUAH9UZtCSQZdhYCk8E8C9B2trKUAh9nb/p
bUCrNdoopY5SpUCadPT7HtDiNXNWYMnpd7ktUun2z7V0u8pZNnhNUVvOuzFc/gT1
ypWJp+0=
=QV3a
-----END PGP SIGNATURE-----
Merge tag 'sound-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"This looks like a relatively calm development cycle; there have been
only few changes in ALSA and ASoC core sides while we get lots of
device-specific fixes and updates as usual. Most of commits are about
ASoC, including Intel SOF/AVS and many device tree updates.
Below are some highlights:
Core:
- Improvement in memalloc helper for fallback allocations
- More cleanups of ASoC DAPM code
ASoC:
- Factoring out of mapping hw_params onto SoundWire configuration
- The ever ongoing overhauls of the Intel DSP code continue,
including support for loading libraries and probes with IPC4 on
SOF.
- Support for more sample formats on JZ4740
- Lots of device tree conversions and fixups
- Support for Allwinner D1, a range of AMD and Intel systems,
Mediatek systems with multiple DMICs, Nuvoton NAU8318, NXP
fsl_rpmsg and i.MX93, Qualcomm AudioReach Enable, MFC and SAL,
RealTek RT1318 and Rockchip RK3588
ALSA:
- Addition of PCM kselftest; still minimalistic but can be extended
in future
- Fixes for corner-case XRUNs with USB-audio implicit feedback mode
- Usual device-specific quirk updates for USB- and HD-audio
- FireWire DICE updates
This also contains a few cross-tree updates:
- Some OMAP board file updates for removal of relevant OMAP platforms
- A new I2C API update for I2C probe API adaption
- A DRM update for the further hdmi-codec updates"
* tag 'sound-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (417 commits)
ALSA: mts64: fix possible null-ptr-defer in snd_mts64_interrupt
ALSA: patch_realtek: Fix Dell Inspiron Plus 16
ALSA: hda/cirrus: Add extra 10 ms delay to allow PLL settle and lock.
ASoC: dt-bindings: Correct Alexandre Belloni email
ASoC: dt-bindings: maxim,max98504: Convert to DT schema
ASoC: dt-bindings: maxim,max98357a: Convert to DT schema
ASoC: dt-bindings: Reference common DAI properties
ASoC: dt-bindings: Extend name-prefix.yaml into common DAI properties
ASoC: rt715: Make read-only arrays capture_reg_H and capture_reg_L static const
ASoC: uniphier: aio-core: Make some read-only arrays static const
ASoC: wcd938x: Make read-only array minCode_param static const
ASoC: qcom: lpass-sc7280: Add maybe_unused tag for system PM ops
ASoC : SOF: amd: Add support for IPC and DSP dumps
ASoC: SOF: amd: Use poll function instead to read ACP_SHA_DSP_FW_QUALIFIER
ALSA: usb-audio: Workaround for XRUN at prepare
ALSA: pcm: Handle XRUN at trigger START
ALSA: pcm: Set missing stop_operating flag at undoing trigger start
drm: tda99x: Don't advertise non-existent capture support
ASoC: hdmi-codec: Allow playback and capture to be disabled
kselftest/alsa: Add more coverage of sample rates and channel counts
...
dma_alloc_coherent/dma_alloc_wc is an opaque allocator that only uses
the GFP_ flags for allocation context control. Don't pass __GFP_COMP
which makes no sense for an allocation that can't in any way be
converted to a page pointer.
Note that for dma_alloc_noncoherent and dma_alloc_noncontigous in
combination with the DMA mmap helpers __GFP_COMP looks sketchy as well,
so I would suggest to drop that as well after a careful audit.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Currently the fallback SG allocation tries to allocate each single
page, and this tends to result in the reverse order of memory
addresses when large space is available at boot, as the kernel takes a
free page from the top to the bottom in the zone. The end result
looks as if non-contiguous (although it actually is). What's worse is
that it leads to an overflow of BDL entries for HD-audio.
For avoiding such a problem, this patch modifies the allocation code
slightly; now it tries to allocate the larger contiguous chunks as
much as possible, then reduces to the smaller chunks only if the
allocation failed -- a similar strategy as the existing
snd_dma_alloc_pages_fallback() function.
Along with the trick, drop the unused address array from
snd_dma_sg_fallback object. It was needed in the past when
dma_alloc_coherent() was used, but with the standard page allocator,
it became superfluous and never referred.
Fixes: a8d302a0b7 ("ALSA: memalloc: Revive x86-specific WC page allocations again")
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20221114141658.29620-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The latest fix for the non-contiguous memalloc helper changed the
allocation method for a non-IOMMU system to use only the fallback
allocator. This should have worked, but it caused a problem sometimes
when too many non-contiguous pages are allocated that can't be treated
by HD-audio controller.
As a quirk workaround, go back to the original strategy: use
dma_alloc_noncontiguous() at first, and apply the fallback only when
it fails, but only for non-IOMMU case.
We'll need a better fix in the fallback code as well, but this
workaround should paper over most cases.
Fixes: 9736a32513 ("ALSA: memalloc: Don't fall back for SG-buffer with IOMMU")
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/CAHk-=wgSH5ubdvt76gNwa004ooZAEJL_1Q-Fyw5M2FDdqL==dg@mail.gmail.com
Link: https://lore.kernel.org/r/20221112084718.3305-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
When the non-contiguous page allocation for SG buffer allocation
fails, the memalloc helper tries to fall back to the old page
allocation methods. This would, however, result in the bogus page
addresses when IOMMU is enabled. Usually in such a case, the fallback
allocation should fail as well, but occasionally it succeeds and
hitting a bad access.
The fallback was thought for non-IOMMU case, and as the error from
dma_alloc_noncontiguous() with IOMMU essentially implies a fatal
memory allocation error, we should return the error straightforwardly
without fallback. This avoids the corner case like the above.
The patch also renames the local variable "dma_ops" with snd_ prefix
for avoiding the name conflict.
Fixes: a8d302a0b7 ("ALSA: memalloc: Revive x86-specific WC page allocations again")
Reported-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/alpine.DEB.2.22.394.2211041541090.3532114@eliteleevi.tm.intel.com
Link: https://lore.kernel.org/r/20221110132216.30605-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Use __GFP_RETRY_MAYFAIL instead of __GFP__NORETRY in
snd_dma_dev_alloc(), snd_dma_wc_alloc() and friends, to allocate pages
for device memory. The MAYFAIL flag retains the semantics of not
triggering the OOM killer, but lowers the risk of alloc failure.
MAYFAIL flag was added in commit dcda9b0471 ("mm, tree wide: replace
__GFP_REPEAT by __GFP_RETRY_MAYFAIL with more useful semantic").
This change addresses recurring failures with SOF audio driver in test
cases where a system suspend-resume stress test is run, combined with an
active high memory-load use-case. The failure typically shows up as:
[ 379.480229] sof-audio-pci-intel-tgl 0000:00:1f.3: booting DSP firmware
[ 379.484803] sof-audio-pci-intel-tgl 0000:00:1f.3: error: memory alloc failed: -12
[ 379.484810] sof-audio-pci-intel-tgl 0000:00:1f.3: error: dma prepare for ICCMAX stream failed
Multiple fixes to reduce the memory usage of DSP boot have been
identified in SOF driver, but even with those fixes, debug on affected
systems has shown that even a single page alloc may fail with
__GFP_NORETRY. When this occurs, system is under significant load on
physical memory, but a lot of reclaimable pages are available, so the
system has not run out of memory. With __GFP_RETRY_MAYFAIL, the errors
are not hit in these stress tests.
The alloc failure is severe as audio capability is completely lost if
alloc failure is hit at system resume.
An alternative solution was considered where the resources for DSP boot
would be kept allocated until driver is unbound. This would avoid the
allocation failure, but consume memory that is only needed temporarily
at probe and resume time. It seems better to not hang on to the memory,
but rather work a bit harder for allocating the pages at resume.
BugLink: https://github.com/thesofproject/linux/issues/3844
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20220923153501.3326041-1-kai.vehmanen@linux.intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The last fix for trying to recover the regression on AMD platforms,
unfortunately, leaded to yet another regression: it turned out that
IOMMUs don't like the usage of raw page allocations.
This is yet another attempt for addressing the log saga; at this time,
we re-use the existing buffer allocation mechanism with SG-pages
although we require only single pages. The SG buffer allocation
itself was confirmed to work for stream buffers, so it's relatively
easy to adapt for other places.
The only problem is: although the HD-audio code is accessing the
address directly via dmab->address field, SG-pages don't set up it.
For the ease of adaption, we now set up the dmab->addr field from the
address of the first page as default, so that it can run with the
HD-audio driver code as-is without the excessive call of
snd_sgbuf_get_addr() multiple times; that's the only change in the
memalloc helper side. The rest is nothing but a flip of the dma_type
field in the HD-audio side.
Fixes: a8d302a0b7 ("ALSA: memalloc: Revive x86-specific WC page allocations again")
Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/CABXGCsO+kB2t5QyHY-rUe76npr1m0-5JOtt8g8SiHUo34ur7Ww@mail.gmail.com
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216112
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216363
Link: https://lore.kernel.org/r/20220906090319.23358-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Now that all users of snd_dma_continuous_data() is gone, let's drop
this ugly (and dangerous) way.
After this commit, SNDRV_DMA_TYPE_CONTINUOUS may take the standard
device pointer instead of the hacked pointer by the macro above, and
the memalloc core refers to the coherent_dma_mask of the given
device like other SNDRV_DMA_TYPE. It's still allowed to pass NULL
there, and in that case, the allocation is performed always in the
normal zone.
For SNDRV_DMA_TYPE_VMALLOC, the device pointer is simply ignored.
Link: https://lore.kernel.org/r/20220823115740.14123-5-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
We dropped the x86-specific hack for WC-page allocations with a hope
that the standard dma_alloc_wc() works nowadays. Alas, it doesn't,
and we need to take back some workaround again, but in a different
form, as the previous one was broken for some platforms.
This patch re-introduces the x86-specific WC-page allocations, but it
uses rather the manual page allocations instead of
dma_alloc_coherent(). The use of dma_alloc_coherent() was also a
potential problem in the recent addition of the fallback allocation
for noncontig pages, and this patch eliminates both at once.
Fixes: 9882d63bea ("ALSA: memalloc: Drop x86-specific hack for WC allocations")
Cc: <stable@vger.kernel.org>
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216363
Link: https://lore.kernel.org/r/20220821155911.10715-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Each kernel doc comment expects the definition of the return value in
a proper format. This patch adds or fixes the missing entries for
memory allocation helpers.
Link: https://lore.kernel.org/r/20220713104759.4365-7-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The recent report for a crash on Haswell machines implied that the
x86-specific (rather hackish) implementation for write-cache memory
buffer allocation in ALSA core is buggy with the recent kernel in some
corner cases. This patch drops the x86-specific implementation and
uses the standard dma_alloc_wc() & co generically for avoiding the bug
and also for simplification.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216112
Cc: <stable@vger.kernel.org> # v5.18+
Link: https://lore.kernel.org/r/20220620073440.7514-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The recent change for memory allocator replaced the SG-buffer handling
helper for x86 with the standard non-contiguous page handler. This
works for most cases, but there is a corner case I obviously
overlooked, namely, the fallback of non-contiguous handler without
IOMMU. When the system runs without IOMMU, the core handler tries to
use the continuous pages with a single SGL entry. It works nicely for
most cases, but when the system memory gets fragmented, the large
allocation may fail frequently.
Ideally the non-contig handler could deal with the proper SG pages,
it's cumbersome to extend for now. As a workaround, here we add new
types for (minimalistic) SG allocations, instead, so that the
allocator falls back to those types automatically when the allocation
with the standard API failed.
BTW, one better (but pretty minor) improvement from the previous
SG-buffer code is that this provides the proper mmap support without
the PCM's page fault handling.
Fixes: 2c95b92ecd ("ALSA: memalloc: Unify x86 SG-buffer handling (take#3)")
BugLink: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2272
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1198248
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20220413054808.7547-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
It seems that calling invalidate_kernel_vmap_range() is more correct
to be called before dma_sync_*(), judging from the other thread:
https://lore.kernel.org/all/20220111085958.GA22795@lst.de/
Although this won't matter much in practice, let's fix the call order
for consistency.
Fixes: a25684a956 ("ALSA: memalloc: Support for non-contiguous page allocation")
Reported-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20220210123344.8756-3-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
dma_need_sync() checks each DMA address. Fix the incorrect usages
for non-contiguous and non-coherent page allocations.
Fortunately, there are no actual call sites that need manual syncs
yet.
Fixes: a25684a956 ("ALSA: memalloc: Support for non-contiguous page allocation")
Fixes: 73325f60e2 ("ALSA: memalloc: Support for non-coherent page allocation")
Cc: <stable@vger.kernel.org>
Reported-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Link: https://lore.kernel.org/r/20220210123344.8756-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This is a second attempt to unify the x86-specific SG-buffer handling
code with the new standard non-contiguous page handler.
The first try (in commit 2d9ea39917) failed due to the wrong page
and address calculations, hence reverted. (And the second try failed
due to a copy&paste error.) Now it's corrected with the previous fix
for noncontig pages, and the proper sg page iteration by this patch.
After the migration, SNDRV_DMA_TYPE_DMA_SG becomes identical with
SNDRV_DMA_TYPE_NONCONTIG on x86, while others still fall back to
SNDRV_DMA_TYPE_DEV.
Tested-by: Alex Xu (Hello71) <alex_y_xu@yahoo.ca>
Tested-by: Harald Arnesen <harald@skogtun.org>
Link: https://lore.kernel.org/r/20211017074859.24112-4-tiwai@suse.de
Link: https://lore.kernel.org/r/20211109062235.22310-1-tiwai@suse.de
Link: https://lore.kernel.org/r/20211116073358.19741-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The comment about the reused vmalloc helpers is no longer valid after
the recent change for the noncontig allocator. Drop the stale
comment.
Fixes: ad4f93ca41 ("ALSA: memalloc: Use proper SG helpers for noncontig allocations")
Link: https://lore.kernel.org/r/20211110063100.21359-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The recently introduced non-contiguous page allocation support helpers
are using the simplified code to calculate the page and DMA address
based on the vmalloc helpers, but this isn't quite right as the vmap
is valid only for the direct DMA.
This patch corrects those accessors to use the proper SG helpers
instead.
Fixes: a25684a956 ("ALSA: memalloc: Support for non-contiguous page allocation")
Tested-by: Alex Xu (Hello71) <alex_y_xu@yahoo.ca>
Link: https://lore.kernel.org/r/20211108151059.31898-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The recent refactoring of mmap handling caused Oops on some devices
that don't use the standard memory allocations. This patch addresses
it by allowing snd_dma_buffer_mmap() helper to receive the NULL
pointer dmab argument (and return an error appropriately).
Fixes: a202bd1ad8 ("ALSA: core: Move mmap handler into memalloc ops")
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20211107163911.13534-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Although we've covered all calls with NULL dma buffer pointer, so far,
there may be still some else in the wild. For catching such a case
more easily, add a WARN_ON_ONCE() in snd_dma_get_ops().
Fixes: 37af81c599 ("ALSA: core: Abstract memory alloc helpers")
Link: https://lore.kernel.org/r/20211105102103.28148-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This reverts commit 2d9ea39917.
We've got a regression report showing that the audio got broken the
device over AMD IOMMU. The conversion assumed the wrong pointer /
page mapping for the indirect mapping case, and we need to correct
this urgently, so let's revert it for now.
Fixes: 2d9ea39917 ("ALSA: memalloc: Convert x86 SG-buffer handling with non-contiguous type")
Reported-and-tested-by: Alex Xu (Hello71) <alex_y_xu@yahoo.ca>
Link: https://lore.kernel.org/r/20211104180846.16340-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
We've had an x86-specific SG-buffer handling code, but now it can be
merged gracefully with the standard non-contiguous DMA pages.
After the migration, SNDRV_DMA_TYPE_DMA_SG becomes identical with
SNDRV_DMA_TYPE_NONCONTIG on x86, while others still fall back to
SNDRV_DMA_TYPE_DEV.
The remaining problem is about the SG-buffer with WC pages: the DMA
core stuff on x86 doesn't treat it well, so we still need some special
handling to manipulate the page attribute manually. The mmap handler
for SNDRV_DMA_TYPE_DEV_SG_WC still returns -ENOENT intentionally for
the fallback to the default handler.
Link: https://lore.kernel.org/r/20211017074859.24112-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Following to the addition of non-contiguous pages, this patch adds the
new contiguous non-coherent page allocation to the standard memalloc
helper. Like the previous non-contig type, this non-coherent type is
also directional and requires the explicit sync, too. Hence the
driver using this type of buffer may need to set
SNDRV_PCM_INFO_EXPLICIT_SYNC flag to the PCM hardware.info as well,
unless it's set up in the managed mode.
Link: https://lore.kernel.org/r/20211017074859.24112-3-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This patch adds the support for allocation of non-contiguous DMA pages
in the common memalloc helper. It's another SG-buffer type, but
unlike the existing one, this is directional and requires the explicit
sync / invalidation of dirty pages on non-coherent architectures.
For this enhancement, the following points are changed:
- snd_dma_device stores the DMA direction.
- snd_dma_device stores need_sync flag indicating whether the explicit
sync is required or not.
- A new variant of helper functions, snd_dma_alloc_dir_pages() and
*_all() are introduced; the old snd_dma_alloc_pages() and *_all()
kept as just wrappers with DMA_BIDIRECTIONAL.
- A new helper snd_dma_buffer_sync() is introduced; this gets called
in the appropriate places.
- A new allocation type, SNDRV_DMA_TYPE_NONCONTIG, is introduced.
When the driver allocates pages with this new type, and it may require
the SNDRV_PCM_INFO_EXPLICIT_SYNC flag set to the PCM hardware.info for
taking the full control of PCM applptr and hwptr changes (that implies
disabling the mmap of control/status data). When the buffer
allocation is managed by snd_pcm_set_managed_buffer(), this flag is
automatically set depending on the result of dma_need_sync()
internally. Otherwise, if the buffer is managed manually, the driver
has to set the flag explicitly, too.
The explicit sync between CPU and device for non-coherent memory is
performed at the points before and after read/write transfer as well
as the applptr/hwptr syncptr ioctl. In the case of mmap mode,
user-space is supposed to call the syncptr ioctl with the hwptr flag
to update and fetch the status at first; this corresponds to CPU-sync.
Then user-space advances the applptr via syncptr ioctl again with
applptr flag, and this corresponds to the device sync with flushing.
Other than the DMA direction and the explicit sync, the usage of this
new buffer type is almost equivalent with the existing
SNDRV_DMA_TYPE_DEV_SG; you can get the page and the address via
snd_sgbuf_get_page() and snd_sgbuf_get_addr(), also calculate the
continuous pages via snd_sgbuf_get_chunk_size().
For those SG-page handling, the non-contig type shares the same ops
with the vmalloc handler. As we do always vmap the SG pages at first,
the actual address can be deduced from the vmapped address easily
without iterating the SG-list.
Link: https://lore.kernel.org/r/20211017074859.24112-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This is an enhancement for the SG-style page handling in vmalloc
buffer handler to calculate the continuous pages.
When snd_sgbuf_get_chunk_size() is called for a vmalloc buffer,
currently we return only the size that fits into a single page.
However, this API call is rather supposed for obtaining the continuous
pages and most of vmalloc or noncontig buffers do have lots of
continuous pages indeed. So, in this patch, the callback now
calculates the possibly continuous pages up to the given size limit.
Note that the end address in the function is calculated from the last
byte, hence it's one byte shorter. This is because ofs + size can be
above the actual buffer size boundary.
Until now, this feature isn't really used, but it'll become useful in
a later patch that adds the non-contiguous buffer type that shares the
same callback function as vmalloc.
Link: https://lore.kernel.org/r/20210812113818.6479-1-tiwai@suse.de
Link: https://lore.kernel.org/r/20210813081645.4680-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
In the recent fix commit eda80d7c9c ("ALSA: memalloc: Fix regression
with SNDRV_DMA_TYPE_CONTINUOUS"), we replaced the pfn argument of the
remap_page_pfn() call from the uninitialized dmab->addr. It was the
right fix, but it'd be more generic if we actually initialize
dmab->area for SNDRV_DMA_TYPE_CONTINOUS, too. e.g. the field is used
in the common snd_sgbuf_get_addr(), too.
This patch adds the initialization of addr field and does revert of
the previous change to refer to it again in the mmap call.
Link: https://lore.kernel.org/r/20210804074125.8170-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
We have a special handling of WC pages on x86, and it's currently
specific to HD-audio. The last forgotten piece was the pgprot setup
for the mmap with WC pages.
This patch moves the pgprot setup for WC pages from HD-audio-specific
mmap callback to the common helper code. It allows us to remove the
superfluous mmap callback in HD-audio and its prepare_mmap
redirection.
Link: https://lore.kernel.org/r/20210804061329.29265-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
There are the generic DMA API calls for allocating and managing the
pages with the write-combined attribute. Let's use them for all
architectures but x86; x86 still needs the special handling to
override the page attributes.
Acked-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20210802072815.13551-5-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
SNDRV_DMA_TYPE_DEV_UC and SNDRV_DMA_TYPE_DEV_UC_SG are incorrectly
named as if they were for the uncached memory, while actually we set
the pages as write-combined. Rename them to reflect the right
attribute.
Acked-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20210802072815.13551-3-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Return the pointer directly from alloc ops instead of setting
dmab->area at each place. It simplifies the code a bit.
Acked-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20210802072815.13551-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The recent code refactoring made the mmap of continuous pages to be
done via the own helper snd_dma_continuous_mmap() with
remap_pfn_range(). There I overlooked that dmab->addr isn't set for
the allocation with SNDRV_DMA_TYPE_CONTINUOUS. This resulted always
in an error at mmap with this buffer type on the system such as
Intel SST Baytrail driver.
This patch fixes the regression by passing the correct address.
Fixes: 30b7ba6972 ("ALSA: core: Add continuous and vmalloc mmap ops")
Reported-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/8d6674da-7d7b-803e-acc9-7de6cb1223fa@redhat.com
Link: https://lore.kernel.org/r/20210801113801.31290-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This is a preparation for allowing devres usages more widely in
various sound drivers. As a first step, this patch adds a new
allocator function, snd_devm_alloc_pages(), to manage the allocated
pages via devres, so that the pages will be automagically released as
device unbinding.
Unlike the old snd_dma_alloc_pages(), the new function returns
directly the snd_dma_buffer pointer. The caller needs NULL-check for
the allocation error appropriately.
Also, since a real device pointer is mandatory for devres,
SNDRV_DMA_TYPE_CONTINUOUS or SNDRV_DMA_TYPE_VMALLOC type can't be used
for this function.
Link: https://lore.kernel.org/r/20210715075941.23332-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The mmap of continuous pages and vmalloc'ed pages are relatively
easily done in a shot with the existing helper functions.
Implement the mmap ops for those types, so that the mmap works without
relying on the page fault handling.
Link: https://lore.kernel.org/r/20210609162551.7842-6-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This patch moves the mmap handling code into the common memalloc
handler. It allows us to reduce the memory-type specific code in PCM
code gracefully.
Link: https://lore.kernel.org/r/20210609162551.7842-5-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This patch introduces the ops table to each memory allocation type
(SNDRV_DMA_TYPE_XXX) and abstract the handling for the better code
management. Then we get separate the page allocation, release and
other tasks for each type, especially for the SG buffer.
Each buffer type has now callbacks in the struct snd_malloc_ops, and
the common helper functions call those ops accordingly. The former
inline code that is specific to SG-buffer is moved into the local
sgbuf.c, and we can simplify the PCM code without details of memory
handling.
Link: https://lore.kernel.org/r/20210609162551.7842-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Currently the standard memory allocator (snd_dma_malloc_pages*())
passes the byte size to allocate as is. Most of the backends
allocates real pages, hence the actual allocations are aligned in page
size. However, the genalloc doesn't seem assuring the size alignment,
hence it may result in the access outside the buffer when the whole
memory pages are exposed via mmap.
For avoiding such inconsistencies, this patch makes the allocation
size always to be aligned in page size.
Note that, after this change, snd_dma_buffer.bytes field contains the
aligned size, not the originally requested size. This value is also
used for releasing the pages in return.
Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
Link: https://lore.kernel.org/r/20201218145625.2045-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Since mmap for userspace is based on page alignment, add page alignment
for iram alloc from pool, otherwise, some good data located in the same
page of dmab->area maybe touched wrongly by userspace like pulseaudio.
Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/1608221747-3474-1-git-send-email-yibin.gong@nxp.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Fix cppcheck, the fallthrough only makes sense within the conditional
block
sound/core/memalloc.c:161:3: style:inconclusive: Statements following
return, break, continue, goto or throw will never be
executed. [unreachableCode]
fallthrough;
^
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200902212133.30964-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>