diff mbox series

ASoC: simple-card-utils: Allocate link info structure on heap

Message ID 20210419164117.1422242-1-thierry.reding@gmail.com
State New
Headers show
Series ASoC: simple-card-utils: Allocate link info structure on heap | expand

Commit Message

Thierry Reding April 19, 2021, 4:41 p.m. UTC
From: Thierry Reding <treding@nvidia.com>

struct link_info can grow fairly large and may cause the stack frame
size to be exceeded when allocated on the stack. Some architectures
such as 32-bit ARM, RISC-V or PowerPC have small stack frames where
this causes a compiler warning, so allocate these structures on the
heap instead of the stack.

Fixes: 343e55e71877 ("ASoC: simple-card-utils: Increase maximum number of links to 128")
Reported-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 sound/soc/generic/audio-graph-card.c | 18 +++++++++++-------
 sound/soc/generic/simple-card.c      | 23 +++++++++++++----------
 2 files changed, 24 insertions(+), 17 deletions(-)

Comments

Mark Brown April 20, 2021, 3:06 p.m. UTC | #1
On Mon, 19 Apr 2021 18:41:17 +0200, Thierry Reding wrote:
> struct link_info can grow fairly large and may cause the stack frame
> size to be exceeded when allocated on the stack. Some architectures
> such as 32-bit ARM, RISC-V or PowerPC have small stack frames where
> this causes a compiler warning, so allocate these structures on the
> heap instead of the stack.

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: simple-card-utils: Allocate link info structure on heap
      commit: ec1af6c64db94e4f24e53011a77b2bf2220ae000

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark
diff mbox series

Patch

diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index c7369beee805..e45a560aa9b0 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -548,21 +548,24 @@  static int graph_get_dais_count(struct asoc_simple_priv *priv,
 int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev)
 {
 	struct snd_soc_card *card = simple_priv_to_card(priv);
-	struct link_info li;
+	struct link_info *li;
 	int ret;
 
+	li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL);
+	if (!li)
+		return -ENOMEM;
+
 	card->owner = THIS_MODULE;
 	card->dev = dev;
 
-	memset(&li, 0, sizeof(li));
-	ret = graph_get_dais_count(priv, &li);
+	ret = graph_get_dais_count(priv, li);
 	if (ret < 0)
 		return ret;
 
-	if (!li.link)
+	if (!li->link)
 		return -EINVAL;
 
-	ret = asoc_simple_init_priv(priv, &li);
+	ret = asoc_simple_init_priv(priv, li);
 	if (ret < 0)
 		return ret;
 
@@ -581,8 +584,8 @@  int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev)
 	if (ret < 0)
 		return ret;
 
-	memset(&li, 0, sizeof(li));
-	ret = graph_for_each_link(priv, &li,
+	memset(li, 0, sizeof(*li));
+	ret = graph_for_each_link(priv, li,
 				  graph_dai_link_of,
 				  graph_dai_link_of_dpcm);
 	if (ret < 0)
@@ -600,6 +603,7 @@  int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev)
 	if (ret < 0)
 		goto err;
 
+	devm_kfree(dev, li);
 	return 0;
 
 err:
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 8b9964d25757..ca27cb9ff9e1 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -442,10 +442,9 @@  static int simple_for_each_link(struct asoc_simple_priv *priv,
 	return ret;
 }
 
-static int simple_parse_of(struct asoc_simple_priv *priv)
+static int simple_parse_of(struct asoc_simple_priv *priv, struct link_info *li)
 {
 	struct snd_soc_card *card = simple_priv_to_card(priv);
-	struct link_info li;
 	int ret;
 
 	ret = asoc_simple_parse_widgets(card, PREFIX);
@@ -461,8 +460,8 @@  static int simple_parse_of(struct asoc_simple_priv *priv)
 		return ret;
 
 	/* Single/Muti DAI link(s) & New style of DT node */
-	memset(&li, 0, sizeof(li));
-	ret = simple_for_each_link(priv, &li,
+	memset(li, 0, sizeof(*li));
+	ret = simple_for_each_link(priv, li,
 				   simple_dai_link_of,
 				   simple_dai_link_of_dpcm);
 	if (ret < 0)
@@ -612,7 +611,7 @@  static int asoc_simple_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct snd_soc_card *card;
-	struct link_info li;
+	struct link_info *li;
 	int ret;
 
 	/* Allocate the private data and the DAI link array */
@@ -625,21 +624,24 @@  static int asoc_simple_probe(struct platform_device *pdev)
 	card->dev		= dev;
 	card->probe		= simple_soc_probe;
 
-	memset(&li, 0, sizeof(li));
-	ret = simple_get_dais_count(priv, &li);
+	li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL);
+	if (!li)
+		return -ENOMEM;
+
+	ret = simple_get_dais_count(priv, li);
 	if (ret < 0)
 		return ret;
 
-	if (!li.link)
+	if (!li->link)
 		return -EINVAL;
 
-	ret = asoc_simple_init_priv(priv, &li);
+	ret = asoc_simple_init_priv(priv, li);
 	if (ret < 0)
 		return ret;
 
 	if (np && of_device_is_available(np)) {
 
-		ret = simple_parse_of(priv);
+		ret = simple_parse_of(priv, li);
 		if (ret < 0) {
 			if (ret != -EPROBE_DEFER)
 				dev_err(dev, "parse error %d\n", ret);
@@ -698,6 +700,7 @@  static int asoc_simple_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err;
 
+	devm_kfree(dev, li);
 	return 0;
 err:
 	asoc_simple_clean_reference(card);