amlvideo: fix panic when unreg [1/1]
authorjintao xu <jintao.xu@amlogic.com>
Sun, 5 May 2019 11:37:14 +0000 (19:37 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Wed, 15 May 2019 01:38:32 +0000 (18:38 -0700)
PD#OTT-3420

Problem:
panic when vfm unreg.

Solution:
Add mutex in dequeue and unreg

Verify:
U212

Change-Id: I902085aed670fefb519d07ffcc3e896ec0c404dd
Signed-off-by: jintao xu <jintao.xu@amlogic.com>
drivers/amlogic/media/video_processor/video_dev/amlvideo.c
drivers/amlogic/media/video_processor/video_dev/amlvideo.h

index f8528f1..082b3d6 100644 (file)
@@ -229,9 +229,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
        struct vivi_dev *dev = (struct vivi_dev *)private_data;
 
        if (type == VFRAME_EVENT_PROVIDER_UNREG) {
-               if (dev->index != 8)
-                       mutex_lock(&dev->vfpMutex);
                AMLVIDEO_DBG("AML:VFRAME_EVENT_PROVIDER_UNREG\n");
+               mutex_lock(&dev->vf_mutex);
                if (vf_get_receiver(dev->vf_provider_name)) {
                        AMLVIDEO_DBG("unreg:amlvideo\n");
                        vf_unreg_provider(&dev->video_vf_prov);
@@ -241,14 +240,16 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                dev->first_frame = 0;
                vfq_init(&dev->q_ready, AMLVIDEO_POOL_SIZE + 1,
                        &dev->amlvideo_pool_ready[0]);
+               mutex_unlock(&dev->vf_mutex);
        }
        if (type == VFRAME_EVENT_PROVIDER_REG) {
                AMLVIDEO_DBG("AML:VFRAME_EVENT_PROVIDER_REG\n");
+               mutex_lock(&dev->vf_mutex);
 
                dev->vf = NULL;
                dev->first_frame = 0;
                dev->frame_num = 0;
-               mutex_unlock(&dev->vfpMutex);
+               mutex_unlock(&dev->vf_mutex);
        } else if (type == VFRAME_EVENT_PROVIDER_QUREY_STATE) {
                amlvideo_vf_states(&states, dev);
                if (states.buf_avail_num > 0) {
@@ -265,6 +266,7 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                /*break;*/
        } else if (type == VFRAME_EVENT_PROVIDER_START) {
                AMLVIDEO_DBG("AML:VFRAME_EVENT_PROVIDER_START\n");
+               mutex_lock(&dev->vf_mutex);
                if (vf_get_receiver(dev->vf_provider_name)) {
                        struct vframe_receiver_s *aaa = vf_get_receiver(
                                dev->vf_provider_name);
@@ -281,6 +283,7 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                                                VFRAME_EVENT_PROVIDER_START,
                                                NULL);
                }
+               mutex_unlock(&dev->vf_mutex);
        } else if (type == VFRAME_EVENT_PROVIDER_FR_HINT) {
                vf_notify_receiver(dev->vf_provider_name,
                        VFRAME_EVENT_PROVIDER_FR_HINT, data);
@@ -547,15 +550,18 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
        if (!vf_peek(dev->vf_receiver_name))
                return -EAGAIN;
 
+       mutex_lock(&dev->vf_mutex);
+
        dev->vf = vf_get(dev->vf_receiver_name);
        if (!dev->vf) {
                /* printk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
-               mutex_unlock(&dev->vfpMutex);
+               mutex_unlock(&dev->vf_mutex);
                return -EAGAIN;
        }
 
        if (dev->vf->index == 0xFFFFFFFF) {
                pr_info("vidioc_dqbuf: Invalid vf\n");
+               mutex_unlock(&dev->vf_mutex);
                return -EAGAIN;
        }
 
@@ -601,6 +607,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
                p->timecode.flags = dev->vf->height;
        }
        p->sequence = dev->frame_num++;
+       mutex_unlock(&dev->vf_mutex);
 
        vf_notify_receiver(
                        dev->vf_provider_name,
@@ -666,7 +673,6 @@ static int amlvideo_open(struct file *file)
 
        dev->vf = NULL;
        dev->index = 0;
-       mutex_unlock(&dev->vfpMutex);
        mutex_lock(&dev->mutex);
        dev->users++;
        if (dev->users > 1) {
@@ -751,7 +757,6 @@ static int amlvideo_close(struct file *file)
        videobuf_mmap_free(&fh->vb_vidq);
        kfree(fh);
        dev->index = 8;
-       mutex_unlock(&dev->vfpMutex);
 /* if (dev->res) { */
        kfree(dev->res);
        dev->res = NULL;
@@ -879,7 +884,7 @@ static int __init amlvideo_create_instance(int inst)
        /* initialize locks */
        spin_lock_init(&dev->slock);
        mutex_init(&dev->mutex);
-       mutex_init(&dev->vfpMutex);
+       mutex_init(&dev->vf_mutex);
 
        ret = -ENOMEM;
        vfd = video_device_alloc();
index e1ea5c9..8dcb3ef 100644 (file)
@@ -80,7 +80,7 @@ struct vivi_dev {
        struct vframe_s *vf;
        struct vframe_s *amlvideo_pool_ready[AMLVIDEO_POOL_SIZE + 1];
        int index;
-       struct mutex vfpMutex;
+       struct mutex vf_mutex;
        int amlvideo_v4l_num;
        char vf_receiver_name[AMLVIDEO_VF_NAME_SIZE];
        char vf_provider_name[AMLVIDEO_VF_NAME_SIZE];