amlvideo: fix panic when unreg [1/1]
authorjintao xu <jintao.xu@amlogic.com>
Sun, 5 May 2019 11:37:14 +0000 (19:37 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 07:37:23 +0000 (15:37 +0800)
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 2474fbf..e249073 100644 (file)
@@ -234,9 +234,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);
@@ -246,14 +245,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) {
@@ -270,6 +271,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);
@@ -286,6 +288,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);
@@ -555,15 +558,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;
        }
 
@@ -610,6 +616,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,
@@ -675,7 +682,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) {
@@ -767,7 +773,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;
@@ -895,7 +900,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 743243f..4789a1c 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];