Re: [RFCv2 PATCH 01/10] vb2: add debugging code to check for unbalanced ops.

2014-02-13 Thread Hans Verkuil
On 02/13/14 09:01, Pawel Osciak wrote:
> Hi Hans,
> Thanks for the patch. I'm really happy to see this, it's a great idea
> and it will be very useful.
> 
> Two comments:
> - What do you think about moving the debug stuff to something like
> videobuf2-debug.{c,h} instead?

It's not quite worth it at the moment IMHO.

> - At this point vb2_buffer_done() shouldn't be required to be balanced
> with buf_queue(). I know later patches in this series will require it,
> but at this point it's not true. Perhaps we should move this to the
> 8th patch or after it? I don't feel too strong about this though.

I disagree with you here. It has always been required, except nobody noticed
it. Without the call to vb2_buffer_done the finish memop will never be called.

That's always been wrong.

Regards,

Hans

> 
> One more nit inline.
> 
> But in general:
> 
> Acked-by: Pawel Osciak 
> 
> 
> On Thu, Feb 6, 2014 at 8:02 PM, Hans Verkuil  wrote:
>> From: Hans Verkuil 
>>
>> When a vb2_queue is freed check if all the mem_ops and queue ops were 
>> balanced.
>> So the number of calls to e.g. buf_finish has to match the number of calls to
>> buf_prepare, etc.
>>
>> This code is only enabled if CONFIG_VIDEO_ADV_DEBUG is set.
>>
>> Signed-off-by: Hans Verkuil 
>> ---
>>  drivers/media/v4l2-core/videobuf2-core.c | 233 
>> ---
>>  include/media/videobuf2-core.h   |  43 ++
>>  2 files changed, 226 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
>> b/drivers/media/v4l2-core/videobuf2-core.c
>> index 5a5fb7f..07b58bd 100644
>> --- a/drivers/media/v4l2-core/videobuf2-core.c
>> +++ b/drivers/media/v4l2-core/videobuf2-core.c
>> @@ -33,12 +33,63 @@ module_param(debug, int, 0644);
>> printk(KERN_DEBUG "vb2: " fmt, ## arg); \
>> } while (0)
>>
>> -#define call_memop(q, op, args...) \
>> -   (((q)->mem_ops->op) ?   \
>> -   ((q)->mem_ops->op(args)) : 0)
>> +#ifdef CONFIG_VIDEO_ADV_DEBUG
>> +
>> +/*
>> + * If advanced debugging is on, then count how often each op is called,
>> + * which can either be per-buffer or per-queue.
>> + *
>> + * If the op failed then the 'fail_' variant is called to decrease the
>> + * counter. That makes it easy to check that the 'init' and 'cleanup'
>> + * (and variations thereof) stay balanced.
>> + */
>> +
>> +#define call_memop(vb, op, args...)\
>> +({ \
>> +   struct vb2_queue *_q = (vb)->vb2_queue; \
>> +   dprintk(2, "call_memop(%p, %d, %s)%s\n",\
>> +   _q, (vb)->v4l2_buf.index, #op,  \
>> +   _q->mem_ops->op ? "" : " (nop)");   \
>> +   (vb)->cnt_mem_ ## op++; \
>> +   _q->mem_ops->op ? _q->mem_ops->op(args) : 0;\
>> +})
>> +#define fail_memop(vb, op) ((vb)->cnt_mem_ ## op--)
>> +
>> +#define call_qop(q, op, args...)   \
>> +({ \
>> +   dprintk(2, "call_qop(%p, %s)%s\n", q, #op,  \
>> +   (q)->ops->op ? "" : " (nop)");  \
>> +   (q)->cnt_ ## op++;  \
>> +   (q)->ops->op ? (q)->ops->op(args) : 0;  \
>> +})
>> +#define fail_qop(q, op) ((q)->cnt_ ## op--)
>> +
>> +#define call_vb_qop(vb, op, args...)   \
>> +({ \
>> +   struct vb2_queue *_q = (vb)->vb2_queue; \
>> +   dprintk(2, "call_vb_qop(%p, %d, %s)%s\n",   \
>> +   _q, (vb)->v4l2_buf.index, #op,  \
>> +   _q->ops->op ? "" : " (nop)");   \
>> +   (vb)->cnt_ ## op++; \
>> +   _q->ops->op ? _q->ops->op(args) : 0;\
>> +})
>> +#define fail_vb_qop(vb, op) ((vb)->cnt_ ## op--)
>> +
>> +#else
>> +
>> +#define call_memop(vb, op, args...)\
>> +   ((vb)->vb2_queue->mem_ops->op ? (vb)->vb2_queue->mem_ops->op(args) : 
>> 0)
>> +#define fail_memop(vb, op)
>>
>>  #define call_qop(q, op, args...)   \
>> -   (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
>> +   ((q)->ops->op ? (q)->ops->op(args) : 0)
>> +#define fail_qop(q, op)
>> +
>> +#define call_vb_qop(vb, op, args...)   \
>> +   ((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0)
>> +#define fail_vb_qop(vb, op)
>> +
>> +#endif
>>
>>  #define V4L2

Re: [RFCv2 PATCH 01/10] vb2: add debugging code to check for unbalanced ops.

2014-02-13 Thread Pawel Osciak
Hi Hans,
Thanks for the patch. I'm really happy to see this, it's a great idea
and it will be very useful.

Two comments:
- What do you think about moving the debug stuff to something like
videobuf2-debug.{c,h} instead?
- At this point vb2_buffer_done() shouldn't be required to be balanced
with buf_queue(). I know later patches in this series will require it,
but at this point it's not true. Perhaps we should move this to the
8th patch or after it? I don't feel too strong about this though.

One more nit inline.

But in general:

Acked-by: Pawel Osciak 


On Thu, Feb 6, 2014 at 8:02 PM, Hans Verkuil  wrote:
> From: Hans Verkuil 
>
> When a vb2_queue is freed check if all the mem_ops and queue ops were 
> balanced.
> So the number of calls to e.g. buf_finish has to match the number of calls to
> buf_prepare, etc.
>
> This code is only enabled if CONFIG_VIDEO_ADV_DEBUG is set.
>
> Signed-off-by: Hans Verkuil 
> ---
>  drivers/media/v4l2-core/videobuf2-core.c | 233 
> ---
>  include/media/videobuf2-core.h   |  43 ++
>  2 files changed, 226 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
> b/drivers/media/v4l2-core/videobuf2-core.c
> index 5a5fb7f..07b58bd 100644
> --- a/drivers/media/v4l2-core/videobuf2-core.c
> +++ b/drivers/media/v4l2-core/videobuf2-core.c
> @@ -33,12 +33,63 @@ module_param(debug, int, 0644);
> printk(KERN_DEBUG "vb2: " fmt, ## arg); \
> } while (0)
>
> -#define call_memop(q, op, args...) \
> -   (((q)->mem_ops->op) ?   \
> -   ((q)->mem_ops->op(args)) : 0)
> +#ifdef CONFIG_VIDEO_ADV_DEBUG
> +
> +/*
> + * If advanced debugging is on, then count how often each op is called,
> + * which can either be per-buffer or per-queue.
> + *
> + * If the op failed then the 'fail_' variant is called to decrease the
> + * counter. That makes it easy to check that the 'init' and 'cleanup'
> + * (and variations thereof) stay balanced.
> + */
> +
> +#define call_memop(vb, op, args...)\
> +({ \
> +   struct vb2_queue *_q = (vb)->vb2_queue; \
> +   dprintk(2, "call_memop(%p, %d, %s)%s\n",\
> +   _q, (vb)->v4l2_buf.index, #op,  \
> +   _q->mem_ops->op ? "" : " (nop)");   \
> +   (vb)->cnt_mem_ ## op++; \
> +   _q->mem_ops->op ? _q->mem_ops->op(args) : 0;\
> +})
> +#define fail_memop(vb, op) ((vb)->cnt_mem_ ## op--)
> +
> +#define call_qop(q, op, args...)   \
> +({ \
> +   dprintk(2, "call_qop(%p, %s)%s\n", q, #op,  \
> +   (q)->ops->op ? "" : " (nop)");  \
> +   (q)->cnt_ ## op++;  \
> +   (q)->ops->op ? (q)->ops->op(args) : 0;  \
> +})
> +#define fail_qop(q, op) ((q)->cnt_ ## op--)
> +
> +#define call_vb_qop(vb, op, args...)   \
> +({ \
> +   struct vb2_queue *_q = (vb)->vb2_queue; \
> +   dprintk(2, "call_vb_qop(%p, %d, %s)%s\n",   \
> +   _q, (vb)->v4l2_buf.index, #op,  \
> +   _q->ops->op ? "" : " (nop)");   \
> +   (vb)->cnt_ ## op++; \
> +   _q->ops->op ? _q->ops->op(args) : 0;\
> +})
> +#define fail_vb_qop(vb, op) ((vb)->cnt_ ## op--)
> +
> +#else
> +
> +#define call_memop(vb, op, args...)\
> +   ((vb)->vb2_queue->mem_ops->op ? (vb)->vb2_queue->mem_ops->op(args) : 
> 0)
> +#define fail_memop(vb, op)
>
>  #define call_qop(q, op, args...)   \
> -   (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
> +   ((q)->ops->op ? (q)->ops->op(args) : 0)
> +#define fail_qop(q, op)
> +
> +#define call_vb_qop(vb, op, args...)   \
> +   ((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0)
> +#define fail_vb_qop(vb, op)
> +
> +#endif
>
>  #define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED 
> | \
>  V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
> @@ -61,7 +112,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
> for (plane = 0; plane < vb->num_planes; ++plane) {
> unsigned long size = PAGE_ALIGN(q->plane_sizes[plane]);
>
> -   mem_priv = call_memop(q, alloc, q->alloc_c

[RFCv2 PATCH 01/10] vb2: add debugging code to check for unbalanced ops.

2014-02-06 Thread Hans Verkuil
From: Hans Verkuil 

When a vb2_queue is freed check if all the mem_ops and queue ops were balanced.
So the number of calls to e.g. buf_finish has to match the number of calls to
buf_prepare, etc.

This code is only enabled if CONFIG_VIDEO_ADV_DEBUG is set.

Signed-off-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-core.c | 233 ---
 include/media/videobuf2-core.h   |  43 ++
 2 files changed, 226 insertions(+), 50 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 5a5fb7f..07b58bd 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -33,12 +33,63 @@ module_param(debug, int, 0644);
printk(KERN_DEBUG "vb2: " fmt, ## arg); \
} while (0)
 
-#define call_memop(q, op, args...) \
-   (((q)->mem_ops->op) ?   \
-   ((q)->mem_ops->op(args)) : 0)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+/*
+ * If advanced debugging is on, then count how often each op is called,
+ * which can either be per-buffer or per-queue.
+ *
+ * If the op failed then the 'fail_' variant is called to decrease the
+ * counter. That makes it easy to check that the 'init' and 'cleanup'
+ * (and variations thereof) stay balanced.
+ */
+
+#define call_memop(vb, op, args...)\
+({ \
+   struct vb2_queue *_q = (vb)->vb2_queue; \
+   dprintk(2, "call_memop(%p, %d, %s)%s\n",\
+   _q, (vb)->v4l2_buf.index, #op,  \
+   _q->mem_ops->op ? "" : " (nop)");   \
+   (vb)->cnt_mem_ ## op++; \
+   _q->mem_ops->op ? _q->mem_ops->op(args) : 0;\
+})
+#define fail_memop(vb, op) ((vb)->cnt_mem_ ## op--)
+
+#define call_qop(q, op, args...)   \
+({ \
+   dprintk(2, "call_qop(%p, %s)%s\n", q, #op,  \
+   (q)->ops->op ? "" : " (nop)");  \
+   (q)->cnt_ ## op++;  \
+   (q)->ops->op ? (q)->ops->op(args) : 0;  \
+})
+#define fail_qop(q, op) ((q)->cnt_ ## op--)
+
+#define call_vb_qop(vb, op, args...)   \
+({ \
+   struct vb2_queue *_q = (vb)->vb2_queue; \
+   dprintk(2, "call_vb_qop(%p, %d, %s)%s\n",   \
+   _q, (vb)->v4l2_buf.index, #op,  \
+   _q->ops->op ? "" : " (nop)");   \
+   (vb)->cnt_ ## op++; \
+   _q->ops->op ? _q->ops->op(args) : 0;\
+})
+#define fail_vb_qop(vb, op) ((vb)->cnt_ ## op--)
+
+#else
+
+#define call_memop(vb, op, args...)\
+   ((vb)->vb2_queue->mem_ops->op ? (vb)->vb2_queue->mem_ops->op(args) : 0)
+#define fail_memop(vb, op)
 
 #define call_qop(q, op, args...)   \
-   (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
+   ((q)->ops->op ? (q)->ops->op(args) : 0)
+#define fail_qop(q, op)
+
+#define call_vb_qop(vb, op, args...)   \
+   ((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0)
+#define fail_vb_qop(vb, op)
+
+#endif
 
 #define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
 V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
@@ -61,7 +112,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
for (plane = 0; plane < vb->num_planes; ++plane) {
unsigned long size = PAGE_ALIGN(q->plane_sizes[plane]);
 
-   mem_priv = call_memop(q, alloc, q->alloc_ctx[plane],
+   mem_priv = call_memop(vb, alloc, q->alloc_ctx[plane],
  size, q->gfp_flags);
if (IS_ERR_OR_NULL(mem_priv))
goto free;
@@ -73,9 +124,10 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 
return 0;
 free:
+   fail_memop(vb, alloc);
/* Free already allocated memory if one of the allocations failed */
for (; plane > 0; --plane) {
-   call_memop(q, put, vb->planes[plane - 1].mem_priv);
+   call_memop(vb, put, vb->planes[plane - 1].mem_priv);
vb->planes[plane - 1].mem_priv = NULL;
}
 
@@ -87,11 +139,10 @@ free:
  */
 static void __vb2_buf_mem_free(struct vb2_buffer *vb)
 {
-   struct vb2_queue *q = vb->vb2_