Currently, the available buffer allocation size for a PCM stream
depends on the preallocated size; when a buffer has been preallocated,
the max buffer size is set to that size, so that application won't
re-allocate too much memory. OTOH, when no preallocation is done,
each substream may allocate arbitrary size of buffers as long as
snd_pcm_hardware.buffer_bytes_max allows -- which can be quite high,
HD-audio sets 1GB there.
It means that the system may consume a high amount of pages for PCM
buffers, and they are pinned and never swapped out. This can lead to
OOM easily.
For avoiding such a situation, this patch adds the upper limit per
card. Each snd_pcm_lib_malloc_pages() and _free_pages() calls are
tracked and it will return an error if the total amount of buffers
goes over the defined upper limit. The default value is set to 32MB,
which should be really large enough for usual operations.
If larger buffers are needed for any specific usage, it can be
adjusted (also dynamically) via snd_pcm.max_alloc_per_card option.
Setting zero there means no chceck is performed, and again, unlimited
amount of buffers are allowed.
Link: https://lore.kernel.org/r/20200120124423.11862-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This is a preliminary patch to allow const for snd_device_ops
definitions in each driver's code. The ops reference is read-only,
hence it can be declared as const for further optimization.
There should be no functional changes by this patch.
Link: https://lore.kernel.org/r/20200103081714.9560-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Many PCI and other drivers performs snd_pcm_period_elapsed() simply in
its interrupt handler, so the sync_stop operation is just to call
synchronize_irq(). Instead of putting this call multiple times,
introduce the common card->sync_irq field. When this field is set,
PCM core performs synchronize_irq() for sync-stop operation. Each
driver just needs to copy its local IRQ number to card->sync_irq, and
that's all we need.
Link: https://lore.kernel.org/r/20191117085308.23915-8-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Based on 1 normalized pattern(s):
this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license as published by
the free software foundation either version 2 of the license or at
your option any later version this program is distributed in the
hope that it will be useful but without any warranty without even
the implied warranty of merchantability or fitness for a particular
purpose see the gnu general public license for more details you
should have received a copy of the gnu general public license along
with this program if not write to the free software foundation inc
59 temple place suite 330 boston ma 02111 1307 usa
extracted by the scancode license scanner the SPDX license identifier
GPL-2.0-or-later
has been chosen to replace the boilerplate/reference in 1334 file(s).
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Richard Fontana <rfontana@redhat.com>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190527070033.113240726@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The snd_cards[] array holds the card pointers that have been currently
registered, and it's exported for the external modules that may need
to refer a card object. But accessing to this array can be racy
against the driver probe or removal, as the card registration or free
may happen concurrently.
This patch gets rid of the direct access to snd_cards[] array and
provides a helper function to give the card object from the index
number with a refcount management. Then the caller can access to the
given card object safely, and releases it via snd_card_unref().
While we're at it, add a proper comment to snd_card_unref() and make
it an inlined function for type-safety, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The creation of card's id proc file can be moved gracefully into
info.c. Also, the assignment of card->proc_id is superfluous and can
be dropped. So let's do it.
Basically this is no functional change but code refactoring, but one
potential behavior change is that now it returns properly the error
code from snd_info_card_register(), which is a good thing (tm).
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The commit 289ca025ee ("ALSA: Use priority list for managing device
list") changed the way to register/disconnect/free devices via a
single priority list. This helped to make behavior consistent, but it
also changed a slight behavior change: namely, the control device is
registered earlier than others, while it was supposed to be the very
last one.
I've put SNDRV_DEV_CONTROL in the current position as the release of
ctl elements often conflict with the private ctl elements some PCM or
other components may create, which often leads to a double-free.
But, the order of register and disconnect should be indeed fixed as
expected in the early days: the control device gets registered at
last, and disconnected at first.
This patch changes the priority list order to move SNDRV_DEV_CONTROL
as the last guy to assure the register / disconnect order. Meanwhile,
for keeping the messy resource release order, manually treat the
control and lowlevel devices as last freed one.
Additional note:
The lowlevel device is the device where a card driver creates at
probe. And, we still keep the release order control -> lowlevel, as
there might be link from a control element back to a lowlevel object.
Fixes: 289ca025ee ("ALSA: Use priority list for managing device list")
Reported-by: Tzung-Bi Shih <tzungbi@google.com>
Tested-by: Tzung-Bi Shih <tzungbi@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
In case of user unbind ALSA driver during playing back / capturing,
each driver needs to stop and remove it correctly. One note here is
that we can't cancel from remove function in such case, because
unbind operation doesn't check return value from remove function.
So, we *must* stop and remove in this case.
For this purpose, we need to sync (= wait) until the all top-level
operations are canceled at remove function.
For example, snd_card_free() processes the disconnection procedure at
first, then waits for the completion. That's how the hot-unplug works
safely. It's implemented, at least, in the top-level driver removal.
Now for the lower level driver, we need a similar strategy. Notify to
the toplevel for hot-unplug (disconnect in ALSA), and sync with the
stop operation, then continue the rest of its own remove procedure.
This patch adds snd_card_disconnect_sync(), and driver can use it from
remove function.
Note: the "lower level" driver here refers to a middle layer driver
(e.g. ASoC components) that can be unbound freely during operation.
Most of legacy ALSA helper drivers don't have such a problem because
they can't be unbound.
Note#2: snd_card_disconnect_sync() merely calls snd_card_disconnect()
and syncs with closing all pending files. It takes only the files
opened by user-space into account, and doesn't care about object
refcounts. (The latter is handled by snd_card_free() completion call,
BTW.) Also, the function doesn't free resources by itself.
Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Currently we're taking power_lock at each card component for assuring
the power-up sequence, but it doesn't help anything in the
implementation at the moment: it just serializes unnecessarily the
callers, but it doesn't protect about the power state change itself.
It used to have some usefulness in the early days where we managed the
PM manually. But now the suspend/resume core procedure is beyond our
hands, and power_lock lost its meaning.
This patch drops the power_lock from allover the places.
There shouldn't be any issues by this change, as it's no helper
regarding the power state change. Rather we'll get better performance
by removing the serialization; which is the only slight concern of any
behavior change, but it can't be a showstopper, after all.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
At a previous commit, concurrent requests for TLV data are maintained
exclusively between read requests and write/command requests. TLV
callback handlers in each driver has no risk from concurrent access for
reference/change.
In current implementation, 'struct snd_card' has a mutex to control
concurrent accesses to user-defined element sets. This commit obsoletes it.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Several lines in sound/core.h get the kernel-doc warnings like
./include/sound/core.h:323: warning: No description found for parameter '...'
where we use define like foo(x, args...) and "args" isn't mentioned in
the comments. As an easy workaround, use simple __VA_ARGS__ for VLA
in macros.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Currently the info in /proc/interrupts doesn't allow to figure out which
interrupt belongs to which card (HDMI, PCH, ..).
Therefore add card details to the interrupt description.
With the patch the info in /proc/interrupts looks like this:
PCI-MSI 442368-edge snd_hda_intel:card1
PCI-MSI 49152-edge snd_hda_intel:card0
NOTE: this patch adds the new irq_descr field snd_card struct that is
filled automatically at a card object creation. This can be used
generically for other drivers as well. The changes for others will
follow later -- tiwai
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Since each proc entry is freed automatically by the parent, we don't
have to take care of its life cycle any longer. This allows us to
reduce a few more lines of codes.
Acked-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Revive snd_device_disconnect() again so that it can be called from the
individual driver. This time, HD-audio will need it.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
For assigning sysfs entries for a card device from the driver,
introduce a new helper function, snd_card_add_dev_attr(). In this
way, we can avoid the possible race between the device registration
and the sysfs addition / removal.
The driver can pass a new attribute group to add freely. This has to
be called before snd_card_register().
Currently, up to two extra groups can be added. More than that, it'll
return an error.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Since the device is no longer hidden but embedded into each component,
we no longer need snd_get_device(). Let's drop it and relevant codes.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Now that all callers have been replaced with
snd_device_register_for_dev(), let's drop the obsolete device
registration code and concentrate only on the code handling struct
device directly. That said,
- remove the old snd_device_register(),
- rename snd_device_register_for_dev() with snd_device_register(),
- drop superfluous arguments from snd_device_register(),
- change snd_unregister_device() to pass the device pointer directly
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This patch embeds a struct device for the control device into the card
object and avoid the device creation at registration time.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Introduce a new helper function snd_device_initialize() to initialize
the device object for sound devices.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This is a preliminary patch for the further work on embedding struct
device into each sound device instance. It changes
snd_register_device*() helpers to receive the device object directly
for skipping creating a device there.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The user-control put and get handlers as well as the tlv do not protect against
concurrent access from multiple threads. Since the state of the control is not
updated atomically it is possible that either two write operations or a write
and a read operation race against each other. Both can lead to arbitrary memory
disclosure. This patch introduces a new lock that protects user-controls from
concurrent access. Since applications typically access controls sequentially
than in parallel a single lock per card should be fine.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Jaroslav Kysela <perex@perex.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The hda codecs all use this struct and, with an HDA platform driver,
will be able to be built without PCI.
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>