[alsa-devel] [PATCH 00/13] ASoC: soc-core cleanup - step 3
Hi Mark
These are soc-core.c cleanup (maybe) step 3. These try to clenaup around kmalloc/kfree related code. Basically these do nothing from technical point of view.
Kuninori Morimoto (13): ASoC: soc-core: move soc_free_pcm_runtime() ASoC: soc-core: merge soc_add_pcm_runtime() into soc_new_pcm_runtime() ASoC: soc-core: call list_del(&rtd->list) at soc_free_pcm_runtime() ASoC: soc-core: create rtd->codec_dais first ASoC: soc-core: merge soc_new_pcm_runtime() and soc_rtd_init() ASoC: soc-core: merge soc_free_pcm_runtime() and soc_rtd_free() ASoC: soc-core: tidyup soc_new_pcm_runtime() alloc order ASoC: soc-core: remove snd_soc_rtdcom_del_all() ASoC: soc-core: use devm_kzalloc() for rtd ASoC: soc-core: remove soc_remove_dai_links() ASoC: soc-core: add soc_setup_card_name() ASoC: soc-core: use devm_xxx for component related resource ASoC: soc-core: setup card->rtd_num at snd_soc_instantiate_card()
include/sound/soc.h | 1 - sound/soc/soc-core.c | 276 +++++++++++++++++++++++++-------------------------- 2 files changed, 138 insertions(+), 139 deletions(-)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
This patch moves soc_free_pcm_runtime() next to soc_new_pcm_runtime(). This is prepare for soc_xxx_pcm_runtime() cleanup.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 35f48e9..2aa5bc7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -355,6 +355,13 @@ EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream);
static const struct snd_soc_ops null_snd_soc_ops;
+static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) +{ + kfree(rtd->codec_dais); + snd_soc_rtdcom_del_all(rtd); + kfree(rtd); +} + static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { @@ -381,13 +388,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( return rtd; }
-static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) -{ - kfree(rtd->codec_dais); - snd_soc_rtdcom_del_all(rtd); - kfree(rtd); -} - static void soc_add_pcm_runtime(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd) {
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
We have soc_new_pcm_runtime() which allocs rtd and its related memory, and soc_add_pcm_runtime() which connects rtd to card.
But we don't need to separate these, we can alloc and connect rtd in the same time.
Current implementation is just makes code complex. This patch merges these into one.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2aa5bc7..4e93d2f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -385,16 +385,12 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( return NULL; }
- return rtd; -} - -static void soc_add_pcm_runtime(struct snd_soc_card *card, - struct snd_soc_pcm_runtime *rtd) -{ /* see for_each_card_rtds */ list_add_tail(&rtd->list, &card->rtd_list); rtd->num = card->num_rtd; card->num_rtd++; + + return rtd; }
static void soc_remove_pcm_runtimes(struct snd_soc_card *card) @@ -930,7 +926,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card, } }
- soc_add_pcm_runtime(card, rtd); return 0;
_err_defer:
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current ALSA SoC is calling list_del(&rtd->list) at (1)
static void soc_remove_pcm_runtimes(...) { ... for_each_card_rtds_safe(card, rtd, _rtd) { (1) list_del(&rtd->list); (2) soc_free_pcm_runtime(rtd); } ... }
But, we will call soc_free_pcm_runtime() after that (2). &rtd->list is connected at soc_new_pcm_runtime(), Thus, it should be disconnected at soc_free_pcm_runtime().
This patch calls list_del(&rtd->list) at soc_free_pcm_runtime().
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4e93d2f..44e1bff 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -359,6 +359,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) { kfree(rtd->codec_dais); snd_soc_rtdcom_del_all(rtd); + list_del(&rtd->list); kfree(rtd); }
@@ -397,10 +398,8 @@ static void soc_remove_pcm_runtimes(struct snd_soc_card *card) { struct snd_soc_pcm_runtime *rtd, *_rtd;
- for_each_card_rtds_safe(card, rtd, _rtd) { - list_del(&rtd->list); + for_each_card_rtds_safe(card, rtd, _rtd) soc_free_pcm_runtime(rtd); - }
card->num_rtd = 0; }
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
soc_new_pcm_runtime() allocs rtd and rtd->codec_dais. This patch allocs both first, and setup these after that. This is prepare for soc_new_pcm_runtime() cleanup.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 44e1bff..fe6cafd 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -372,12 +372,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( if (!rtd) return NULL;
- INIT_LIST_HEAD(&rtd->component_list); - rtd->card = card; - rtd->dai_link = dai_link; - if (!rtd->dai_link->ops) - rtd->dai_link->ops = &null_snd_soc_ops; - rtd->codec_dais = kcalloc(dai_link->num_codecs, sizeof(struct snd_soc_dai *), GFP_KERNEL); @@ -386,6 +380,12 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( return NULL; }
+ INIT_LIST_HEAD(&rtd->component_list); + rtd->card = card; + rtd->dai_link = dai_link; + if (!rtd->dai_link->ops) + rtd->dai_link->ops = &null_snd_soc_ops; + /* see for_each_card_rtds */ list_add_tail(&rtd->list, &card->rtd_list); rtd->num = card->num_rtd;
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
"rtd" is handled by soc_xxx_pcm_runtime(), and "rtd->dev" is handled by soc_rtd_xxx().
There is no reason to separate these, and it makes code complex. We can create these in the same time.
This patch merges soc_rtd_init() into soc_new_pcm_runtime().
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 95 +++++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 42 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index fe6cafd..b550fa9 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -355,8 +355,17 @@ EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream);
static const struct snd_soc_ops null_snd_soc_ops;
+static void soc_release_rtd_dev(struct device *dev) +{ + /* "dev" means "rtd->dev" */ + kfree(dev); +} + static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) { + if (!rtd) + return; + kfree(rtd->codec_dais); snd_soc_rtdcom_del_all(rtd); list_del(&rtd->list); @@ -367,20 +376,54 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { struct snd_soc_pcm_runtime *rtd; + int ret;
+ /* + * for rtd + */ rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL); if (!rtd) - return NULL; + goto free_rtd;
+ /* + * for rtd->codec_dais + */ rtd->codec_dais = kcalloc(dai_link->num_codecs, sizeof(struct snd_soc_dai *), GFP_KERNEL); - if (!rtd->codec_dais) { - kfree(rtd); - return NULL; + if (!rtd->codec_dais) + goto free_rtd; + + /* + * for rtd->dev + */ + rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL); + if (!rtd->dev) + goto free_rtd; + + rtd->dev->parent = card->dev; + rtd->dev->release = soc_release_rtd_dev; + rtd->dev->groups = soc_dev_attr_groups; + + dev_set_name(rtd->dev, "%s", dai_link->name); + dev_set_drvdata(rtd->dev, rtd); + + ret = device_register(rtd->dev); + if (ret < 0) { + put_device(rtd->dev); /* soc_release_rtd_dev */ + rtd->dev = NULL; + goto free_rtd; }
+ /* + * rtd remaining settings + */ INIT_LIST_HEAD(&rtd->component_list); + INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients); + INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients); + INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients); + INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); + rtd->card = card; rtd->dai_link = dai_link; if (!rtd->dai_link->ops) @@ -391,7 +434,13 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( rtd->num = card->num_rtd; card->num_rtd++;
+ rtd->dev_registered = 1; + return rtd; + +free_rtd: + soc_free_pcm_runtime(rtd); + return NULL; }
static void soc_remove_pcm_runtimes(struct snd_soc_card *card) @@ -1420,40 +1469,6 @@ static void soc_rtd_free(struct snd_soc_pcm_runtime *rtd) } }
-static void soc_rtd_release(struct device *dev) -{ - kfree(dev); -} - -static int soc_rtd_init(struct snd_soc_pcm_runtime *rtd, const char *name) -{ - int ret = 0; - - /* register the rtd device */ - rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL); - if (!rtd->dev) - return -ENOMEM; - rtd->dev->parent = rtd->card->dev; - rtd->dev->release = soc_rtd_release; - rtd->dev->groups = soc_dev_attr_groups; - dev_set_name(rtd->dev, "%s", name); - dev_set_drvdata(rtd->dev, rtd); - INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients); - INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients); - INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients); - INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); - ret = device_register(rtd->dev); - if (ret < 0) { - /* calling put_device() here to free the rtd->dev */ - put_device(rtd->dev); - dev_err(rtd->card->dev, - "ASoC: failed to register runtime device: %d\n", ret); - return ret; - } - rtd->dev_registered = 1; - return 0; -} - static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais, struct snd_soc_pcm_runtime *rtd) { @@ -1503,10 +1518,6 @@ static int soc_link_init(struct snd_soc_card *card, return ret; }
- ret = soc_rtd_init(rtd, dai_link->name); - if (ret) - return ret; - /* add DPCM sysfs entries */ soc_dpcm_debugfs_add(rtd);
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
"rtd" is handled by soc_xxx_pcm_runtime(), and "rtd->dev" is handled by soc_rtd_xxx().
There is no reason to separate these, and it makes code complex. We can free these in the same time.
Here soc_rtd_free() (A) which frees rtd->dev is called from soc_remove_link_dais() many times (1). Then, it is using dev_registered flags to avoid multi kfree() (2). This is no longer needed if we can merge these functions.
static void soc_remove_link_dais(...) { ... (1) for_each_comp_order(order) { (1) for_each_card_rtds(card, rtd) {
(A) soc_rtd_free(rtd); ... } } }
(A) static void soc_rtd_free(...) { (2) if (rtd->dev_registered) { /* we don't need to call kfree() for rtd->dev */ device_unregister(rtd->dev); (2) rtd->dev_registered = 0; } }
This patch merges soc_rtd_free() into soc_free_pcm_runtime().
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 1 - sound/soc/soc-core.c | 18 ++---------------- 2 files changed, 2 insertions(+), 17 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index f264c65..d93cb46 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1148,7 +1148,6 @@ struct snd_soc_pcm_runtime { struct list_head component_list; /* list of connected components */
/* bit field */ - unsigned int dev_registered:1; unsigned int pop_wait:1; unsigned int fe_compr:1; /* for Dynamic PCM */ }; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b550fa9..552f460 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -368,6 +368,8 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
kfree(rtd->codec_dais); snd_soc_rtdcom_del_all(rtd); + if (rtd->dev) + device_unregister(rtd->dev); /* soc_release_rtd_dev */ list_del(&rtd->list); kfree(rtd); } @@ -434,8 +436,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( rtd->num = card->num_rtd; card->num_rtd++;
- rtd->dev_registered = 1; - return rtd;
free_rtd: @@ -1169,7 +1169,6 @@ static int soc_probe_dai(struct snd_soc_dai *dai, int order) return 0; }
-static void soc_rtd_free(struct snd_soc_pcm_runtime *rtd); /* remove me */ static void soc_remove_link_dais(struct snd_soc_card *card) { int i; @@ -1179,10 +1178,6 @@ static void soc_remove_link_dais(struct snd_soc_card *card)
for_each_comp_order(order) { for_each_card_rtds(card, rtd) { - - /* finalize rtd device */ - soc_rtd_free(rtd); - /* remove the CODEC DAI */ for_each_rtd_codec_dai(rtd, i, codec_dai) soc_remove_dai(codec_dai, order); @@ -1460,15 +1455,6 @@ void snd_soc_remove_dai_link(struct snd_soc_card *card, } EXPORT_SYMBOL_GPL(snd_soc_remove_dai_link);
-static void soc_rtd_free(struct snd_soc_pcm_runtime *rtd) -{ - if (rtd->dev_registered) { - /* we don't need to call kfree() for rtd->dev */ - device_unregister(rtd->dev); - rtd->dev_registered = 0; - } -} - static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais, struct snd_soc_pcm_runtime *rtd) {
On Mon, Sep 9, 2019 at 7:10 PM Kuninori Morimoto < kuninori.morimoto.gx@renesas.com> wrote:
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
"rtd" is handled by soc_xxx_pcm_runtime(), and "rtd->dev" is handled by soc_rtd_xxx().
There is no reason to separate these, and it makes code complex. We can free these in the same time.
Here soc_rtd_free() (A) which frees rtd->dev is called from soc_remove_link_dais() many times (1). Then, it is using dev_registered flags to avoid multi kfree() (2). This is no longer needed if we can merge these functions.
static void soc_remove_link_dais(...) { ...
(1) for_each_comp_order(order) { (1) for_each_card_rtds(card, rtd) {
(A) soc_rtd_free(rtd); ... } } }
(A) static void soc_rtd_free(...) { (2) if (rtd->dev_registered) { /* we don't need to call kfree() for rtd->dev */ device_unregister(rtd->dev); (2) rtd->dev_registered = 0; } }
This patch merges soc_rtd_free() into soc_free_pcm_runtime().
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
include/sound/soc.h | 1 - sound/soc/soc-core.c | 18 ++---------------- 2 files changed, 2 insertions(+), 17 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index f264c65..d93cb46 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1148,7 +1148,6 @@ struct snd_soc_pcm_runtime { struct list_head component_list; /* list of connected components */
/* bit field */
unsigned int dev_registered:1; unsigned int pop_wait:1; unsigned int fe_compr:1; /* for Dynamic PCM */
}; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b550fa9..552f460 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -368,6 +368,8 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
kfree(rtd->codec_dais); snd_soc_rtdcom_del_all(rtd);
if (rtd->dev)
device_unregister(rtd->dev); /* soc_release_rtd_dev */ list_del(&rtd->list); kfree(rtd);
} @@ -434,8 +436,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( rtd->num = card->num_rtd; card->num_rtd++;
rtd->dev_registered = 1;
return rtd;
free_rtd: @@ -1169,7 +1169,6 @@ static int soc_probe_dai(struct snd_soc_dai *dai, int order) return 0; }
-static void soc_rtd_free(struct snd_soc_pcm_runtime *rtd); /* remove me */ static void soc_remove_link_dais(struct snd_soc_card *card) { int i; @@ -1179,10 +1178,6 @@ static void soc_remove_link_dais(struct snd_soc_card *card)
for_each_comp_order(order) { for_each_card_rtds(card, rtd) {
/* finalize rtd device */
soc_rtd_free(rtd);
/* remove the CODEC DAI */ for_each_rtd_codec_dai(rtd, i, codec_dai) soc_remove_dai(codec_dai, order);
@@ -1460,15 +1455,6 @@ void snd_soc_remove_dai_link(struct snd_soc_card *card, } EXPORT_SYMBOL_GPL(snd_soc_remove_dai_link);
-static void soc_rtd_free(struct snd_soc_pcm_runtime *rtd) -{
if (rtd->dev_registered) {
/* we don't need to call kfree() for rtd->dev */
Morimoto-san,
I think it is useful to keep this comment when you move soc_rtd_free() to soc_free_pcm_runtime().
Thanks, Ranjani
device_unregister(rtd->dev);
rtd->dev_registered = 0;
}
-}
static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais, struct snd_soc_pcm_runtime *rtd) { -- 2.7.4
Alsa-devel mailing list Alsa-devel@alsa-project.org https://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Hi Sridharan
Thank you for your review.
-static void soc_rtd_free(struct snd_soc_pcm_runtime *rtd) -{ - if (rtd->dev_registered) { - /* we don't need to call kfree() for rtd->dev */
Morimoto-san,
I think it is useful to keep this comment when you move soc_rtd_free() to soc_free_pcm_runtime().
Yeah, indeed. In my mind, the comment /* soc_release_rtd_dev */ was almost for it. But, yes, Let's keep above comment too. will fix in v2
+ if (rtd->dev) + device_unregister(rtd->dev); /* soc_release_rtd_dev */
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
This patch allocs dev first at soc_new_pcm_runtime(). This is prepare for rtd->dev, rtd->codec_dais alloc cleanup
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 552f460..d6bc6e2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -125,6 +125,9 @@ static umode_t soc_dev_attr_is_visible(struct kobject *kobj, struct device *dev = kobj_to_dev(kobj); struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
+ if (!rtd) + return 0; + if (attr == &dev_attr_pmdown_time.attr) return attr->mode; /* always visible */ return rtd->num_codecs ? attr->mode : 0; /* enabled only with codec */ @@ -378,15 +381,38 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { struct snd_soc_pcm_runtime *rtd; + struct device *dev; int ret;
/* + * for rtd->dev + */ + dev = kzalloc(sizeof(struct device), GFP_KERNEL); + if (!dev) + return NULL; + + dev->parent = card->dev; + dev->release = soc_release_rtd_dev; + dev->groups = soc_dev_attr_groups; + + dev_set_name(dev, "%s", dai_link->name); + + ret = device_register(dev); + if (ret < 0) { + put_device(dev); /* soc_release_rtd_dev */ + return NULL; + } + + /* * for rtd */ rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL); if (!rtd) goto free_rtd;
+ rtd->dev = dev; + dev_set_drvdata(dev, rtd); + /* * for rtd->codec_dais */ @@ -397,27 +423,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( goto free_rtd;
/* - * for rtd->dev - */ - rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL); - if (!rtd->dev) - goto free_rtd; - - rtd->dev->parent = card->dev; - rtd->dev->release = soc_release_rtd_dev; - rtd->dev->groups = soc_dev_attr_groups; - - dev_set_name(rtd->dev, "%s", dai_link->name); - dev_set_drvdata(rtd->dev, rtd); - - ret = device_register(rtd->dev); - if (ret < 0) { - put_device(rtd->dev); /* soc_release_rtd_dev */ - rtd->dev = NULL; - goto free_rtd; - } - - /* * rtd remaining settings */ INIT_LIST_HEAD(&rtd->component_list);
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
If we can use devm_kzalloc(rtd->dev, xxx) for rtdcom, we don't need to call snd_soc_rtdcom_del_all() for kfree(). This patch uses devm_kzalloc(rtd->dev, xxx) for rtdcom, and remove snd_soc_rtdcom_del_all().
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d6bc6e2..8802287 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -288,28 +288,29 @@ static int snd_soc_rtdcom_add(struct snd_soc_pcm_runtime *rtd, return 0; }
- rtdcom = kmalloc(sizeof(*rtdcom), GFP_KERNEL); + /* + * created rtdcom here will be freed when rtd->dev was freed. + * see + * soc_free_pcm_runtime() :: device_unregister(rtd->dev) + */ + rtdcom = devm_kzalloc(rtd->dev, sizeof(*rtdcom), GFP_KERNEL); if (!rtdcom) return -ENOMEM;
rtdcom->component = component; INIT_LIST_HEAD(&rtdcom->list);
+ /* + * When rtd was freed, created rtdcom here will be + * also freed. + * And we don't need to call list_del(&rtdcom->list) + * when freed, because rtd is also freed. + */ list_add_tail(&rtdcom->list, &rtd->component_list);
return 0; }
-static void snd_soc_rtdcom_del_all(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_rtdcom_list *rtdcom1, *rtdcom2; - - for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) - kfree(rtdcom1); - - INIT_LIST_HEAD(&rtd->component_list); -} - struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd, const char *driver_name) { @@ -370,7 +371,6 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) return;
kfree(rtd->codec_dais); - snd_soc_rtdcom_del_all(rtd); if (rtd->dev) device_unregister(rtd->dev); /* soc_release_rtd_dev */ list_del(&rtd->list);
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current rtd, rtd->dev, rtd->codec_dais are created by normal kzalloc(), but we want to use devm_kzalloc() as much as possible.
Created rtd->dev is registered by device_register() at soc_new_pcm_runtime(), and it will be freed at soc_free_pcm_runtime() by device_unregister().
This means, if we can use devm_kzalloc(rtd->dev, xxx) for rtd / rtd->codec_dais, all these are automatically freed via soc_free_pcm_runtime(). This patch uses devm_kzalloc(rtd->dev, xxx) for rtd / rtd->codec_dais.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 8802287..968cf5c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -370,11 +370,8 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) if (!rtd) return;
- kfree(rtd->codec_dais); - if (rtd->dev) - device_unregister(rtd->dev); /* soc_release_rtd_dev */ list_del(&rtd->list); - kfree(rtd); + device_unregister(rtd->dev); /* soc_release_rtd_dev */ }
static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( @@ -406,7 +403,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( /* * for rtd */ - rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL); + rtd = devm_kzalloc(dev, sizeof(*rtd), GFP_KERNEL); if (!rtd) goto free_rtd;
@@ -416,7 +413,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( /* * for rtd->codec_dais */ - rtd->codec_dais = kcalloc(dai_link->num_codecs, + rtd->codec_dais = devm_kcalloc(dev, dai_link->num_codecs, sizeof(struct snd_soc_dai *), GFP_KERNEL); if (!rtd->codec_dais)
On Mon, Sep 9, 2019 at 7:12 PM Kuninori Morimoto < kuninori.morimoto.gx@renesas.com> wrote:
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current rtd, rtd->dev, rtd->codec_dais are created by normal kzalloc(), but we want to use devm_kzalloc() as much as possible.
Created rtd->dev is registered by device_register() at soc_new_pcm_runtime(), and it will be freed at soc_free_pcm_runtime() by device_unregister().
This means, if we can use devm_kzalloc(rtd->dev, xxx) for rtd / rtd->codec_dais, all these are automatically freed via soc_free_pcm_runtime(). This patch uses devm_kzalloc(rtd->dev, xxx) for rtd / rtd->codec_dais.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
sound/soc/soc-core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 8802287..968cf5c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -370,11 +370,8 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) if (!rtd) return;
kfree(rtd->codec_dais);
if (rtd->dev)
device_unregister(rtd->dev); /* soc_release_rtd_dev */ list_del(&rtd->list);
kfree(rtd);
Morimoto-san,
Just curious, why did you remove the check for if(rtd->dev) here before calling device_unregister()?
Thanks, Ranjani
device_unregister(rtd->dev); /* soc_release_rtd_dev */
}
Hi Sridharan
Thank you for your review
--- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -370,11 +370,8 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) if (!rtd) return; - kfree(rtd->codec_dais); - if (rtd->dev) - device_unregister(rtd->dev); /* soc_release_rtd_dev */ list_del(&rtd->list); - kfree(rtd);
Morimoto-san,
Just curious, why did you remove the check for if(rtd->dev) here before calling device_unregister()?
Thanks, Ranjani
+ device_unregister(rtd->dev); /* soc_release_rtd_dev */ }
Can you check [07/13] patch ? It allocs rtd->dev (as dev) first, and allocs rtd next. This means, if it has rtd, it has rtd->dev.
Here, this function checks rtd pointer. If rtd is not NULL, rtd->dev is also not NULL.
But, indeed it is a littile bit tricky ? Some comment is needed.
Thank you for your help !! Best regards --- Kuninori Morimoto
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
It is easy to read code if it is cleanly using paired function/naming, like start <-> stop, register <-> unregister, etc, etc. But, current ALSA SoC code is very random, unbalance, not paired, etc. It is easy to create bug at the such code, and it will be difficult to debug.
soc_cleanup_card_resources() (a) which is paired function of snd_soc_instantiate_card() (A) is calling soc_remove_dai_links() (*) to remove card related resources, but it is breaking add/remove balance (B)(b)(C)(c)(D)(d), in other words these should be called from soc_cleanup_card_resources() (a) from balance point of view.
More headacke is that it is using original removing method for dai_link even though we already have snd_soc_remove_dai_link() which is the function for it (d).
This patch removes snd_soc_remove_dai_links() and balance up code.
static void soc_remove_dai_links(...) { ... (b) soc_remove_link_dais(card); (c) soc_remove_link_components(card);
for_each_card_links_safe(card, link, _link) { ... /* it should use snd_soc_remove_dai_link() here */ (d) list_del(&link->list); } }
(a) static int soc_cleanup_card_resources(...) { ...
/* remove and free each DAI */ (*) soc_remove_dai_links(card); ... }
(A) static int snd_soc_instantiate_card(struct snd_soc_card *card) { ... /* add predefined DAI links to the list */ for_each_card_prelinks(card, i, dai_link) (B) snd_soc_add_dai_link(card, dai_link); ... /* probe all components used by DAI links on this card */ (C) ret = soc_probe_link_components(card); ... /* probe all DAI links on this card */ (D) ret = soc_probe_link_dais(card); ... }
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 968cf5c..4110114 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1264,23 +1264,6 @@ static int soc_probe_link_components(struct snd_soc_card *card) return 0; }
-static void soc_remove_dai_links(struct snd_soc_card *card) -{ - struct snd_soc_dai_link *link, *_link; - - soc_remove_link_dais(card); - - soc_remove_link_components(card); - - for_each_card_links_safe(card, link, _link) { - if (link->dobj.type == SND_SOC_DOBJ_DAI_LINK) - dev_warn(card->dev, "Topology forgot to remove link %s?\n", - link->name); - - list_del(&link->list); - } -} - static int soc_init_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link) { @@ -1913,6 +1896,8 @@ static void soc_check_tplg_fes(struct snd_soc_card *card)
static void soc_cleanup_card_resources(struct snd_soc_card *card) { + struct snd_soc_dai_link *link, *_link; + /* free the ALSA card at first; this syncs with pending operations */ if (card->snd_card) { snd_card_free(card->snd_card); @@ -1920,7 +1905,12 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card) }
/* remove and free each DAI */ - soc_remove_dai_links(card); + soc_remove_link_dais(card); + soc_remove_link_components(card); + + for_each_card_links_safe(card, link, _link) + snd_soc_remove_dai_link(card, link); + soc_remove_pcm_runtimes(card);
/* remove auxiliary devices */
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
ALSA needs to setup shortname, longname, and driver. These methods are very similar. This patch adds new soc_setup_card_name() and setup these.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 60 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 18 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4110114..ce7793a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1894,6 +1894,42 @@ static void soc_check_tplg_fes(struct snd_soc_card *card) } }
+#define soc_setup_card_name(name, name1, name2, norm) \ + __soc_setup_card_name(name, sizeof(name), name1, name2, norm) +static void __soc_setup_card_name(char *name, int len, + const char *name1, const char *name2, + int normalization) +{ + int i; + + snprintf(name, len, "%s", name1 ? name1 : name2); + + if (!normalization) + return; + + /* + * Name normalization + * + * The driver name is somewhat special, as it's used as a key for + * searches in the user-space. + * + * ex) + * "abcd??efg" -> "abcd__efg" + */ + for (i = 0; i < len; i++) { + switch (name[i]) { + case '_': + case '-': + case '\0': + break; + default: + if (!isalnum(name[i])) + name[i] = '_'; + break; + } + } +} + static void soc_cleanup_card_resources(struct snd_soc_card *card) { struct snd_soc_dai_link *link, *_link; @@ -2059,24 +2095,12 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) /* try to set some sane longname if DMI is available */ snd_soc_set_dmi_name(card, NULL);
- snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), - "%s", card->name); - snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), - "%s", card->long_name ? card->long_name : card->name); - snprintf(card->snd_card->driver, sizeof(card->snd_card->driver), - "%s", card->driver_name ? card->driver_name : card->name); - for (i = 0; i < ARRAY_SIZE(card->snd_card->driver); i++) { - switch (card->snd_card->driver[i]) { - case '_': - case '-': - case '\0': - break; - default: - if (!isalnum(card->snd_card->driver[i])) - card->snd_card->driver[i] = '_'; - break; - } - } + soc_setup_card_name(card->snd_card->shortname, + card->name, NULL, 0); + soc_setup_card_name(card->snd_card->longname, + card->long_name, card->name, 0); + soc_setup_card_name(card->snd_card->driver, + card->driver_name, card->name, 1);
if (card->late_probe) { ret = card->late_probe(card);
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
dai / component related resources are created when component is registered, and it will be freed when component was unregistered. These resources are not re-used after that. This means, we can use devm_xxx for dai / component, without thinking about kfree(). This patch uses devm_xxx for these.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ce7793a..bde885f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2495,7 +2495,7 @@ static char *fmt_single_name(struct device *dev, int *id) *id = 0; }
- return kstrdup(name, GFP_KERNEL); + return devm_kstrdup(dev, name, GFP_KERNEL); }
/* @@ -2512,7 +2512,7 @@ static inline char *fmt_multiple_name(struct device *dev, return NULL; }
- return kstrdup(dai_drv->name, GFP_KERNEL); + return devm_kstrdup(dev, dai_drv->name, GFP_KERNEL); }
/** @@ -2528,8 +2528,6 @@ static void snd_soc_unregister_dais(struct snd_soc_component *component) dev_dbg(component->dev, "ASoC: Unregistered DAI '%s'\n", dai->name); list_del(&dai->list); - kfree(dai->name); - kfree(dai); } }
@@ -2543,7 +2541,7 @@ static struct snd_soc_dai *soc_add_dai(struct snd_soc_component *component,
dev_dbg(dev, "ASoC: dynamically register DAI %s\n", dev_name(dev));
- dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); + dai = devm_kzalloc(dev, sizeof(*dai), GFP_KERNEL); if (dai == NULL) return NULL;
@@ -2565,10 +2563,8 @@ static struct snd_soc_dai *soc_add_dai(struct snd_soc_component *component, else dai->id = component->num_dai; } - if (dai->name == NULL) { - kfree(dai); + if (!dai->name) return NULL; - }
dai->component = component; dai->dev = dev; @@ -2754,7 +2750,6 @@ static void snd_soc_component_add(struct snd_soc_component *component) static void snd_soc_component_cleanup(struct snd_soc_component *component) { snd_soc_unregister_dais(component); - kfree(component->name); }
static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
card->rtd_num is used to count rtd. Initialize it at snd_soc_instantiate_card() is very natural and less confusion.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index bde885f..a5683da 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -451,8 +451,6 @@ static void soc_remove_pcm_runtimes(struct snd_soc_card *card)
for_each_card_rtds_safe(card, rtd, _rtd) soc_free_pcm_runtime(rtd); - - card->num_rtd = 0; }
struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, @@ -1997,6 +1995,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) goto probe_end;
/* add predefined DAI links to the list */ + card->num_rtd = 0; for_each_card_prelinks(card, i, dai_link) { ret = snd_soc_add_dai_link(card, dai_link); if (ret < 0) @@ -2407,7 +2406,6 @@ int snd_soc_register_card(struct snd_soc_card *card) INIT_LIST_HEAD(&card->dapm_dirty); INIT_LIST_HEAD(&card->dobj_list);
- card->num_rtd = 0; card->instantiated = 0; mutex_init(&card->mutex); mutex_init(&card->dapm_mutex);
On Mon, Sep 9, 2019 at 7:15 PM Kuninori Morimoto < kuninori.morimoto.gx@renesas.com> wrote:
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
card->rtd_num is used to count rtd. Initialize it at snd_soc_instantiate_card() is very natural and less confusion.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Thanks for this clean-up, Morimoto-san. Just a couple of minor comments for the series that I have replied on the relevant patches. But overall the series looks good.
Thanks, Ranjani
sound/soc/soc-core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index bde885f..a5683da 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -451,8 +451,6 @@ static void soc_remove_pcm_runtimes(struct snd_soc_card *card)
for_each_card_rtds_safe(card, rtd, _rtd) soc_free_pcm_runtime(rtd);
card->num_rtd = 0;
}
struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, @@ -1997,6 +1995,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) goto probe_end;
/* add predefined DAI links to the list */
card->num_rtd = 0; for_each_card_prelinks(card, i, dai_link) { ret = snd_soc_add_dai_link(card, dai_link); if (ret < 0)
@@ -2407,7 +2406,6 @@ int snd_soc_register_card(struct snd_soc_card *card) INIT_LIST_HEAD(&card->dapm_dirty); INIT_LIST_HEAD(&card->dobj_list);
card->num_rtd = 0; card->instantiated = 0; mutex_init(&card->mutex); mutex_init(&card->dapm_mutex);
-- 2.7.4
Alsa-devel mailing list Alsa-devel@alsa-project.org https://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Hi Sridharan
Thank you for your review.
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> card->rtd_num is used to count rtd. Initialize it at snd_soc_instantiate_card() is very natural and less confusion. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Thanks for this clean-up, Morimoto-san. Just a couple of minor comments for the series that I have replied on the relevant patches. But overall the series looks good.
Thanks ! I will wait for other review, and fixup it in v2 and re-post these.
Thank you for your help !! Best regards --- Kuninori Morimoto
participants (2)
-
Kuninori Morimoto
-
Sridharan, Ranjani