staging: mmal-vchiq: Fix memory leak for vchi_instance 65/246165/1
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 26 Oct 2020 07:37:19 +0000 (16:37 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 26 Oct 2020 07:42:32 +0000 (16:42 +0900)
The vchi_instance is allocated with vchiq_initialise() but never
handled properly. Fix memory leak for the vchi_instance.

This fixes below kmemleak report:
    [<000000002312557f>] kmem_cache_alloc_trace+0x1e0/0x348
    [<000000002ee5d470>] vchiq_initialise+0xd0/0x258
    [<000000009b51d8f4>] vchi_initialise+0x84/0xc8
    [<00000000a58f68c5>] vchiq_mmal_init+0xb0/0x2f0
    [<000000006c68d7bf>] bcm2835_mmal_probe+0x90/0x660
    ...

Change-Id: Ib10f194aa4058b3e39ec0a250fa36fd00daf9feb
Reported-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c

index 61a3593..486e1d2 100644 (file)
@@ -191,6 +191,9 @@ struct vchiq_mmal_instance {
 
        /* ordered workqueue to process all bulk operations */
        struct workqueue_struct *bulk_wq;
+
+       /* Opaque handle for a VCHI instance */
+       VCHI_INSTANCE_T vchi_instance;
 };
 
 static struct mmal_msg_context *
@@ -2086,6 +2089,7 @@ int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
 
        mutex_unlock(&instance->vchiq_mutex);
 
+       vchi_disconnect(instance->vchi_instance);
        flush_workqueue(instance->bulk_wq);
        destroy_workqueue(instance->bulk_wq);
 
@@ -2102,6 +2106,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 VCHI_INSTANCE_T vchi_instance;
        struct service_creation params = {
@@ -2135,17 +2140,21 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
        status = vchi_connect(vchi_instance);
        if (status) {
                pr_err("Failed to connect VCHI instance (status=%d)\n", status);
-               return -EIO;
+               err = -EIO;
+               goto err_disconnect_vchi;
        }
 
        instance = kzalloc(sizeof(*instance), GFP_KERNEL);
 
-       if (!instance)
-               return -ENOMEM;
+       if (!instance) {
+               err = -ENOMEM;
+               goto err_disconnect_vchi;
+       }
 
        mutex_init(&instance->vchiq_mutex);
 
        instance->bulk_scratch = vmalloc(PAGE_SIZE);
+       instance->vchi_instance = vchi_instance;
 
        mutex_init(&instance->context_map_lock);
        idr_init_base(&instance->context_map, 1);
@@ -2176,6 +2185,8 @@ err_close_services:
 err_free:
        vfree(instance->bulk_scratch);
        kfree(instance);
-       return -ENODEV;
+err_disconnect_vchi:
+       vchi_disconnect(vchi_instance);
+       return err;
 }
 EXPORT_SYMBOL_GPL(vchiq_mmal_init);