From: Seung-Woo Kim sw0312.kim@samsung.com
[ Upstream commit b6ae84d648954fae096d94faea1ddb6518b27841 ]
The vchiq_instance is allocated with vchiq_initialise() but never freed properly. Fix memory leak for the vchiq_instance.
Reported-by: Jaehoon Chung jh80.chung@samsung.com Signed-off-by: Seung-Woo Kim sw0312.kim@samsung.com Link: https://lore.kernel.org/r/1603706150-10806-1-git-send-email-sw0312.kim@samsu... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../vc04_services/vchiq-mmal/mmal-vchiq.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index e798d494f00ff..bbf033ca47362 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -179,6 +179,9 @@ struct vchiq_mmal_instance {
/* ordered workqueue to process all bulk operations */ struct workqueue_struct *bulk_wq; + + /* handle for a vchiq instance */ + struct vchiq_instance *vchiq_instance; };
static struct mmal_msg_context * @@ -1840,6 +1843,7 @@ int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
mutex_unlock(&instance->vchiq_mutex);
+ vchiq_shutdown(instance->vchiq_instance); flush_workqueue(instance->bulk_wq); destroy_workqueue(instance->bulk_wq);
@@ -1856,6 +1860,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_finalise); int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) { int status; + int err = -ENODEV; struct vchiq_mmal_instance *instance; static struct vchiq_instance *vchiq_instance; struct vchiq_service_params params = { @@ -1890,17 +1895,21 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) status = vchiq_connect(vchiq_instance); if (status) { pr_err("Failed to connect VCHI instance (status=%d)\n", status); - return -EIO; + err = -EIO; + goto err_shutdown_vchiq; }
instance = kzalloc(sizeof(*instance), GFP_KERNEL);
- if (!instance) - return -ENOMEM; + if (!instance) { + err = -ENOMEM; + goto err_shutdown_vchiq; + }
mutex_init(&instance->vchiq_mutex);
instance->bulk_scratch = vmalloc(PAGE_SIZE); + instance->vchiq_instance = vchiq_instance;
mutex_init(&instance->context_map_lock); idr_init_base(&instance->context_map, 1); @@ -1932,7 +1941,9 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) err_free: vfree(instance->bulk_scratch); kfree(instance); - return -ENODEV; +err_shutdown_vchiq: + vchiq_shutdown(vchiq_instance); + return err; } EXPORT_SYMBOL_GPL(vchiq_mmal_init);