linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] videobuf2-core: add queue_busy/idle queue ops
@ 2017-09-22 12:29 Hans Verkuil
  2017-10-17  6:58 ` Hans Verkuil
  2017-10-18 21:12 ` Laurent Pinchart
  0 siblings, 2 replies; 4+ messages in thread
From: Hans Verkuil @ 2017-09-22 12:29 UTC (permalink / raw)
  To: Linux Media Mailing List; +Cc: Jacob Chen, Laurent Pinchart

Some controls (ROTATE) change the buffer layout. This means that they cannot
be set when buffers are allocated. This can be achieved by calling
v4l2_ctrl_grab(ctrl, true) when the queue becomes busy (i.e. the first buffer
is allocated) and v4l2_ctrl_grab(ctrl, false) when the queue becomes idle (i.e.
the last buffer is released).

However, we do not have such queue ops at the moment. This patch adds a queue_busy
and a queue_idle op.

Note that currently queue_busy returns a void, so it assumes that it can't return
an error.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
Jacob, this has only been compile-tested. It's best if you add this patch to your
rockchip-rga patch series and test it there.
---
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 14f83cecfa92..e8ad0e9f78d2 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -665,6 +665,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
 	}

 	if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
+		num_buffers = q->num_buffers;
 		/*
 		 * We already have buffers allocated, so first check if they
 		 * are not in use and can be freed.
@@ -686,6 +687,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
 		mutex_unlock(&q->mmap_lock);
 		if (ret)
 			return ret;
+		if (num_buffers)
+			call_void_qop(q, queue_idle, q);

 		/*
 		 * In case of REQBUFS(0) return immediately without calling
@@ -752,6 +755,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
 		 */
 	}

+	call_void_qop(q, queue_busy, q);
 	mutex_lock(&q->mmap_lock);
 	q->num_buffers = allocated_buffers;

@@ -762,6 +766,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
 		 */
 		__vb2_queue_free(q, allocated_buffers);
 		mutex_unlock(&q->mmap_lock);
+		call_void_qop(q, queue_idle, q);
 		return ret;
 	}
 	mutex_unlock(&q->mmap_lock);
@@ -842,6 +847,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
 		 */
 	}

+	if (!q->num_buffers)
+		call_void_qop(q, queue_busy, q);
 	mutex_lock(&q->mmap_lock);
 	q->num_buffers += allocated_buffers;

@@ -852,6 +859,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
 		 */
 		__vb2_queue_free(q, allocated_buffers);
 		mutex_unlock(&q->mmap_lock);
+		if (!q->num_buffers)
+			call_void_qop(q, queue_idle, q);
 		return -ENOMEM;
 	}
 	mutex_unlock(&q->mmap_lock);
@@ -2011,11 +2020,15 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read);
 static int __vb2_cleanup_fileio(struct vb2_queue *q);
 void vb2_core_queue_release(struct vb2_queue *q)
 {
+	bool was_busy = vb2_is_busy(q);
+
 	__vb2_cleanup_fileio(q);
 	__vb2_queue_cancel(q);
 	mutex_lock(&q->mmap_lock);
 	__vb2_queue_free(q, q->num_buffers);
 	mutex_unlock(&q->mmap_lock);
+	if (was_busy)
+		call_void_qop(q, queue_idle, q);
 }
 EXPORT_SYMBOL_GPL(vb2_core_queue_release);

diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index cb97c224be73..3aa039fd29ce 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -315,6 +315,10 @@ struct vb2_buffer {
  *			\*num_buffers are being allocated additionally to
  *			q->num_buffers. If either \*num_planes or the requested
  *			sizes are invalid callback must return %-EINVAL.
+ * @queue_busy:		called when the queue becomes busy (i.e. at least one
+ *			buffer has been allocated).
+ * @queue_idle:		called when the last buffer from the queue is released
+ *			and the queue is no longer marked busy.
  * @wait_prepare:	release any locks taken while calling vb2 functions;
  *			it is called before an ioctl needs to wait for a new
  *			buffer to arrive; required to avoid a deadlock in
@@ -380,6 +384,8 @@ struct vb2_ops {
 	int (*queue_setup)(struct vb2_queue *q,
 			   unsigned int *num_buffers, unsigned int *num_planes,
 			   unsigned int sizes[], struct device *alloc_devs[]);
+	void (*queue_busy)(struct vb2_queue *q);
+	void (*queue_idle)(struct vb2_queue *q);

 	void (*wait_prepare)(struct vb2_queue *q);
 	void (*wait_finish)(struct vb2_queue *q);
@@ -547,6 +553,8 @@ struct vb2_queue {
 	 * called. Used to check for unbalanced ops.
 	 */
 	u32				cnt_queue_setup;
+	u32				cnt_queue_busy;
+	u32				cnt_queue_idle;
 	u32				cnt_wait_prepare;
 	u32				cnt_wait_finish;
 	u32				cnt_start_streaming;

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] videobuf2-core: add queue_busy/idle queue ops
  2017-09-22 12:29 [PATCH] videobuf2-core: add queue_busy/idle queue ops Hans Verkuil
@ 2017-10-17  6:58 ` Hans Verkuil
  2017-10-18 21:12 ` Laurent Pinchart
  1 sibling, 0 replies; 4+ messages in thread
From: Hans Verkuil @ 2017-10-17  6:58 UTC (permalink / raw)
  To: Linux Media Mailing List; +Cc: Jacob Chen, Laurent Pinchart

Hi Jacob,

When going through my TODO list with pending patches I came across this one from
a few weeks back. I noticed that your rga patch series didn't pick this up.

Does that mean that the ROTATE control can be changed while streaming without
requiring buffer size changes?

If not, then you will need this patch and update the rga driver.

Regards,

	Hans

On 09/22/2017 02:29 PM, Hans Verkuil wrote:
> Some controls (ROTATE) change the buffer layout. This means that they cannot
> be set when buffers are allocated. This can be achieved by calling
> v4l2_ctrl_grab(ctrl, true) when the queue becomes busy (i.e. the first buffer
> is allocated) and v4l2_ctrl_grab(ctrl, false) when the queue becomes idle (i.e.
> the last buffer is released).
> 
> However, we do not have such queue ops at the moment. This patch adds a queue_busy
> and a queue_idle op.
> 
> Note that currently queue_busy returns a void, so it assumes that it can't return
> an error.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
> Jacob, this has only been compile-tested. It's best if you add this patch to your
> rockchip-rga patch series and test it there.
> ---
> diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
> index 14f83cecfa92..e8ad0e9f78d2 100644
> --- a/drivers/media/v4l2-core/videobuf2-core.c
> +++ b/drivers/media/v4l2-core/videobuf2-core.c
> @@ -665,6 +665,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  	}
> 
>  	if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
> +		num_buffers = q->num_buffers;
>  		/*
>  		 * We already have buffers allocated, so first check if they
>  		 * are not in use and can be freed.
> @@ -686,6 +687,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  		mutex_unlock(&q->mmap_lock);
>  		if (ret)
>  			return ret;
> +		if (num_buffers)
> +			call_void_qop(q, queue_idle, q);
> 
>  		/*
>  		 * In case of REQBUFS(0) return immediately without calling
> @@ -752,6 +755,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  		 */
>  	}
> 
> +	call_void_qop(q, queue_busy, q);
>  	mutex_lock(&q->mmap_lock);
>  	q->num_buffers = allocated_buffers;
> 
> @@ -762,6 +766,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  		 */
>  		__vb2_queue_free(q, allocated_buffers);
>  		mutex_unlock(&q->mmap_lock);
> +		call_void_qop(q, queue_idle, q);
>  		return ret;
>  	}
>  	mutex_unlock(&q->mmap_lock);
> @@ -842,6 +847,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
>  		 */
>  	}
> 
> +	if (!q->num_buffers)
> +		call_void_qop(q, queue_busy, q);
>  	mutex_lock(&q->mmap_lock);
>  	q->num_buffers += allocated_buffers;
> 
> @@ -852,6 +859,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
>  		 */
>  		__vb2_queue_free(q, allocated_buffers);
>  		mutex_unlock(&q->mmap_lock);
> +		if (!q->num_buffers)
> +			call_void_qop(q, queue_idle, q);
>  		return -ENOMEM;
>  	}
>  	mutex_unlock(&q->mmap_lock);
> @@ -2011,11 +2020,15 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read);
>  static int __vb2_cleanup_fileio(struct vb2_queue *q);
>  void vb2_core_queue_release(struct vb2_queue *q)
>  {
> +	bool was_busy = vb2_is_busy(q);
> +
>  	__vb2_cleanup_fileio(q);
>  	__vb2_queue_cancel(q);
>  	mutex_lock(&q->mmap_lock);
>  	__vb2_queue_free(q, q->num_buffers);
>  	mutex_unlock(&q->mmap_lock);
> +	if (was_busy)
> +		call_void_qop(q, queue_idle, q);
>  }
>  EXPORT_SYMBOL_GPL(vb2_core_queue_release);
> 
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index cb97c224be73..3aa039fd29ce 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -315,6 +315,10 @@ struct vb2_buffer {
>   *			\*num_buffers are being allocated additionally to
>   *			q->num_buffers. If either \*num_planes or the requested
>   *			sizes are invalid callback must return %-EINVAL.
> + * @queue_busy:		called when the queue becomes busy (i.e. at least one
> + *			buffer has been allocated).
> + * @queue_idle:		called when the last buffer from the queue is released
> + *			and the queue is no longer marked busy.
>   * @wait_prepare:	release any locks taken while calling vb2 functions;
>   *			it is called before an ioctl needs to wait for a new
>   *			buffer to arrive; required to avoid a deadlock in
> @@ -380,6 +384,8 @@ struct vb2_ops {
>  	int (*queue_setup)(struct vb2_queue *q,
>  			   unsigned int *num_buffers, unsigned int *num_planes,
>  			   unsigned int sizes[], struct device *alloc_devs[]);
> +	void (*queue_busy)(struct vb2_queue *q);
> +	void (*queue_idle)(struct vb2_queue *q);
> 
>  	void (*wait_prepare)(struct vb2_queue *q);
>  	void (*wait_finish)(struct vb2_queue *q);
> @@ -547,6 +553,8 @@ struct vb2_queue {
>  	 * called. Used to check for unbalanced ops.
>  	 */
>  	u32				cnt_queue_setup;
> +	u32				cnt_queue_busy;
> +	u32				cnt_queue_idle;
>  	u32				cnt_wait_prepare;
>  	u32				cnt_wait_finish;
>  	u32				cnt_start_streaming;
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] videobuf2-core: add queue_busy/idle queue ops
  2017-09-22 12:29 [PATCH] videobuf2-core: add queue_busy/idle queue ops Hans Verkuil
  2017-10-17  6:58 ` Hans Verkuil
@ 2017-10-18 21:12 ` Laurent Pinchart
  2017-10-18 21:23   ` Hans Verkuil
  1 sibling, 1 reply; 4+ messages in thread
From: Laurent Pinchart @ 2017-10-18 21:12 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: Linux Media Mailing List, Jacob Chen

Hi Hans,

Thank you for the patch.

On Friday, 22 September 2017 15:29:22 EEST Hans Verkuil wrote:
> Some controls (ROTATE) change the buffer layout. This means that they cannot
> be set when buffers are allocated. This can be achieved by calling
> v4l2_ctrl_grab(ctrl, true) when the queue becomes busy (i.e. the first
> buffer is allocated) and v4l2_ctrl_grab(ctrl, false) when the queue becomes
> idle (i.e. the last buffer is released).
> 
> However, we do not have such queue ops at the moment. This patch adds a
> queue_busy and a queue_idle op.

I wonder if this is the best approach. From a quick look at the patch, and 
without seeing drivers using it, I'm worried those new callbacks will be prone 
to race conditions with control operations. I think an in-depth analysis of 
the issue is needed first, and I'd rather avoid new users of the rotation 
control until we come up with a good way to handle it.

> Note that currently queue_busy returns a void, so it assumes that it can't
> return an error.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
> Jacob, this has only been compile-tested. It's best if you add this patch to
> your rockchip-rga patch series and test it there.
> ---
> diff --git a/drivers/media/v4l2-core/videobuf2-core.c
> b/drivers/media/v4l2-core/videobuf2-core.c index 14f83cecfa92..e8ad0e9f78d2
> 100644
> --- a/drivers/media/v4l2-core/videobuf2-core.c
> +++ b/drivers/media/v4l2-core/videobuf2-core.c
> @@ -665,6 +665,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum
> vb2_memory memory, }
> 
>  	if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
> +		num_buffers = q->num_buffers;
>  		/*
>  		 * We already have buffers allocated, so first check if they
>  		 * are not in use and can be freed.
> @@ -686,6 +687,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum
> vb2_memory memory, mutex_unlock(&q->mmap_lock);
>  		if (ret)
>  			return ret;
> +		if (num_buffers)
> +			call_void_qop(q, queue_idle, q);
> 
>  		/*
>  		 * In case of REQBUFS(0) return immediately without calling
> @@ -752,6 +755,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum
> vb2_memory memory, */
>  	}
> 
> +	call_void_qop(q, queue_busy, q);
>  	mutex_lock(&q->mmap_lock);
>  	q->num_buffers = allocated_buffers;
> 
> @@ -762,6 +766,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum
> vb2_memory memory, */
>  		__vb2_queue_free(q, allocated_buffers);
>  		mutex_unlock(&q->mmap_lock);
> +		call_void_qop(q, queue_idle, q);
>  		return ret;
>  	}
>  	mutex_unlock(&q->mmap_lock);
> @@ -842,6 +847,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum
> vb2_memory memory, */
>  	}
> 
> +	if (!q->num_buffers)
> +		call_void_qop(q, queue_busy, q);
>  	mutex_lock(&q->mmap_lock);
>  	q->num_buffers += allocated_buffers;
> 
> @@ -852,6 +859,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum
> vb2_memory memory, */
>  		__vb2_queue_free(q, allocated_buffers);
>  		mutex_unlock(&q->mmap_lock);
> +		if (!q->num_buffers)
> +			call_void_qop(q, queue_idle, q);
>  		return -ENOMEM;
>  	}
>  	mutex_unlock(&q->mmap_lock);
> @@ -2011,11 +2020,15 @@ static int __vb2_init_fileio(struct vb2_queue *q,
> int read); static int __vb2_cleanup_fileio(struct vb2_queue *q);
>  void vb2_core_queue_release(struct vb2_queue *q)
>  {
> +	bool was_busy = vb2_is_busy(q);
> +
>  	__vb2_cleanup_fileio(q);
>  	__vb2_queue_cancel(q);
>  	mutex_lock(&q->mmap_lock);
>  	__vb2_queue_free(q, q->num_buffers);
>  	mutex_unlock(&q->mmap_lock);
> +	if (was_busy)
> +		call_void_qop(q, queue_idle, q);
>  }
>  EXPORT_SYMBOL_GPL(vb2_core_queue_release);
> 
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index cb97c224be73..3aa039fd29ce 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -315,6 +315,10 @@ struct vb2_buffer {
>   *			\*num_buffers are being allocated additionally to
>   *			q->num_buffers. If either \*num_planes or the requested
>   *			sizes are invalid callback must return %-EINVAL.
> + * @queue_busy:		called when the queue becomes busy (i.e. at least one
> + *			buffer has been allocated).
> + * @queue_idle:		called when the last buffer from the queue is released
> + *			and the queue is no longer marked busy.
>   * @wait_prepare:	release any locks taken while calling vb2 functions;
>   *			it is called before an ioctl needs to wait for a new
>   *			buffer to arrive; required to avoid a deadlock in
> @@ -380,6 +384,8 @@ struct vb2_ops {
>  	int (*queue_setup)(struct vb2_queue *q,
>  			   unsigned int *num_buffers, unsigned int *num_planes,
>  			   unsigned int sizes[], struct device *alloc_devs[]);
> +	void (*queue_busy)(struct vb2_queue *q);
> +	void (*queue_idle)(struct vb2_queue *q);
> 
>  	void (*wait_prepare)(struct vb2_queue *q);
>  	void (*wait_finish)(struct vb2_queue *q);
> @@ -547,6 +553,8 @@ struct vb2_queue {
>  	 * called. Used to check for unbalanced ops.
>  	 */
>  	u32				cnt_queue_setup;
> +	u32				cnt_queue_busy;
> +	u32				cnt_queue_idle;
>  	u32				cnt_wait_prepare;
>  	u32				cnt_wait_finish;
>  	u32				cnt_start_streaming;


-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] videobuf2-core: add queue_busy/idle queue ops
  2017-10-18 21:12 ` Laurent Pinchart
@ 2017-10-18 21:23   ` Hans Verkuil
  0 siblings, 0 replies; 4+ messages in thread
From: Hans Verkuil @ 2017-10-18 21:23 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Linux Media Mailing List, Jacob Chen

On 10/18/2017 11:12 PM, Laurent Pinchart wrote:
> Hi Hans,
> 
> Thank you for the patch.
> 
> On Friday, 22 September 2017 15:29:22 EEST Hans Verkuil wrote:
>> Some controls (ROTATE) change the buffer layout. This means that they cannot
>> be set when buffers are allocated. This can be achieved by calling
>> v4l2_ctrl_grab(ctrl, true) when the queue becomes busy (i.e. the first
>> buffer is allocated) and v4l2_ctrl_grab(ctrl, false) when the queue becomes
>> idle (i.e. the last buffer is released).
>>
>> However, we do not have such queue ops at the moment. This patch adds a
>> queue_busy and a queue_idle op.
> 
> I wonder if this is the best approach. From a quick look at the patch, and 
> without seeing drivers using it, I'm worried those new callbacks will be prone 
> to race conditions with control operations. I think an in-depth analysis of 
> the issue is needed first, and I'd rather avoid new users of the rotation 
> control until we come up with a good way to handle it.

While the queue_busy/idle ops are new, calling v4l2_ctrl_grab() from vb2_queue ops
is not. Typically they are called from the start/stop_streaming ops and have been
for many years.

So I have no worries about race conditions.

Regards,

	Hans

> 
>> Note that currently queue_busy returns a void, so it assumes that it can't
>> return an error.
>>
>> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
>> ---
>> Jacob, this has only been compile-tested. It's best if you add this patch to
>> your rockchip-rga patch series and test it there.
>> ---
>> diff --git a/drivers/media/v4l2-core/videobuf2-core.c
>> b/drivers/media/v4l2-core/videobuf2-core.c index 14f83cecfa92..e8ad0e9f78d2
>> 100644
>> --- a/drivers/media/v4l2-core/videobuf2-core.c
>> +++ b/drivers/media/v4l2-core/videobuf2-core.c
>> @@ -665,6 +665,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum
>> vb2_memory memory, }
>>
>>  	if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
>> +		num_buffers = q->num_buffers;
>>  		/*
>>  		 * We already have buffers allocated, so first check if they
>>  		 * are not in use and can be freed.
>> @@ -686,6 +687,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum
>> vb2_memory memory, mutex_unlock(&q->mmap_lock);
>>  		if (ret)
>>  			return ret;
>> +		if (num_buffers)
>> +			call_void_qop(q, queue_idle, q);
>>
>>  		/*
>>  		 * In case of REQBUFS(0) return immediately without calling
>> @@ -752,6 +755,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum
>> vb2_memory memory, */
>>  	}
>>
>> +	call_void_qop(q, queue_busy, q);
>>  	mutex_lock(&q->mmap_lock);
>>  	q->num_buffers = allocated_buffers;
>>
>> @@ -762,6 +766,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum
>> vb2_memory memory, */
>>  		__vb2_queue_free(q, allocated_buffers);
>>  		mutex_unlock(&q->mmap_lock);
>> +		call_void_qop(q, queue_idle, q);
>>  		return ret;
>>  	}
>>  	mutex_unlock(&q->mmap_lock);
>> @@ -842,6 +847,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum
>> vb2_memory memory, */
>>  	}
>>
>> +	if (!q->num_buffers)
>> +		call_void_qop(q, queue_busy, q);
>>  	mutex_lock(&q->mmap_lock);
>>  	q->num_buffers += allocated_buffers;
>>
>> @@ -852,6 +859,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum
>> vb2_memory memory, */
>>  		__vb2_queue_free(q, allocated_buffers);
>>  		mutex_unlock(&q->mmap_lock);
>> +		if (!q->num_buffers)
>> +			call_void_qop(q, queue_idle, q);
>>  		return -ENOMEM;
>>  	}
>>  	mutex_unlock(&q->mmap_lock);
>> @@ -2011,11 +2020,15 @@ static int __vb2_init_fileio(struct vb2_queue *q,
>> int read); static int __vb2_cleanup_fileio(struct vb2_queue *q);
>>  void vb2_core_queue_release(struct vb2_queue *q)
>>  {
>> +	bool was_busy = vb2_is_busy(q);
>> +
>>  	__vb2_cleanup_fileio(q);
>>  	__vb2_queue_cancel(q);
>>  	mutex_lock(&q->mmap_lock);
>>  	__vb2_queue_free(q, q->num_buffers);
>>  	mutex_unlock(&q->mmap_lock);
>> +	if (was_busy)
>> +		call_void_qop(q, queue_idle, q);
>>  }
>>  EXPORT_SYMBOL_GPL(vb2_core_queue_release);
>>
>> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
>> index cb97c224be73..3aa039fd29ce 100644
>> --- a/include/media/videobuf2-core.h
>> +++ b/include/media/videobuf2-core.h
>> @@ -315,6 +315,10 @@ struct vb2_buffer {
>>   *			\*num_buffers are being allocated additionally to
>>   *			q->num_buffers. If either \*num_planes or the requested
>>   *			sizes are invalid callback must return %-EINVAL.
>> + * @queue_busy:		called when the queue becomes busy (i.e. at least one
>> + *			buffer has been allocated).
>> + * @queue_idle:		called when the last buffer from the queue is released
>> + *			and the queue is no longer marked busy.
>>   * @wait_prepare:	release any locks taken while calling vb2 functions;
>>   *			it is called before an ioctl needs to wait for a new
>>   *			buffer to arrive; required to avoid a deadlock in
>> @@ -380,6 +384,8 @@ struct vb2_ops {
>>  	int (*queue_setup)(struct vb2_queue *q,
>>  			   unsigned int *num_buffers, unsigned int *num_planes,
>>  			   unsigned int sizes[], struct device *alloc_devs[]);
>> +	void (*queue_busy)(struct vb2_queue *q);
>> +	void (*queue_idle)(struct vb2_queue *q);
>>
>>  	void (*wait_prepare)(struct vb2_queue *q);
>>  	void (*wait_finish)(struct vb2_queue *q);
>> @@ -547,6 +553,8 @@ struct vb2_queue {
>>  	 * called. Used to check for unbalanced ops.
>>  	 */
>>  	u32				cnt_queue_setup;
>> +	u32				cnt_queue_busy;
>> +	u32				cnt_queue_idle;
>>  	u32				cnt_wait_prepare;
>>  	u32				cnt_wait_finish;
>>  	u32				cnt_start_streaming;
> 
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-10-18 21:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-22 12:29 [PATCH] videobuf2-core: add queue_busy/idle queue ops Hans Verkuil
2017-10-17  6:58 ` Hans Verkuil
2017-10-18 21:12 ` Laurent Pinchart
2017-10-18 21:23   ` Hans Verkuil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).