On Thu, Apr 15, 2021 at 07:14:50PM +0100, Mark Brown wrote:
On Thu, Apr 15, 2021 at 08:01:07PM +0200, Thierry Reding wrote:
This seems to break display support on a Jetson TX2 board for me, though I admittedly don't quite understand how it would be related to display at all. Reverting basically the whole series (because subsequent patches depend on this on) on top of next-20210415, I get working display again.
Given that we got an oops it's probably just memory corruption somewhere.
There's this in the log, which seems to be related:
[ 14.671377] tegra-audio-graph-card sound: too many links [ 14.799645] tegra-audio-graph-card sound: too many links
This looks like an issue? Or perhaps it's just DPCM triggered...
Yeah, as I was looking into this a bit, I noticed that on Tegra186 and later the number of links can go up to 72. I'm not sure why this is wreaking havoc, since presumably the check is there to prevent the array from being overwritten, but apparently it's not. I suspect that the same check might be missing somewhere else.
In any case, I came up with the attached. I don't know how good it is because now the number of links exceeds SNDRV_MINOR_DEVICES, but perhaps that's just irrelevant and that constant was used merely because it was conveniently there.
The patch restores display on Jetson TX2. I can look around a bit if I can find where the boundary checks might be missing so that we gracefully fail rather than corrupting everything.
Thierry
From ba07d30380492661c8fc2677155c9c6230bae2fe Mon Sep 17 00:00:00 2001 From: Thierry Reding treding@nvidia.com Date: Thu, 15 Apr 2021 20:16:09 +0200 Subject: [PATCH] ASoC: simple-card-utils: Increase maximum number of links to 128
On Tegra186 and later, the number of links can go up to 72, so bump the maximum number of links to the next power of two (128).
Fixes: f2138aed231c ("ASoC: simple-card-utils: enable flexible CPU/Codec/Platform") Signed-off-by: Thierry Reding treding@nvidia.com --- include/sound/simple_card_utils.h | 4 +++- sound/soc/generic/audio-graph-card.c | 4 ++-- sound/soc/generic/simple-card.c | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index fac3b832d982..e318a2d4ac44 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -115,10 +115,12 @@ struct asoc_simple_priv { ((codec) = simple_props_to_dai_codec(props, i)); \ (i)++)
+#define SNDRV_MAX_LINKS 128 + struct link_info { int link; /* number of link */ int cpu; /* turn for CPU / Codec */ - struct prop_nums num[SNDRV_MINOR_DEVICES]; + struct prop_nums num[SNDRV_MAX_LINKS]; };
int asoc_simple_parse_daifmt(struct device *dev, diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 0582fe296471..80d065935d9a 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -613,7 +613,7 @@ static int graph_count_noml(struct asoc_simple_priv *priv, { struct device *dev = simple_priv_to_dev(priv);
- if (li->link >= SNDRV_MINOR_DEVICES) { + if (li->link >= SNDRV_MAX_LINKS) { dev_err(dev, "too many links\n"); return -EINVAL; } @@ -636,7 +636,7 @@ static int graph_count_dpcm(struct asoc_simple_priv *priv, { struct device *dev = simple_priv_to_dev(priv);
- if (li->link >= SNDRV_MINOR_DEVICES) { + if (li->link >= SNDRV_MAX_LINKS) { dev_err(dev, "too many links\n"); return -EINVAL; } diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index bf5ddf1ea65f..7ac64fef73c9 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -484,7 +484,7 @@ static int simple_count_noml(struct asoc_simple_priv *priv, struct device_node *codec, struct link_info *li, bool is_top) { - if (li->link >= SNDRV_MINOR_DEVICES) { + if (li->link >= SNDRV_MAX_LINKS) { struct device *dev = simple_priv_to_dev(priv);
dev_err(dev, "too many links\n"); @@ -505,7 +505,7 @@ static int simple_count_dpcm(struct asoc_simple_priv *priv, struct device_node *codec, struct link_info *li, bool is_top) { - if (li->link >= SNDRV_MINOR_DEVICES) { + if (li->link >= SNDRV_MAX_LINKS) { struct device *dev = simple_priv_to_dev(priv);
dev_err(dev, "too many links\n");