[media] exynos-gsc: cleanup m2m src and dst vb2 queues on STREAMOFF
authorJavier Martinez Canillas <javier@osg.samsung.com>
Fri, 7 Oct 2016 20:39:19 +0000 (17:39 -0300)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Wed, 16 Nov 2016 18:29:17 +0000 (16:29 -0200)
Media drivers that use the videobuf2 framework have to give back to vb2
all the buffers that received from vb2 using its .buf_queue callback.

But the exynos-gsc driver isn't doing a proper cleanup so vb2 complains
that the number of buffers enqueued and received are not balanced:

WARNING: CPU: 2 PID: 660 at drivers/media/v4l2-core/videobuf2-core.c:1654 __vb2_queue_cancel+0xec/0x150 [videobuf2_core]
Modules linked in: mwifiex_sdio mwifiex uvcvideo exynos_gsc videobuf2_vmalloc s5p_mfc s5p_jpeg
CPU: 2 PID: 660 Comm: lt-gst-validate Not tainted 4.8.0
Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[<c010e24c>] (unwind_backtrace) from [<c010af30>] (show_stack+0x10/0x14)
[<c010af30>] (show_stack) from [<c03291a4>] (dump_stack+0x88/0x9c)
[<c03291a4>] (dump_stack) from [<c011a858>] (__warn+0xe8/0x100)
[<c011a858>] (__warn) from [<c011a920>] (warn_slowpath_null+0x20/0x28)
[<c011a920>] (warn_slowpath_null) from [<bf0b6ed0>] (__vb2_queue_cancel+0xec/0x150 [videobuf2_core])
[<bf0b6ed0>] (__vb2_queue_cancel [videobuf2_core]) from [<bf0b7464>] (vb2_core_streamoff+0x34/0x9c [videobuf2_core])
[<bf0b7464>] (vb2_core_streamoff [videobuf2_core]) from [<bf11b9e8>] (v4l2_m2m_streamoff+0x2c/0xe4 [v4l2_mem2mem])
[<bf11b9e8>] (v4l2_m2m_streamoff [v4l2_mem2mem]) from [<bf01b84c>] (__video_do_ioctl+0x298/0x30c [videodev])
[<bf01b84c>] (__video_do_ioctl [videodev]) from [<bf01b234>] (video_usercopy+0x174/0x4e8 [videodev])
[<bf01b234>] (video_usercopy [videodev]) from [<bf0165c8>] (v4l2_ioctl+0xc4/0xd8 [videodev])
[<bf0165c8>] (v4l2_ioctl [videodev]) from [<c01f291c>] (do_vfs_ioctl+0x9c/0x8f4)
[<c01f291c>] (do_vfs_ioctl) from [<c01f31a8>] (SyS_ioctl+0x34/0x5c)
[<c01f31a8>] (SyS_ioctl) from [<c01078c0>] (ret_fast_syscall+0x0/0x3c)

Fix this by passing back to vb2 all the received buffers that were not
processed.

Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/platform/exynos-gsc/gsc-m2m.c

index c8c0bcec35ed36193e47fbc0a659116cd56fc4cd..f49f24b4462abe62992837f95a1ab1724a6fd695 100644 (file)
@@ -66,12 +66,29 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
        return ret > 0 ? 0 : ret;
 }
 
+static void __gsc_m2m_cleanup_queue(struct gsc_ctx *ctx)
+{
+       struct vb2_v4l2_buffer *src_vb, *dst_vb;
+
+       while (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) > 0) {
+               src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+               v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
+       }
+
+       while (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) > 0) {
+               dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+               v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
+       }
+}
+
 static void gsc_m2m_stop_streaming(struct vb2_queue *q)
 {
        struct gsc_ctx *ctx = q->drv_priv;
 
        __gsc_m2m_job_abort(ctx);
 
+       __gsc_m2m_cleanup_queue(ctx);
+
        pm_runtime_put(&ctx->gsc_dev->pdev->dev);
 }