[alsa-devel] [PATCH 2/7] ALSA: core: Add managed card creation
Takashi Iwai
tiwai at suse.de
Wed Oct 3 17:37:28 CEST 2018
On Wed, 03 Oct 2018 17:02:59 +0200,
Takashi Sakamoto wrote:
>
> Hi,
>
> On Oct 3 2018 22:14, Takashi Sakamoto wrote:
> > On Oct 3 2018 19:30, Takashi Iwai wrote:
> >> On Wed, 03 Oct 2018 10:12:34 +0200,
> >>> I've investigated to use the new function, 'snd_devm_card_new()', and
> >>> have a concern about timing to release memory object for sound card
> >>> instance (and tailing private data) in error path between calls of the
> >>> function and 'snd_card_register()'.
> >>>
> >>> In the error path, 'snd_card_free()' is called to release instances
> >>> associated to the sound card instance as expected, however memory object
> >>> for the sound card instance is not released yet because in usual cases
> >>> associated device structure does not lost its reference count in this
> >>> timing. It's released when the associated device is removed. This means
> >>> that the memory object remains against its practicality during lifetime
> >>> of the device.
> >>>
> >>> This is not a bug itself, so I have no opposition to this patchset. But
> >>> it's reasonable for us to have a bit time to consider about it, IMO.
> >>
> >> Well, it's exactly same as the usual devm_kzalloc() & co, which have
> >> been already deployed at various places (even you posted a new patch
> >> series for using them :) The card memory is tied with the device, and
> >> it's natural to align with the lifetime of the device.
> >
> > I have this concern against the usage of devres for a long time.
> >
> > A device can be referred by several handlers; e.g. character device
> > driver and kernel driver. An example is USB devices. Userspace
> > applications can transfer message to the device via character device.
> > At the same time, iface driver in kernel land can do the same work.
> >
> > The lifetime of device is apparently different from each of the handler.
> > Even if kernel driver returns negative value in its .probe callback, the
> > other handlers can refer to and use it.
> >
> > If the kernel driver leave the devm-allocated memory in error path, it
> > remains till all of the handler release its reference to the device.
> > Even it the memory objects are maintained by devres, several small parts
> > of kernel logical space is unavailable. This is similar to memory leak,
> > in my view.
>
> I wrote a patch to e06afb87065c (HEAD of 'topic/devres' branch) for this
> purpose. I've not tested thoroughly but expect it solves the above issue.
>
> ======== 8< --------
>
> >From 2ef56174ea3c07eb5d6c2adb60573321c04a02af Mon Sep 17 00:00:00 2001
> From: Takashi Sakamoto <o-takashi at sakamocchi.jp>
> Date: Wed, 3 Oct 2018 23:44:43 +0900
> Subject: [PATCH] ALSA: core: release memory object for sound card immediately
> in error path for a case of devm usage
>
> Drivers can snd_card_free() in error path between calls of
> snd_devm_card_new() and snd_card_register(), In this case,
> memory object for sound card structure is not deallocated
> immediately because it's associated to target device by
> devres framework. The memory object remains till the target
> device is released. This looks like memory leak.
Not really, this is *intentional* and designed behavior.
Imagine the case if you have a device-managed irq handler and a
device-managed IO memory. They are not freed at snd_card_free() call
time, but at a later stage of devres release. Hence the *all*
devres-managed resources have to be released there.
thanks,
Takashi
>
> This commit postpones association of the memory object to
> target device till a call of snd_card_register(). In error
> path, a call of snd_card_free() releases the memory object
> in the last part of snd_card_do_free().
> ---
> sound/core/init.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/sound/core/init.c b/sound/core/init.c
> index 2eade57db4b4..49cb22a735c1 100644
> --- a/sound/core/init.c
> +++ b/sound/core/init.c
> @@ -272,7 +272,6 @@ int snd_devm_card_new(struct device *parent, int idx, const char *xid,
> return err;
> }
>
> - devres_add(parent, card);
> *card_ret = card;
> return 0;
> }
> @@ -569,6 +568,8 @@ static int snd_card_do_free(struct snd_card *card)
> complete(card->release_completion);
> if (!card->managed)
> kfree(card);
> + else if (!devres_find(card->dev, __snd_card_release, NULL, NULL))
> + devres_free(card);
> return 0;
> }
>
> @@ -849,15 +850,6 @@ int snd_card_register(struct snd_card *card)
> if (err < 0)
> return err;
> card->registered = true;
> - } else {
> - if (card->managed)
> - devm_remove_action(card->dev, trigger_card_free, card);
> - }
> -
> - if (card->managed) {
> - err = devm_add_action(card->dev, trigger_card_free, card);
> - if (err < 0)
> - return err;
> }
>
> if ((err = snd_device_register_all(card)) < 0)
> @@ -887,6 +879,14 @@ int snd_card_register(struct snd_card *card)
> if (snd_mixer_oss_notify_callback)
> snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
> #endif
> + if (card->managed &&
> + !devres_find(card->dev, __snd_card_release, NULL, NULL)) {
> + err = devm_add_action(card->dev, trigger_card_free, card);
> + if (err < 0)
> + return err;
> + devres_add(card->dev, card);
> + }
> +
> return 0;
> }
> EXPORT_SYMBOL(snd_card_register);
> --
> 2.17.1
>
>
> Thanks
>
> Takashi Sakamoto
>
More information about the Alsa-devel
mailing list