mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
ASoC: tegra: Fix memory leak in OOT machine driver
Fix a memory leak in the NVIDIA Tegra ASoC machine driver where
allocated DAPM widget lists were never freed. The function
dpcm_runtime_set_dai_fmt() calls snd_soc_dapm_dai_get_connected_widgets()
which allocates memory for a widget list, but was returning without
calling snd_soc_dapm_dai_free_widgets() to free this memory.
The leak was detected by kmemleak:
unreferenced object 0xffff00008fc7e300 (size 192):
comm "alsactl", pid 812, jiffies 4294900395
backtrace:
kmemleak_alloc+0xc0/0xe8
__kmalloc+0x2e0/0x4c8
snd_soc_dapm_dai_get_connected_widgets+0x108/0x2a0
Fix this by using snd_soc_dapm_dai_free_widgets() on
success or failure to ensure the widget list is always freed
before returning.
Bug 5667057
Change-Id: Ied69968884fc0646a3041e54427736ff1fc232ac
Signed-off-by: Sheetal <sheetal@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3500426
(cherry picked from commit 14b3fc2296967968d5972054bff38cf1bf4b518e)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3502770
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-by: Mohan kumar <mkumard@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
42b3ff7b23
commit
f2c7bd17be
@@ -52,17 +52,19 @@ static int dpcm_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
|
|||||||
#else
|
#else
|
||||||
struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
|
struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
|
||||||
#endif
|
#endif
|
||||||
struct snd_soc_dapm_widget_list *list;
|
struct snd_soc_dapm_widget_list *list = NULL;
|
||||||
int stream = SNDRV_PCM_STREAM_PLAYBACK;
|
int stream = SNDRV_PCM_STREAM_PLAYBACK;
|
||||||
struct snd_soc_pcm_runtime *be;
|
struct snd_soc_pcm_runtime *be;
|
||||||
struct snd_soc_dapm_widget *widget;
|
struct snd_soc_dapm_widget *widget;
|
||||||
int i, ret;
|
int i, ret = 0;
|
||||||
|
|
||||||
/* nothing to be done if it is a normal sound card */
|
/* nothing to be done if it is a normal sound card */
|
||||||
if (!rtd->card->component_chaining)
|
if (!rtd->card->component_chaining)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
snd_soc_dapm_dai_get_connected_widgets(dai, stream, &list, NULL);
|
ret = snd_soc_dapm_dai_get_connected_widgets(dai, stream, &list, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
for_each_dapm_widgets(list, i, widget) {
|
for_each_dapm_widgets(list, i, widget) {
|
||||||
if (widget->id != snd_soc_dapm_dai_in &&
|
if (widget->id != snd_soc_dapm_dai_in &&
|
||||||
@@ -75,10 +77,12 @@ static int dpcm_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
|
|||||||
|
|
||||||
ret = snd_soc_runtime_set_dai_fmt(be, fmt);
|
ret = snd_soc_runtime_set_dai_fmt(be, fmt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
out:
|
||||||
|
snd_soc_dapm_dai_free_widgets(&list);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_machine_codec_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
|
static int tegra_machine_codec_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
|
||||||
|
|||||||
Reference in New Issue
Block a user