summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Baluta <daniel.baluta@nxp.com>2018-10-19 14:09:17 +0300
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:52:05 +0800
commitd50e2b69e8026a22c164c5009aa556652ade723d (patch)
treed92489059a945fa52667ec7bbb3cc37e7c6c279f
parent2cdddf2f2e89c73d7126355fdea7b22a3c12f74e (diff)
MLK-19972-2: ASoC: fsl: dsp: Fix component creation cleanup path
Because we don't correctly free resources when an error occurs on component creation path we can end up with partially initialized components. Freeing such partially initialized components most of the time leads to kernel crashing in pain. Avoid this by making sure we either: * return a fully initialized component, comp->active = true * don't "create" the component at all, comp->active = false Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
-rw-r--r--sound/soc/fsl/fsl_dsp_xaf_api.c23
-rw-r--r--sound/soc/fsl/fsl_dsp_xaf_api.h2
2 files changed, 22 insertions, 3 deletions
diff --git a/sound/soc/fsl/fsl_dsp_xaf_api.c b/sound/soc/fsl/fsl_dsp_xaf_api.c
index f40560b099ad..05d1a1685989 100644
--- a/sound/soc/fsl/fsl_dsp_xaf_api.c
+++ b/sound/soc/fsl/fsl_dsp_xaf_api.c
@@ -233,14 +233,14 @@ int xaf_comp_create(struct xf_client *client, struct xf_proxy *proxy,
ret = xf_load_lib(client, p_handle, &p_comp->codec_wrap_lib);
if (ret) {
dev_err(dsp_priv->dev, "load codec wrap lib error\n");
- return ret;
+ goto err_wrap_load;
}
/* ...load codec lib */
ret = xf_load_lib(client, p_handle, &p_comp->codec_lib);
if (ret) {
dev_err(dsp_priv->dev, "load codec lib error\n");
- return ret;
+ goto err_codec_load;
}
/* ...allocate input buffer */
@@ -248,7 +248,7 @@ int xaf_comp_create(struct xf_client *client, struct xf_proxy *proxy,
XF_POOL_INPUT, &p_comp->inpool);
if (ret) {
dev_err(dsp_priv->dev, "alloc input buf error\n");
- return ret;
+ goto err_pool_alloc;
}
/* ...initialize input buffer pointer */
@@ -256,6 +256,17 @@ int xaf_comp_create(struct xf_client *client, struct xf_proxy *proxy,
p_comp->inptr = xf_buffer_data(buf);
}
+ p_comp->active = true;
+
+ return ret;
+
+err_pool_alloc:
+ xf_unload_lib(client, p_handle, &p_comp->codec_lib);
+err_codec_load:
+ xf_unload_lib(client, p_handle, &p_comp->codec_wrap_lib);
+err_wrap_load:
+ xf_close(client, p_handle);
+
return ret;
}
@@ -266,6 +277,12 @@ int xaf_comp_delete(struct xf_client *client, struct xaf_comp *p_comp)
bool loadlib = true;
u32 ret = 0;
+ if (!p_comp->active)
+ return ret;
+
+ /* mark component as unusable from this point */
+ p_comp->active = false;
+
if (p_comp->comp_type == RENDER_ESAI)
loadlib = false;
diff --git a/sound/soc/fsl/fsl_dsp_xaf_api.h b/sound/soc/fsl/fsl_dsp_xaf_api.h
index 5087b46520d5..d6dc734000aa 100644
--- a/sound/soc/fsl/fsl_dsp_xaf_api.h
+++ b/sound/soc/fsl/fsl_dsp_xaf_api.h
@@ -45,6 +45,8 @@ struct xaf_comp {
struct lib_info codec_lib;
struct lib_info codec_wrap_lib;
+
+ int active; /* component fully initialized */
};
struct xaf_pipeline {