diff mbox

[v2,2/3] s5p-g2d: Remove unrequired wait in .job_abort

Message ID 20180618043852.13293-3-ezequiel@collabora.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ezequiel Garcia June 18, 2018, 4:38 a.m. UTC
As per the documentation, job_abort is not required
to wait until the current job finishes. It is redundant
to do so, as the core will perform the wait operation.

Remove the wait infrastructure completely.

Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Kamil Debski <kamil@wypas.org>
Cc: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
 drivers/media/platform/s5p-g2d/g2d.c | 11 -----------
 drivers/media/platform/s5p-g2d/g2d.h |  1 -
 2 files changed, 12 deletions(-)

Comments

Hans Verkuil July 4, 2018, 8:04 a.m. UTC | #1
On 18/06/18 06:38, Ezequiel Garcia wrote:
> As per the documentation, job_abort is not required
> to wait until the current job finishes. It is redundant
> to do so, as the core will perform the wait operation.
> 
> Remove the wait infrastructure completely.

Sylwester, can you review this?

Thanks!

	Hans

> 
> Cc: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Kamil Debski <kamil@wypas.org>
> Cc: Andrzej Hajda <a.hajda@samsung.com>
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> ---
>  drivers/media/platform/s5p-g2d/g2d.c | 11 -----------
>  drivers/media/platform/s5p-g2d/g2d.h |  1 -
>  2 files changed, 12 deletions(-)
> 
> diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
> index 66aa8cf1d048..e98708883413 100644
> --- a/drivers/media/platform/s5p-g2d/g2d.c
> +++ b/drivers/media/platform/s5p-g2d/g2d.c
> @@ -483,15 +483,6 @@ static int vidioc_s_crop(struct file *file, void *prv, const struct v4l2_crop *c
>  
>  static void job_abort(void *prv)
>  {
> -	struct g2d_ctx *ctx = prv;
> -	struct g2d_dev *dev = ctx->dev;
> -
> -	if (dev->curr == NULL) /* No job currently running */
> -		return;
> -
> -	wait_event_timeout(dev->irq_queue,
> -			   dev->curr == NULL,
> -			   msecs_to_jiffies(G2D_TIMEOUT));
>  }
>  
>  static void device_run(void *prv)
> @@ -563,7 +554,6 @@ static irqreturn_t g2d_isr(int irq, void *prv)
>  	v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
>  
>  	dev->curr = NULL;
> -	wake_up(&dev->irq_queue);
>  	return IRQ_HANDLED;
>  }
>  
> @@ -633,7 +623,6 @@ static int g2d_probe(struct platform_device *pdev)
>  	spin_lock_init(&dev->ctrl_lock);
>  	mutex_init(&dev->mutex);
>  	atomic_set(&dev->num_inst, 0);
> -	init_waitqueue_head(&dev->irq_queue);
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  
> diff --git a/drivers/media/platform/s5p-g2d/g2d.h b/drivers/media/platform/s5p-g2d/g2d.h
> index dd812b557e87..9ffb458a1b93 100644
> --- a/drivers/media/platform/s5p-g2d/g2d.h
> +++ b/drivers/media/platform/s5p-g2d/g2d.h
> @@ -31,7 +31,6 @@ struct g2d_dev {
>  	struct g2d_ctx		*curr;
>  	struct g2d_variant	*variant;
>  	int irq;
> -	wait_queue_head_t	irq_queue;
>  };
>  
>  struct g2d_frame {
>
Sylwester Nawrocki July 6, 2018, 11:09 a.m. UTC | #2
Hi,

On 07/04/2018 10:04 AM, Hans Verkuil wrote:
> On 18/06/18 06:38, Ezequiel Garcia wrote:
>> As per the documentation, job_abort is not required
>> to wait until the current job finishes. It is redundant
>> to do so, as the core will perform the wait operation.

Could you elaborate how the core ensures DMA operation is not in progress
after VIDIOC_STREAMOFF, VIDIOC_DQBUF with this patch applied?

>> Remove the wait infrastructure completely.
> 
> Sylwester, can you review this?

Thanks for forwarding Hans!

>> Cc: Kyungmin Park <kyungmin.park@samsung.com>
>> Cc: Kamil Debski <kamil@wypas.org>
>> Cc: Andrzej Hajda <a.hajda@samsung.com>
>> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
>> ---
>>   drivers/media/platform/s5p-g2d/g2d.c | 11 -----------
>>   drivers/media/platform/s5p-g2d/g2d.h |  1 -
>>   2 files changed, 12 deletions(-)
>>
>> diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
>> index 66aa8cf1d048..e98708883413 100644
>> --- a/drivers/media/platform/s5p-g2d/g2d.c
>> +++ b/drivers/media/platform/s5p-g2d/g2d.c
>> @@ -483,15 +483,6 @@ static int vidioc_s_crop(struct file *file, void *prv, const struct v4l2_crop *c
>>   
>>   static void job_abort(void *prv)
>>   {
>> -	struct g2d_ctx *ctx = prv;
>> -	struct g2d_dev *dev = ctx->dev;
>> -
>> -	if (dev->curr == NULL) /* No job currently running */
>> -		return;
>> -
>> -	wait_event_timeout(dev->irq_queue,
>> -			   dev->curr == NULL,
>> -			   msecs_to_jiffies(G2D_TIMEOUT));

I think after this patch there will be a potential race condition possible,
we could have the hardware DMA and CPU writing to same buffer with sequence like:
...
QBUF
STREAMON
STREAMOFF
DQBUF 
CPU accessing the buffer  <--  at this point G2D DMA could still be writing
to an already dequeued buffer. Image processing can take few miliseconds, it should
be fairly easy to trigger such a condition.

Not saying about DMA being still in progress after device file handle is closed,
but that's something that deserves a separate patch. It seems there is a bug in 
the driver as there is no call to v4l2_m2m_ctx_release()in the device fops release() 
callback.

I think we could remove the s5p-g2d driver altogether as the functionality is covered
by the exynos DRM IPP driver (drivers/gpu/drm/exynos).

>>   }
>>   
>>   static void device_run(void *prv)
>> @@ -563,7 +554,6 @@ static irqreturn_t g2d_isr(int irq, void *prv)
>>   	v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
>>   
>>   	dev->curr = NULL;
>> -	wake_up(&dev->irq_queue);
>>   	return IRQ_HANDLED;
>>   }

--
Regards,
Sylwester
Ezequiel Garcia July 6, 2018, 1:43 p.m. UTC | #3
On Fri, 2018-07-06 at 13:09 +0200, Sylwester Nawrocki wrote:
> Hi,
> 
> On 07/04/2018 10:04 AM, Hans Verkuil wrote:
> > On 18/06/18 06:38, Ezequiel Garcia wrote:
> > > As per the documentation, job_abort is not required
> > > to wait until the current job finishes. It is redundant
> > > to do so, as the core will perform the wait operation.
> 
> Could you elaborate how the core ensures DMA operation is not in
> progress
> after VIDIOC_STREAMOFF, VIDIOC_DQBUF with this patch applied?
> 

Well, .streamoff is handled by v4l2_m2m_streamoff, which
guarantees that no job is running by calling v4l2_m2m_cancel_job.

The call chain goes like this:

vidioc_streamoff
  v4l2_m2m_ioctl_streamoff
    v4l2_m2m_streamoff
      v4l2_m2m_cancel_job
        wait_event(m2m_ctx->finished, ...);

The wait_event() wakes up by v4l2_m2m_job_finish(),
which is called by g2d_isr after marking the buffers
as done.

The reason why I haven't elaborated this in the commit log
is because it's documented in .job_abort declaration.
 
> > > Remove the wait infrastructure completely.
> > 
> > Sylwester, can you review this?
> 
> Thanks for forwarding Hans!
> 
> > > Cc: Kyungmin Park <kyungmin.park@samsung.com>
> > > Cc: Kamil Debski <kamil@wypas.org>
> > > Cc: Andrzej Hajda <a.hajda@samsung.com>
> > > Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> > > ---
> > >   drivers/media/platform/s5p-g2d/g2d.c | 11 -----------
> > >   drivers/media/platform/s5p-g2d/g2d.h |  1 -
> > >   2 files changed, 12 deletions(-)
> > > 
> > > diff --git a/drivers/media/platform/s5p-g2d/g2d.c
> > > b/drivers/media/platform/s5p-g2d/g2d.c
> > > index 66aa8cf1d048..e98708883413 100644
> > > --- a/drivers/media/platform/s5p-g2d/g2d.c
> > > +++ b/drivers/media/platform/s5p-g2d/g2d.c
> > > @@ -483,15 +483,6 @@ static int vidioc_s_crop(struct file *file,
> > > void *prv, const struct v4l2_crop *c
> > >   
> > >   static void job_abort(void *prv)
> > >   {
> > > -	struct g2d_ctx *ctx = prv;
> > > -	struct g2d_dev *dev = ctx->dev;
> > > -
> > > -	if (dev->curr == NULL) /* No job currently running */
> > > -		return;
> > > -
> > > -	wait_event_timeout(dev->irq_queue,
> > > -			   dev->curr == NULL,
> > > -			   msecs_to_jiffies(G2D_TIMEOUT));
> 
> I think after this patch there will be a potential race condition
> possible,
> we could have the hardware DMA and CPU writing to same buffer with
> sequence like:
> ...
> QBUF
> STREAMON
> STREAMOFF
> DQBUF 
> CPU accessing the buffer  <--  at this point G2D DMA could still be
> writing
> to an already dequeued buffer. Image processing can take few
> miliseconds, it should
> be fairly easy to trigger such a condition.
> 

I don't think this is the case, as I've explained above. This commit
merely removes a redundant wait, as job_abort simply waits the
interrupt handler to complete, and that is the purpose of
v4l2_m2m_job_finish.

It only makes sense to implement job_abort if you can actually stop
the current DMA. If you can only wait for it to complete, then it's not
needed.

> Not saying about DMA being still in progress after device file handle
> is closed,
> but that's something that deserves a separate patch. It seems there
> is a bug in 
> the driver as there is no call to v4l2_m2m_ctx_release()in the device
> fops release() 
> callback.
> 

Yes, that seems correct. Should be fixed in a separate patch.

> I think we could remove the s5p-g2d driver altogether as the
> functionality is covered
> by the exynos DRM IPP driver (drivers/gpu/drm/exynos).
> 

That I'll leave for you to decide :-)

The intention of this series is simply to make job_abort optional,
and remove those drivers that implement job_abort as a wait-for-
current-job.

Thanks for reviewing!
Eze
Sylwester Nawrocki July 6, 2018, 8:28 p.m. UTC | #4
On 07/06/2018 03:43 PM, Ezequiel Garcia wrote:

>> Could you elaborate how the core ensures DMA operation is not in
>> progress
>> after VIDIOC_STREAMOFF, VIDIOC_DQBUF with this patch applied?
>>
> 
> Well, .streamoff is handled by v4l2_m2m_streamoff, which
> guarantees that no job is running by calling v4l2_m2m_cancel_job.
> 
> The call chain goes like this:
> 
> vidioc_streamoff
>    v4l2_m2m_ioctl_streamoff
>      v4l2_m2m_streamoff
>        v4l2_m2m_cancel_job
>          wait_event(m2m_ctx->finished, ...);
> 
> The wait_event() wakes up by v4l2_m2m_job_finish(),
> which is called by g2d_isr after marking the buffers
> as done.
> 
> The reason why I haven't elaborated this in the commit log
> is because it's documented in .job_abort declaration.

Indeed, you are right, job_abort implementation can be safely removed
in this case. As it is it doesn't help to handle cases when the HW gets
stuck and refuses to generate an interrupt. The rcar_jpu seems to be
addressing such situation properly though.

>>>> diff --git a/drivers/media/platform/s5p-g2d/g2d.c
>>>> b/drivers/media/platform/s5p-g2d/g2d.c
>>>> index 66aa8cf1d048..e98708883413 100644
>>>> --- a/drivers/media/platform/s5p-g2d/g2d.c
>>>> +++ b/drivers/media/platform/s5p-g2d/g2d.c
>>>> @@ -483,15 +483,6 @@ static int vidioc_s_crop(struct file *file,
>>>> void *prv, const struct v4l2_crop *c
>>>>    
>>>>    static void job_abort(void *prv)
>>>>    {
>>>> -	struct g2d_ctx *ctx = prv;
>>>> -	struct g2d_dev *dev = ctx->dev;
>>>> -
>>>> -	if (dev->curr == NULL) /* No job currently running */
>>>> -		return;
>>>> -
>>>> -	wait_event_timeout(dev->irq_queue,
>>>> -			   dev->curr == NULL,
>>>> -			   msecs_to_jiffies(G2D_TIMEOUT));
>>
>> I think after this patch there will be a potential race condition
>> possible,
>> we could have the hardware DMA and CPU writing to same buffer with
>> sequence like:
>> ...
>> QBUF
>> STREAMON
>> STREAMOFF
>> DQBUF
>> CPU accessing the buffer  <--  at this point G2D DMA could still be
>> writing
>> to an already dequeued buffer. Image processing can take few
>> miliseconds, it should
>> be fairly easy to trigger such a condition.
>>
> 
> I don't think this is the case, as I've explained above. This commit
> merely removes a redundant wait, as job_abort simply waits the
> interrupt handler to complete, and that is the purpose of
> v4l2_m2m_job_finish.
> 
> It only makes sense to implement job_abort if you can actually stop
> the current DMA. If you can only wait for it to complete, then it's not
> needed.

Agreed.

> The intention of this series is simply to make job_abort optional,
> and remove those drivers that implement job_abort as a wait-for-
> current-job.

Sure, thanks for your effort.

--
Regards,
Sylwester
diff mbox

Patch

diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index 66aa8cf1d048..e98708883413 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -483,15 +483,6 @@  static int vidioc_s_crop(struct file *file, void *prv, const struct v4l2_crop *c
 
 static void job_abort(void *prv)
 {
-	struct g2d_ctx *ctx = prv;
-	struct g2d_dev *dev = ctx->dev;
-
-	if (dev->curr == NULL) /* No job currently running */
-		return;
-
-	wait_event_timeout(dev->irq_queue,
-			   dev->curr == NULL,
-			   msecs_to_jiffies(G2D_TIMEOUT));
 }
 
 static void device_run(void *prv)
@@ -563,7 +554,6 @@  static irqreturn_t g2d_isr(int irq, void *prv)
 	v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
 
 	dev->curr = NULL;
-	wake_up(&dev->irq_queue);
 	return IRQ_HANDLED;
 }
 
@@ -633,7 +623,6 @@  static int g2d_probe(struct platform_device *pdev)
 	spin_lock_init(&dev->ctrl_lock);
 	mutex_init(&dev->mutex);
 	atomic_set(&dev->num_inst, 0);
-	init_waitqueue_head(&dev->irq_queue);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
diff --git a/drivers/media/platform/s5p-g2d/g2d.h b/drivers/media/platform/s5p-g2d/g2d.h
index dd812b557e87..9ffb458a1b93 100644
--- a/drivers/media/platform/s5p-g2d/g2d.h
+++ b/drivers/media/platform/s5p-g2d/g2d.h
@@ -31,7 +31,6 @@  struct g2d_dev {
 	struct g2d_ctx		*curr;
 	struct g2d_variant	*variant;
 	int irq;
-	wait_queue_head_t	irq_queue;
 };
 
 struct g2d_frame {