From 54b03424a7ef37e3dc8c6b75d7d10998056aa31a Mon Sep 17 00:00:00 2001 From: Alan Kwong Date: Thu, 3 Nov 2016 14:18:41 -0400 Subject: [PATCH] msm: sde: add buf_finish callback to clear last fd Fd is tunneled using userptr memory type to v4l2 rotator driver. Fd can assume the same value between multiple qbuf but with the underlying mapping modified. However, v4l2 assumes that if userptr of the same value are passed in, the underlying buffer is the same and will bypass memory mapping callback. This will cause problem for fd tunneling because the obsolete mapping is used. To ensure buffer mapping, add buf_finish callback to clear last fd value before dequeuing buffer back to user client. This will force the next queue buffer command to invoke memory mapping callback since the incoming fd value is different from the reset value. CRs-Fixed: 1084634 Change-Id: I932a58fc633918b151959fcbe320668a87dbc49c Signed-off-by: Alan Kwong --- .../msm/sde/rotator/sde_rotator_dev.c | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c index b88f03ce89ae..08075ae90507 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c @@ -304,6 +304,39 @@ static void sde_rotator_buf_queue(struct vb2_buffer *vb) v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); } +/* + * sde_rotator_buf_finish - vb2_ops buf_finish to finalize buffer before going + * back to user space + * @vb: Pointer to vb2 buffer struct. + */ +static void sde_rotator_buf_finish(struct vb2_buffer *vb) +{ + struct sde_rotator_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + int i; + + SDEDEV_DBG(ctx->rot_dev->dev, + "buf_finish t:%d i:%d s:%d m:%u np:%d up:%lu\n", + vb->type, vb->index, vb->state, + vb->vb2_queue->memory, + vb->num_planes, + vb->planes[0].m.userptr); + + if (vb->vb2_queue->memory != VB2_MEMORY_USERPTR) + return; + + /* + * We use userptr to tunnel fd, and fd can be the same across qbuf + * even though the underlying buffer is different. Since vb2 layer + * optimizes memory mapping for userptr by first checking if userptr + * has changed, it will not trigger put_userptr if fd value does + * not change. In order to force buffer release, we need to clear + * userptr when the current buffer is done and ready to go back to + * user mode. Since 0 is a valid fd, reset userptr to -1 instead. + */ + for (i = 0; i < vb->num_planes; i++) + vb->planes[i].m.userptr = ~0; +} + /* * sde_rotator_return_all_buffers - Return all buffers with the given status. * @q: Pointer to vb2 buffer queue struct. @@ -460,6 +493,7 @@ static struct vb2_ops sde_rotator_vb2_q_ops = { .stop_streaming = sde_rotator_stop_streaming, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, + .buf_finish = sde_rotator_buf_finish, }; /*