[PATCH v11 01/19] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2017-06-15 Thread Stanimir Varbanov
this add functions for:
  - remove buffers from src/dst queue by index
  - remove exact buffer from src/dst queue

also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.

Signed-off-by: Stanimir Varbanov 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 37 ++
 include/media/v4l2-mem2mem.h   | 92 ++
 2 files changed, 129 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..f62e68aa04c4 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
 
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf)
+{
+   struct v4l2_m2m_buffer *b;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+   list_del(>list);
+   q_ctx->num_rdy--;
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_buf);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+   struct v4l2_m2m_buffer *b, *tmp;
+   struct vb2_v4l2_buffer *ret = NULL;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
+   if (b->vb.vb2_buf.index == idx) {
+   list_del(>list);
+   q_ctx->num_rdy--;
+   ret = >vb;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
 /*
  * Scheduling handlers
  */
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..e157d5c9b224 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,47 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
v4l2_m2m_ctx *m2m_ctx)
 }
 
 /**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
  * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
  *
  * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
@@ -488,6 +529,57 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
v4l2_m2m_ctx *m2m_ctx)
return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
 }
 
+/**
+ * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ * @vbuf: the buffer to be removed
+ */
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the 
list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+   v4l2_m2m_buf_remove_by_buf(_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove_by_buf() - take off exact destination buffer from 
the
+ * list of ready 

[PATCH v10 01/18] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2017-06-12 Thread Stanimir Varbanov
this add functions for:
  - remove buffers from src/dst queue by index
  - remove exact buffer from src/dst queue

also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.

Signed-off-by: Stanimir Varbanov 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 37 ++
 include/media/v4l2-mem2mem.h   | 92 ++
 2 files changed, 129 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..f62e68aa04c4 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
 
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf)
+{
+   struct v4l2_m2m_buffer *b;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+   list_del(>list);
+   q_ctx->num_rdy--;
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_buf);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+   struct v4l2_m2m_buffer *b, *tmp;
+   struct vb2_v4l2_buffer *ret = NULL;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
+   if (b->vb.vb2_buf.index == idx) {
+   list_del(>list);
+   q_ctx->num_rdy--;
+   ret = >vb;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
 /*
  * Scheduling handlers
  */
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..e157d5c9b224 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,47 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
v4l2_m2m_ctx *m2m_ctx)
 }
 
 /**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
  * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
  *
  * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
@@ -488,6 +529,57 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
v4l2_m2m_ctx *m2m_ctx)
return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
 }
 
+/**
+ * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ * @vbuf: the buffer to be removed
+ */
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the 
list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+   v4l2_m2m_buf_remove_by_buf(_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove_by_buf() - take off exact destination buffer from 
the
+ * list of ready 

[PATCH v9 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2017-05-09 Thread Stanimir Varbanov
this add functions for:
  - remove buffers from src/dst queue by index
  - remove exact buffer from src/dst queue

also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.

Reviewed-by: Hans Verkuil 
Signed-off-by: Stanimir Varbanov 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 37 ++
 include/media/v4l2-mem2mem.h   | 92 ++
 2 files changed, 129 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..f62e68aa04c4 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
 
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf)
+{
+   struct v4l2_m2m_buffer *b;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+   list_del(>list);
+   q_ctx->num_rdy--;
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_buf);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+   struct v4l2_m2m_buffer *b, *tmp;
+   struct vb2_v4l2_buffer *ret = NULL;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
+   if (b->vb.vb2_buf.index == idx) {
+   list_del(>list);
+   q_ctx->num_rdy--;
+   ret = >vb;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
 /*
  * Scheduling handlers
  */
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..e157d5c9b224 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,47 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
v4l2_m2m_ctx *m2m_ctx)
 }
 
 /**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
  * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
  *
  * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
@@ -488,6 +529,57 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
v4l2_m2m_ctx *m2m_ctx)
return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
 }
 
+/**
+ * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ * @vbuf: the buffer to be removed
+ */
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the 
list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+   v4l2_m2m_buf_remove_by_buf(_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove_by_buf() - take off exact 

Re: [PATCH v8 02/10] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2017-05-05 Thread Hans Verkuil
On 04/28/17 11:13, Stanimir Varbanov wrote:
> this add functions for:
>   - remove buffers from src/dst queue by index
>   - remove exact buffer from src/dst queue
> 
> also extends m2m API to iterate over a list of src/dst buffers
> in safely and non-safely manner.
> 
> Signed-off-by: Stanimir Varbanov 

Reviewed-by: Hans Verkuil 

Thanks!

Hans

> ---
>  drivers/media/v4l2-core/v4l2-mem2mem.c | 37 ++
>  include/media/v4l2-mem2mem.h   | 92 
> ++
>  2 files changed, 129 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
> b/drivers/media/v4l2-core/v4l2-mem2mem.c
> index 6bc27e7b2a33..f62e68aa04c4 100644
> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> @@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx 
> *q_ctx)
>  }
>  EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
>  
> +void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
> + struct vb2_v4l2_buffer *vbuf)
> +{
> + struct v4l2_m2m_buffer *b;
> + unsigned long flags;
> +
> + spin_lock_irqsave(_ctx->rdy_spinlock, flags);
> + b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
> + list_del(>list);
> + q_ctx->num_rdy--;
> + spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
> +}
> +EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_buf);
> +
> +struct vb2_v4l2_buffer *
> +v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int 
> idx)
> +
> +{
> + struct v4l2_m2m_buffer *b, *tmp;
> + struct vb2_v4l2_buffer *ret = NULL;
> + unsigned long flags;
> +
> + spin_lock_irqsave(_ctx->rdy_spinlock, flags);
> + list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
> + if (b->vb.vb2_buf.index == idx) {
> + list_del(>list);
> + q_ctx->num_rdy--;
> + ret = >vb;
> + break;
> + }
> + }
> + spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
> +
>  /*
>   * Scheduling handlers
>   */
> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> index 3ccd01bd245e..e157d5c9b224 100644
> --- a/include/media/v4l2-mem2mem.h
> +++ b/include/media/v4l2-mem2mem.h
> @@ -437,6 +437,47 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
> v4l2_m2m_ctx *m2m_ctx)
>  }
>  
>  /**
> + * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
> + * buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> + * @b: current buffer of type struct v4l2_m2m_buffer
> + */
> +#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)\
> + list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> + * @b: current buffer of type struct v4l2_m2m_buffer
> + */
> +#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)\
> + list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination 
> ready
> + * buffers safely
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> + * @b: current buffer of type struct v4l2_m2m_buffer
> + * @n: used as temporary storage
> + */
> +#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)\
> + list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
> + * buffers safely
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> + * @b: current buffer of type struct v4l2_m2m_buffer
> + * @n: used as temporary storage
> + */
> +#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)\
> + list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
> +
> +/**
>   * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
>   *
>   * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> @@ -488,6 +529,57 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
> v4l2_m2m_ctx *m2m_ctx)
>   return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
>  }
>  
> +/**
> + * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of 
> ready
> + * buffers
> + *
> + * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
> + * @vbuf: the buffer to be removed
> + */
> +void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
> + struct vb2_v4l2_buffer *vbuf);
> +
> +/**
> + * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the 
> list
> + * of ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by 

[PATCH v8 02/10] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2017-04-28 Thread Stanimir Varbanov
this add functions for:
  - remove buffers from src/dst queue by index
  - remove exact buffer from src/dst queue

also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.

Signed-off-by: Stanimir Varbanov 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 37 ++
 include/media/v4l2-mem2mem.h   | 92 ++
 2 files changed, 129 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..f62e68aa04c4 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
 
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf)
+{
+   struct v4l2_m2m_buffer *b;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+   list_del(>list);
+   q_ctx->num_rdy--;
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_buf);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+   struct v4l2_m2m_buffer *b, *tmp;
+   struct vb2_v4l2_buffer *ret = NULL;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
+   if (b->vb.vb2_buf.index == idx) {
+   list_del(>list);
+   q_ctx->num_rdy--;
+   ret = >vb;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
 /*
  * Scheduling handlers
  */
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..e157d5c9b224 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,47 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
v4l2_m2m_ctx *m2m_ctx)
 }
 
 /**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
  * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
  *
  * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
@@ -488,6 +529,57 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
v4l2_m2m_ctx *m2m_ctx)
return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
 }
 
+/**
+ * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ * @vbuf: the buffer to be removed
+ */
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the 
list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+   v4l2_m2m_buf_remove_by_buf(_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove_by_buf() - take off exact destination buffer from 
the
+ * list of ready 

[PATCH v7 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2017-03-13 Thread Stanimir Varbanov
this add functions for:
  - remove buffers from src/dst queue by index
  - remove exact buffer from src/dst queue

also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.

Signed-off-by: Stanimir Varbanov 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 37 ++
 include/media/v4l2-mem2mem.h   | 92 ++
 2 files changed, 129 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..f62e68aa04c4 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
 
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf)
+{
+   struct v4l2_m2m_buffer *b;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+   list_del(>list);
+   q_ctx->num_rdy--;
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_buf);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+   struct v4l2_m2m_buffer *b, *tmp;
+   struct vb2_v4l2_buffer *ret = NULL;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
+   if (b->vb.vb2_buf.index == idx) {
+   list_del(>list);
+   q_ctx->num_rdy--;
+   ret = >vb;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
 /*
  * Scheduling handlers
  */
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..e157d5c9b224 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,47 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
v4l2_m2m_ctx *m2m_ctx)
 }
 
 /**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
  * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
  *
  * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
@@ -488,6 +529,57 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
v4l2_m2m_ctx *m2m_ctx)
return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
 }
 
+/**
+ * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ * @vbuf: the buffer to be removed
+ */
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the 
list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+   v4l2_m2m_buf_remove_by_buf(_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove_by_buf() - take off exact destination buffer from 
the
+ * list of ready 

[PATCH v6 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2017-02-07 Thread Stanimir Varbanov
this add functions for:
  - remove buffers from src/dst queue by index
  - remove exact buffer from src/dst queue

also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.

Signed-off-by: Stanimir Varbanov 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 37 ++
 include/media/v4l2-mem2mem.h   | 92 ++
 2 files changed, 129 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..f62e68aa04c4 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
 
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf)
+{
+   struct v4l2_m2m_buffer *b;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+   list_del(>list);
+   q_ctx->num_rdy--;
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_buf);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+   struct v4l2_m2m_buffer *b, *tmp;
+   struct vb2_v4l2_buffer *ret = NULL;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
+   if (b->vb.vb2_buf.index == idx) {
+   list_del(>list);
+   q_ctx->num_rdy--;
+   ret = >vb;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
 /*
  * Scheduling handlers
  */
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..e157d5c9b224 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,47 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
v4l2_m2m_ctx *m2m_ctx)
 }
 
 /**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
  * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
  *
  * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
@@ -488,6 +529,57 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
v4l2_m2m_ctx *m2m_ctx)
return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
 }
 
+/**
+ * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ * @vbuf: the buffer to be removed
+ */
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the 
list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+   v4l2_m2m_buf_remove_by_buf(_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove_by_buf() - take off exact destination buffer from 
the
+ * list of ready 

[PATCH v5 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2016-12-15 Thread Stanimir Varbanov
this add functions for:
  - remove buffers from src/dst queue by index
  - remove exact buffer from src/dst queue

also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.

Signed-off-by: Stanimir Varbanov 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 37 ++
 include/media/v4l2-mem2mem.h   | 92 ++
 2 files changed, 129 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..f62e68aa04c4 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
 
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf)
+{
+   struct v4l2_m2m_buffer *b;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+   list_del(>list);
+   q_ctx->num_rdy--;
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_buf);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+   struct v4l2_m2m_buffer *b, *tmp;
+   struct vb2_v4l2_buffer *ret = NULL;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
+   if (b->vb.vb2_buf.index == idx) {
+   list_del(>list);
+   q_ctx->num_rdy--;
+   ret = >vb;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
 /*
  * Scheduling handlers
  */
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..e157d5c9b224 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,47 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
v4l2_m2m_ctx *m2m_ctx)
 }
 
 /**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
  * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
  *
  * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
@@ -488,6 +529,57 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
v4l2_m2m_ctx *m2m_ctx)
return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
 }
 
+/**
+ * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ * @vbuf: the buffer to be removed
+ */
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+   struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the 
list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+   v4l2_m2m_buf_remove_by_buf(_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove_by_buf() - take off exact destination buffer from 
the
+ * list of ready 

Re: [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2016-12-05 Thread Stanimir Varbanov
Hi Hans,

On 12/05/2016 01:25 PM, Hans Verkuil wrote:
> On 12/01/2016 10:03 AM, Stanimir Varbanov wrote:
>> this add functions for:
>>   - remove buffers from src/dst queue by index
>>   - remove exact buffer from src/dst queue
>>
>> also extends m2m API to iterate over a list of src/dst buffers
>> in safely and non-safely manner.
>>
>> Signed-off-by: Stanimir Varbanov 
>> ---
>>  drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +++
>>  include/media/v4l2-mem2mem.h   | 83 
>> ++
>>  2 files changed, 120 insertions(+)
>>
>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
>> b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> index 6bc27e7b2a33..d689e7bb964f 100644
>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> @@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx 
>> *q_ctx)
>>  }
>>  EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
>>  
>> +void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
>> +   struct vb2_v4l2_buffer *vbuf)
> 
> I'd call this v4l2_m2m_buf_remove_by_buf to be consistent with _by_idx.

Thanks, I will rename it.

-- 
regards,
Stan
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2016-12-05 Thread Hans Verkuil
On 12/01/2016 10:03 AM, Stanimir Varbanov wrote:
> this add functions for:
>   - remove buffers from src/dst queue by index
>   - remove exact buffer from src/dst queue
> 
> also extends m2m API to iterate over a list of src/dst buffers
> in safely and non-safely manner.
> 
> Signed-off-by: Stanimir Varbanov 
> ---
>  drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +++
>  include/media/v4l2-mem2mem.h   | 83 
> ++
>  2 files changed, 120 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
> b/drivers/media/v4l2-core/v4l2-mem2mem.c
> index 6bc27e7b2a33..d689e7bb964f 100644
> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> @@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx 
> *q_ctx)
>  }
>  EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
>  
> +void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
> +struct vb2_v4l2_buffer *vbuf)

I'd call this v4l2_m2m_buf_remove_by_buf to be consistent with _by_idx.

Other than that, this looks OK.

Regards,

Hans

> +{
> + struct v4l2_m2m_buffer *b;
> + unsigned long flags;
> +
> + spin_lock_irqsave(_ctx->rdy_spinlock, flags);
> + b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
> + list_del(>list);
> + q_ctx->num_rdy--;
> + spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
> +}
> +EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_exact);
> +
> +struct vb2_v4l2_buffer *
> +v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int 
> idx)
> +
> +{
> + struct v4l2_m2m_buffer *b, *tmp;
> + struct vb2_v4l2_buffer *ret = NULL;
> + unsigned long flags;
> +
> + spin_lock_irqsave(_ctx->rdy_spinlock, flags);
> + list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
> + if (b->vb.vb2_buf.index == idx) {
> + list_del(>list);
> + q_ctx->num_rdy--;
> + ret = >vb;
> + break;
> + }
> + }
> + spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
> +
>  /*
>   * Scheduling handlers
>   */
> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> index 3ccd01bd245e..c8632c52d5e2 100644
> --- a/include/media/v4l2-mem2mem.h
> +++ b/include/media/v4l2-mem2mem.h
> @@ -437,6 +437,41 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
> v4l2_m2m_ctx *m2m_ctx)
>  }
>  
>  /**
> + * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
> + * buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> + */
> +#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)\
> + list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> + */
> +#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)\
> + list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination 
> ready
> + * buffers safely
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> + */
> +#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)\
> + list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
> + * buffers safely
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> + */
> +#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)\
> + list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
> +
> +/**
>   * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
>   *
>   * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> @@ -488,6 +523,54 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
> v4l2_m2m_ctx *m2m_ctx)
>   return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
>  }
>  
> +/**
> + * v4l2_m2m_buf_remove_exact() - take off exact buffer from the list of ready
> + * buffers
> + *
> + * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
> + */
> +void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
> +struct vb2_v4l2_buffer *vbuf);
> +
> +/**
> + * v4l2_m2m_src_buf_remove_exact() - take off exact source buffer from the 
> list
> + * of ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct 
> _m2m_ctx
> + */
> +static inline void v4l2_m2m_src_buf_remove_exact(struct v4l2_m2m_ctx 
> *m2m_ctx,
> +  struct vb2_v4l2_buffer *vbuf)
> +{
> + v4l2_m2m_buf_remove_exact(_ctx->out_q_ctx, vbuf);
> +}
> +
> +/**
> + * 

Re: [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2016-12-02 Thread kbuild test robot
Hi Stanimir,

[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v4.9-rc7 next-20161202]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Stanimir-Varbanov/Qualcomm-video-decoder-encoder-driver/20161203-054705
base:   git://linuxtv.org/media_tree.git master
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   make[3]: warning: jobserver unavailable: using -j1.  Add '+' to parent make 
rule.
   include/linux/init.h:1: warning: no structured comments found
   include/linux/workqueue.h:392: warning: No description found for parameter 
'...'
   include/linux/workqueue.h:392: warning: Excess function parameter 'args' 
description in 'alloc_workqueue'
   include/linux/workqueue.h:413: warning: No description found for parameter 
'...'
   include/linux/workqueue.h:413: warning: Excess function parameter 'args' 
description in 'alloc_ordered_workqueue'
   include/linux/kthread.h:26: warning: No description found for parameter '...'
   kernel/sys.c:1: warning: no structured comments found
   drivers/dma-buf/seqno-fence.c:1: warning: no structured comments found
   include/linux/fence-array.h:61: warning: No description found for parameter 
'fence'
   include/sound/core.h:324: warning: No description found for parameter '...'
   include/sound/core.h:335: warning: No description found for parameter '...'
   include/sound/core.h:388: warning: No description found for parameter '...'
   drivers/media/dvb-core/dvb_frontend.h:677: warning: No description found for 
parameter 'refcount'
   include/media/media-entity.h:1054: warning: No description found for 
parameter '...'
>> include/media/v4l2-mem2mem.h:446: warning: No description found for 
>> parameter 'b'
   include/media/v4l2-mem2mem.h:454: warning: No description found for 
parameter 'b'
   include/media/v4l2-mem2mem.h:463: warning: No description found for 
parameter 'b'
>> include/media/v4l2-mem2mem.h:463: warning: No description found for 
>> parameter 'n'
   include/media/v4l2-mem2mem.h:472: warning: No description found for 
parameter 'b'
   include/media/v4l2-mem2mem.h:472: warning: No description found for 
parameter 'n'
>> include/media/v4l2-mem2mem.h:533: warning: No description found for 
>> parameter 'vbuf'
   include/media/v4l2-mem2mem.h:543: warning: No description found for 
parameter 'vbuf'
   include/media/v4l2-mem2mem.h:555: warning: No description found for 
parameter 'vbuf'
   include/net/mac80211.h:3207: ERROR: Unexpected indentation.
   include/net/mac80211.h:3210: WARNING: Block quote ends without a blank line; 
unexpected unindent.
   include/net/mac80211.h:3212: ERROR: Unexpected indentation.
   include/net/mac80211.h:3213: WARNING: Block quote ends without a blank line; 
unexpected unindent.
   include/net/mac80211.h:1772: ERROR: Unexpected indentation.
   include/net/mac80211.h:1776: WARNING: Block quote ends without a blank line; 
unexpected unindent.
   kernel/sched/fair.c:7259: WARNING: Inline emphasis start-string without 
end-string.
   kernel/time/timer.c:1240: ERROR: Unexpected indentation.
   kernel/time/timer.c:1242: ERROR: Unexpected indentation.
   kernel/time/timer.c:1243: WARNING: Block quote ends without a blank line; 
unexpected unindent.
   include/linux/wait.h:121: WARNING: Block quote ends without a blank line; 
unexpected unindent.
   include/linux/wait.h:124: ERROR: Unexpected indentation.
   include/linux/wait.h:126: WARNING: Block quote ends without a blank line; 
unexpected unindent.
   kernel/time/hrtimer.c:1021: WARNING: Block quote ends without a blank line; 
unexpected unindent.
   kernel/signal.c:317: WARNING: Inline literal start-string without end-string.
   drivers/base/firmware_class.c:1348: WARNING: Bullet list ends without a 
blank line; unexpected unindent.
   drivers/message/fusion/mptbase.c:5054: WARNING: Definition list ends without 
a blank line; unexpected unindent.
   drivers/tty/serial/serial_core.c:1893: WARNING: Definition list ends without 
a blank line; unexpected unindent.
   include/linux/spi/spi.h:369: ERROR: Unexpected indentation.
   WARNING: dvipng command 'dvipng' cannot be run (needed for math display), 
check the imgmath_dvipng setting

vim +/b +446 include/media/v4l2-mem2mem.h

   440   * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination 
ready
   441   * buffers
   442   *
   443   * @m2m_ctx: m2m context assigned to the instance given by struct 
_m2m_ctx
   444   */
   445  #define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)   \
 > 446  list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
   447  
   448  /**
   449   * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready 
buffers
   450   *
   451   * @m2m_ctx: m2m context assigned to the instance given by struct 
_m2m_ctx
   452   */
   453  #define v4l2_m2m_for_each_src_buf(m2m_ctx, b)   \
   454  list_for_each_entry(b, 

[PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

2016-12-01 Thread Stanimir Varbanov
this add functions for:
  - remove buffers from src/dst queue by index
  - remove exact buffer from src/dst queue

also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.

Signed-off-by: Stanimir Varbanov 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +++
 include/media/v4l2-mem2mem.h   | 83 ++
 2 files changed, 120 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..d689e7bb964f 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
 
+void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
+  struct vb2_v4l2_buffer *vbuf)
+{
+   struct v4l2_m2m_buffer *b;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+   list_del(>list);
+   q_ctx->num_rdy--;
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_exact);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+   struct v4l2_m2m_buffer *b, *tmp;
+   struct vb2_v4l2_buffer *ret = NULL;
+   unsigned long flags;
+
+   spin_lock_irqsave(_ctx->rdy_spinlock, flags);
+   list_for_each_entry_safe(b, tmp, _ctx->rdy_queue, list) {
+   if (b->vb.vb2_buf.index == idx) {
+   list_del(>list);
+   q_ctx->num_rdy--;
+   ret = >vb;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_ctx->rdy_spinlock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
 /*
  * Scheduling handlers
  */
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..c8632c52d5e2 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,41 @@ static inline void *v4l2_m2m_next_dst_buf(struct 
v4l2_m2m_ctx *m2m_ctx)
 }
 
 /**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)  \
+   list_for_each_entry(b, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)  \
+   list_for_each_entry_safe(b, n, _ctx->out_q_ctx.rdy_queue, list)
+
+/**
  * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
  *
  * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
@@ -488,6 +523,54 @@ static inline void *v4l2_m2m_dst_buf_remove(struct 
v4l2_m2m_ctx *m2m_ctx)
return v4l2_m2m_buf_remove(_ctx->cap_q_ctx);
 }
 
+/**
+ * v4l2_m2m_buf_remove_exact() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ */
+void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
+  struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_exact() - take off exact source buffer from the list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ */
+static inline void v4l2_m2m_src_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
+struct vb2_v4l2_buffer *vbuf)
+{
+   v4l2_m2m_buf_remove_exact(_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_src_buf_remove_exact() - take off exact destination buffer from the
+ * list of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct _m2m_ctx
+ */
+static inline void v4l2_m2m_dst_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
+struct vb2_v4l2_buffer *vbuf)
+{
+   v4l2_m2m_buf_remove_exact(_ctx->cap_q_ctx, vbuf);
+}
+
+struct vb2_v4l2_buffer *

[PATCH 2/2] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-26 Thread William Towle
This commit moves the buffer in use logic from the .buf_cleanup
handler into .stop_streaming, based on advice that this is its
proper logical home.

By ensuring the list of pointers in priv-queue_buf[] is managed
as soon as possible, we avoid warnings concerning buffers in ACTIVE
state when the system cleans up after streaming stops. This fixes a
problem with modification of buffers after their content has been
cleared for passing to userspace.

After the refactoring, the buf_init and buf_cleanup functions were
found to contain only initialisation/release steps as are carried out
elsewhere if omitted; these functions and references were removed.

Signed-off-by: William Towle william.to...@codethink.co.uk
---
 drivers/media/platform/soc_camera/rcar_vin.c |   62 ++
 1 file changed, 13 insertions(+), 49 deletions(-)

diff --git a/drivers/media/platform/soc_camera/rcar_vin.c 
b/drivers/media/platform/soc_camera/rcar_vin.c
index 89c409b..aa25a3b 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -480,72 +480,36 @@ static void rcar_vin_wait_stop_streaming(struct 
rcar_vin_priv *priv)
}
 }
 
-static void rcar_vin_videobuf_release(struct vb2_buffer *vb)
+static void rcar_vin_stop_streaming(struct vb2_queue *vq)
 {
-   struct soc_camera_device *icd = soc_camera_from_vb2q(vb-vb2_queue);
+   struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
struct soc_camera_host *ici = to_soc_camera_host(icd-parent);
struct rcar_vin_priv *priv = ici-priv;
-   unsigned int i;
-   int buf_in_use = 0;
+   struct list_head *buf_head, *tmp;
+   int i;
 
spin_lock_irq(priv-lock);
+   rcar_vin_wait_stop_streaming(priv);
 
-   /* Is the buffer in use by the VIN hardware? */
for (i = 0; i  MAX_BUFFER_NUM; i++) {
-   if (priv-queue_buf[i] == vb) {
-   buf_in_use = 1;
-   break;
-   }
-   }
-
-   if (buf_in_use) {
-   rcar_vin_wait_stop_streaming(priv);
-
-   /*
-* Capturing has now stopped. The buffer we have been asked
-* to release could be any of the current buffers in use, so
-* release all buffers that are in use by HW
-*/
-   for (i = 0; i  MAX_BUFFER_NUM; i++) {
-   if (priv-queue_buf[i]) {
-   vb2_buffer_done(priv-queue_buf[i],
+   if (priv-queue_buf[i]) {
+   vb2_buffer_done(priv-queue_buf[i],
VB2_BUF_STATE_ERROR);
-   priv-queue_buf[i] = NULL;
-   }
+   priv-queue_buf[i] = NULL;
}
-   } else {
-   list_del_init(to_buf_list(vb));
}
 
-   spin_unlock_irq(priv-lock);
-}
-
-static int rcar_vin_videobuf_init(struct vb2_buffer *vb)
-{
-   INIT_LIST_HEAD(to_buf_list(vb));
-   return 0;
-}
-
-static void rcar_vin_stop_streaming(struct vb2_queue *vq)
-{
-   struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
-   struct soc_camera_host *ici = to_soc_camera_host(icd-parent);
-   struct rcar_vin_priv *priv = ici-priv;
-   struct list_head *buf_head, *tmp;
-
-   spin_lock_irq(priv-lock);
-
-   rcar_vin_wait_stop_streaming(priv);
-   list_for_each_safe(buf_head, tmp, priv-capture)
+   list_for_each_safe(buf_head, tmp, priv-capture) {
+   vb2_buffer_done(list_entry(buf_head,
+   struct rcar_vin_buffer, list)-vb,
+   VB2_BUF_STATE_ERROR);
list_del_init(buf_head);
-
+   }
spin_unlock_irq(priv-lock);
 }
 
 static struct vb2_ops rcar_vin_vb2_ops = {
.queue_setup= rcar_vin_videobuf_setup,
-   .buf_init   = rcar_vin_videobuf_init,
-   .buf_cleanup= rcar_vin_videobuf_release,
.buf_queue  = rcar_vin_videobuf_queue,
.stop_streaming = rcar_vin_stop_streaming,
.wait_prepare   = soc_camera_unlock,
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


rcar_vin video buffer management fixes, v3

2015-01-26 Thread William Towle
  This is version 3 of the hotfix patchset for video support on Lager,
in which we aim to fix the kernel's warnings about unexpected buffer
states. It replaces the following series:

http://comments.gmane.org/gmane.linux.drivers.video-input-infrastructure/87009

  This version of the series contains two patches which add a helper
function and then refactors the code where it is called, respectively.
Based on recent feedback, further modification is included in the
second patch where initialise/cleanup routines are removed due to
all significant content having moved elsewhere.

  The series comprises:
[PATCH 1/2] media: rcar_vin: helper function for streaming stop
[PATCH 2/2] media: rcar_vin: move buffer management to

Cheers,
  Wills
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 5/5] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-20 Thread William Towle



On Mon, 19 Jan 2015, Guennadi Liakhovetski wrote:

On Mon, 19 Jan 2015, William Towle wrote:

  in the patchset Ben linked to above we think
we have the appropriate loops: a for loop for queue_buf[], and
list_for_each_safe() for anything left in priv-capture; this is
consistent with rcar_vin_fill_hw_slot() setting up queue_buf[] with
pointers unlinked from priv-capture. This in turn suggests that we
are right not to call list_del_init() in both of
rcar_vin_stop_streaming()'s loops ... as long as I've correctly
interpreted the code and everyone's feedback thus far.


I'm referring to this comment by Hans Verkuil of 14 August last year:


I'm assuming all buffers that are queued to the driver via buf_queue() are
linked into priv-capture. So you would typically call vb2_buffer_done
when you are walking that list:

list_for_each_safe(buf_head, tmp, priv-capture) {
// usually you go from buf_head to the real buffer struct
// containing a vb2_buffer struct
vb2_buffer_done(buf-vb, VB2_BUF_STATE_ERROR);
list_del_init(buf_head);
}

Please use this rather than looking into internal vb2_queue
datastructures.


I think, that's the right way to implement that clean up loop.


Hi,
  I was describing the code in my latest patch; we start with
rcar_vin_stop_streaming() having a list_for_each_safe() loop like
that above, and leave that loop in place but add statements to it.

  I add another loop to rcar_vin_stop_streaming() [which you will
have seen -in the patch Ben published in my absence over Christmas-
was particularly inelegant initially], but it can't be rewritten in
the same way.  The new version is undeniably neater, though.

  We believe the latest patches take Hans' comment above into
account properly, and we are looking into his latest suggestion at
the moment.

Thanks again,
  Wills.
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 5/5] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-19 Thread William Towle


On Mon, 19 Jan 2015, Guennadi Liakhovetski wrote:


On Thu, 18 Dec 2014, Ben Hutchings wrote:

Well, I thought that too.  Will's submission from last week has that
change:
http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/87009



Anyway, yes, that looks better! But I would still consider keeping buffers
on the list in .buf_clean(), in which case you can remove it. And walk the
list instead of the VB2 internal buffer array, as others have pointed out.


Hi Guennadi,
  Thanks for the clarification. Ian (when he was with us) did say it
was particularly difficult to understand WTH this driver was doing.

  Regarding your first point, if it's safe to skip the actions left
in rcar_vin_videobuf_release() then I will do a further rework to
remove it completely.

  Regarding your second, in the patchset Ben linked to above we think
we have the appropriate loops: a for loop for queue_buf[], and
list_for_each_safe() for anything left in priv-capture; this is
consistent with rcar_vin_fill_hw_slot() setting up queue_buf[] with
pointers unlinked from priv-capture. This in turn suggests that we
are right not to call list_del_init() in both of
rcar_vin_stop_streaming()'s loops ... as long as I've correctly
interpreted the code and everyone's feedback thus far.


Cheers,
  Wills.
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 5/5] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-19 Thread Guennadi Liakhovetski
Hi,

On Mon, 19 Jan 2015, William Towle wrote:

 
 On Mon, 19 Jan 2015, Guennadi Liakhovetski wrote:
 
On Thu, 18 Dec 2014, Ben Hutchings wrote:
   Well, I thought that too.  Will's submission from last week has that
   change:
   http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/87009
 
  Anyway, yes, that looks better! But I would still consider keeping buffers
  on the list in .buf_clean(), in which case you can remove it. And walk the
  list instead of the VB2 internal buffer array, as others have pointed out.
 
 Hi Guennadi,
   Thanks for the clarification. Ian (when he was with us) did say it
 was particularly difficult to understand WTH this driver was doing.
 
   Regarding your first point, if it's safe to skip the actions left
 in rcar_vin_videobuf_release() then I will do a further rework to
 remove it completely.
 
   Regarding your second, in the patchset Ben linked to above we think
 we have the appropriate loops: a for loop for queue_buf[], and
 list_for_each_safe() for anything left in priv-capture; this is
 consistent with rcar_vin_fill_hw_slot() setting up queue_buf[] with
 pointers unlinked from priv-capture. This in turn suggests that we
 are right not to call list_del_init() in both of
 rcar_vin_stop_streaming()'s loops ... as long as I've correctly
 interpreted the code and everyone's feedback thus far.

I'm referring to this comment by Hans Verkuil of 14 August last year:

 I'm assuming all buffers that are queued to the driver via buf_queue() are
 linked into priv-capture. So you would typically call vb2_buffer_done
 when you are walking that list:
 
   list_for_each_safe(buf_head, tmp, priv-capture) {
   // usually you go from buf_head to the real buffer struct
   // containing a vb2_buffer struct
   vb2_buffer_done(buf-vb, VB2_BUF_STATE_ERROR);
   list_del_init(buf_head);
   }
 
 Please use this rather than looking into internal vb2_queue 
 datastructures.

I think, that's the right way to implement that clean up loop.

Thanks
Guennadi
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 5/5] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-19 Thread Hans Verkuil
On 01/19/2015 03:11 PM, William Towle wrote:
 
 On Mon, 19 Jan 2015, Guennadi Liakhovetski wrote:
 
 On Thu, 18 Dec 2014, Ben Hutchings wrote:
 Well, I thought that too.  Will's submission from last week has that
 change:
 http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/87009
 
 Anyway, yes, that looks better! But I would still consider keeping buffers
 on the list in .buf_clean(), in which case you can remove it. And walk the
 list instead of the VB2 internal buffer array, as others have pointed out.
 
 Hi Guennadi,
Thanks for the clarification. Ian (when he was with us) did say it
 was particularly difficult to understand WTH this driver was doing.
 
Regarding your first point, if it's safe to skip the actions left
 in rcar_vin_videobuf_release() then I will do a further rework to
 remove it completely.

Yes, that's safe. Just remove it altogether.

The buf_init and buf_release ops are matching ops that are normally only
used if you have to do per-buffer initialization and/or release. These
are only called when the buffer memory changes. In most drivers including
this one it's not needed at all.

The same is true for rcar_vin_videobuf_init: it's pointless since the
list initialization is done implicitly when you add the buffer to a
list with list_add_tail(). Just drop the function.

Regards,

Hans

 
Regarding your second, in the patchset Ben linked to above we think
 we have the appropriate loops: a for loop for queue_buf[], and
 list_for_each_safe() for anything left in priv-capture; this is
 consistent with rcar_vin_fill_hw_slot() setting up queue_buf[] with
 pointers unlinked from priv-capture. This in turn suggests that we
 are right not to call list_del_init() in both of
 rcar_vin_stop_streaming()'s loops ... as long as I've correctly
 interpreted the code and everyone's feedback thus far.
 
 
 Cheers,
Wills.
 --
 To unsubscribe from this list: send the line unsubscribe linux-media in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 5/5] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-19 Thread Guennadi Liakhovetski
On Mon, 19 Jan 2015, Ben Hutchings wrote:

 On Sun, 2015-01-18 at 22:23 +0100, Guennadi Liakhovetski wrote:
  On Thu, 18 Dec 2014, Ben Hutchings wrote:
  
   From: William Towle william.to...@codethink.co.uk
   
   Move the buffer state test in the .buf_cleanup handler into
   .stop_streaming so that a) the vb2_queue API is not subverted, and
   b) tracking of active-state buffers via priv-queue_buf[] is handled
   as early as is possible
  
  Huh... Sorry, patches 1, 2, 3, and 5 of this series look like a strange 
  way to get from the present state to the destination. They all have to be 
  merged IMHO. 
 [...]
 
 Well, I thought that too.  Will's submission from last week has that
 change:
 http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/87009

Hm... interesting, why I didn't get those mails in my INBOX, although I do 
see myself in CC... Only got them from the list, and no, I don't have 
avoid copies enabled.

Anyway, yes, that looks better! But I would still consider keeping buffers 
on the list in .buf_clean(), in which case you can remove it. And walk the 
list instead of the VB2 internal buffer array, as others have pointed out.

Thanks
Guennadi
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 5/5] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-19 Thread Ben Hutchings
On Sun, 2015-01-18 at 22:23 +0100, Guennadi Liakhovetski wrote:
 On Thu, 18 Dec 2014, Ben Hutchings wrote:
 
  From: William Towle william.to...@codethink.co.uk
  
  Move the buffer state test in the .buf_cleanup handler into
  .stop_streaming so that a) the vb2_queue API is not subverted, and
  b) tracking of active-state buffers via priv-queue_buf[] is handled
  as early as is possible
 
 Huh... Sorry, patches 1, 2, 3, and 5 of this series look like a strange 
 way to get from the present state to the destination. They all have to be 
 merged IMHO. 
[...]

Well, I thought that too.  Will's submission from last week has that
change:
http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/87009

Ben.


--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 5/5] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-18 Thread Guennadi Liakhovetski
On Thu, 18 Dec 2014, Ben Hutchings wrote:

 From: William Towle william.to...@codethink.co.uk
 
 Move the buffer state test in the .buf_cleanup handler into
 .stop_streaming so that a) the vb2_queue API is not subverted, and
 b) tracking of active-state buffers via priv-queue_buf[] is handled
 as early as is possible

Huh... Sorry, patches 1, 2, 3, and 5 of this series look like a strange 
way to get from the present state to the destination. They all have to be 
merged IMHO. 

Further, looking at vb2, I don't think active buffers should ever stay 
active until .buf_cleanup() is called. I think rcar_vin's 
.stop_streaming() should stop the hardware, wait until it's stopped, then 
walk all queued buffers and return errors for them, while removing them 
from the list at the same time. Then I don't think a .buf_cleanup() method 
is needed there at all.

Thanks
Guennadi

 
 Signed-off-by: William Towle william.to...@codethink.co.uk
 ---
  drivers/media/platform/soc_camera/rcar_vin.c |   36 
 ++
  1 file changed, 14 insertions(+), 22 deletions(-)
 
 diff --git a/drivers/media/platform/soc_camera/rcar_vin.c 
 b/drivers/media/platform/soc_camera/rcar_vin.c
 index 20dbedf..bf60074 100644
 --- a/drivers/media/platform/soc_camera/rcar_vin.c
 +++ b/drivers/media/platform/soc_camera/rcar_vin.c
 @@ -486,28 +486,8 @@ static void rcar_vin_videobuf_release(struct vb2_buffer 
 *vb)
   struct soc_camera_device *icd = soc_camera_from_vb2q(vb-vb2_queue);
   struct soc_camera_host *ici = to_soc_camera_host(icd-parent);
   struct rcar_vin_priv *priv = ici-priv;
 - unsigned int i;
 - int buf_in_use = 0;
 - spin_lock_irq(priv-lock);
 -
 - /* Is the buffer in use by the VIN hardware? */
 - for (i = 0; i  MAX_BUFFER_NUM; i++) {
 - if (priv-queue_buf[i] == vb) {
 - buf_in_use = 1;
 - break;
 - }
 - }
  
 - if (buf_in_use) {
 - rcar_vin_wait_stop_streaming(priv);
 -
 - /*
 -  * Capturing has now stopped. The buffer we have been asked
 -  * to release could be any of the current buffers in use, so
 -  * release all buffers that are in use by HW
 -  */
 - priv-queue_buf[i] = NULL;
 - }
 + spin_lock_irq(priv-lock);
  
   list_del_init(to_buf_list(vb));
  
 @@ -533,8 +513,20 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
   rcar_vin_wait_stop_streaming(priv);
  
   for (i = 0; i  vq-num_buffers; ++i)
 - if (vq-bufs[i]-state == VB2_BUF_STATE_ACTIVE)
 + if (vq-bufs[i]-state == VB2_BUF_STATE_ACTIVE) {
 + int j;
 +
 + /*  Is this a buffer we have told the
 +  *  hardware about? Update the associated
 +  *  list, if so
 +  */
 + for (j = 0; j  MAX_BUFFER_NUM; j++) {
 + if (priv-queue_buf[j] == vq-bufs[i]) {
 + priv-queue_buf[j] = NULL;
 + }
 + }
   vb2_buffer_done(vq-bufs[i], VB2_BUF_STATE_ERROR);
 + }
  
   list_for_each_safe(buf_head, tmp, priv-capture)
   list_del_init(buf_head);
 -- 
 1.7.10.4
 
 
 
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-16 Thread William Towle
This commit moves the buffer in use logic from the .buf_cleanup
handler into .stop_streaming, based on advice that this is its
proper logical home.

By ensuring the list of pointers in priv-queue_buf[] is managed
as soon as possible, we avoid warnings concerning buffers in ACTIVE
state when the system cleans up after streaming stops. This fixes a
problem with modification of buffers after their content has been
cleared for passing to userspace.

Signed-off-by: William Towle william.to...@codethink.co.uk
---
 drivers/media/platform/soc_camera/rcar_vin.c |   47 +-
 1 file changed, 16 insertions(+), 31 deletions(-)

diff --git a/drivers/media/platform/soc_camera/rcar_vin.c 
b/drivers/media/platform/soc_camera/rcar_vin.c
index 89c409b..022fa9d 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -485,37 +485,10 @@ static void rcar_vin_videobuf_release(struct vb2_buffer 
*vb)
struct soc_camera_device *icd = soc_camera_from_vb2q(vb-vb2_queue);
struct soc_camera_host *ici = to_soc_camera_host(icd-parent);
struct rcar_vin_priv *priv = ici-priv;
-   unsigned int i;
-   int buf_in_use = 0;
 
spin_lock_irq(priv-lock);
 
-   /* Is the buffer in use by the VIN hardware? */
-   for (i = 0; i  MAX_BUFFER_NUM; i++) {
-   if (priv-queue_buf[i] == vb) {
-   buf_in_use = 1;
-   break;
-   }
-   }
-
-   if (buf_in_use) {
-   rcar_vin_wait_stop_streaming(priv);
-
-   /*
-* Capturing has now stopped. The buffer we have been asked
-* to release could be any of the current buffers in use, so
-* release all buffers that are in use by HW
-*/
-   for (i = 0; i  MAX_BUFFER_NUM; i++) {
-   if (priv-queue_buf[i]) {
-   vb2_buffer_done(priv-queue_buf[i],
-   VB2_BUF_STATE_ERROR);
-   priv-queue_buf[i] = NULL;
-   }
-   }
-   } else {
-   list_del_init(to_buf_list(vb));
-   }
+   list_del_init(to_buf_list(vb));
 
spin_unlock_irq(priv-lock);
 }
@@ -532,13 +505,25 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
struct soc_camera_host *ici = to_soc_camera_host(icd-parent);
struct rcar_vin_priv *priv = ici-priv;
struct list_head *buf_head, *tmp;
+   int i;
 
spin_lock_irq(priv-lock);
-
rcar_vin_wait_stop_streaming(priv);
-   list_for_each_safe(buf_head, tmp, priv-capture)
-   list_del_init(buf_head);
 
+   for (i = 0; i  MAX_BUFFER_NUM; i++) {
+   if (priv-queue_buf[i]) {
+   vb2_buffer_done(priv-queue_buf[i],
+   VB2_BUF_STATE_ERROR);
+   priv-queue_buf[i] = NULL;
+   }
+   }
+
+   list_for_each_safe(buf_head, tmp, priv-capture) {
+   vb2_buffer_done(list_entry(buf_head,
+   struct rcar_vin_buffer, list)-vb,
+   VB2_BUF_STATE_ERROR);
+   list_del_init(buf_head);
+   }
spin_unlock_irq(priv-lock);
 }
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 0/5] media: rcar_vin: Fixes for buffer management

2015-01-16 Thread William Towle
  The following is a subset of our work in progress branch for video
support on the Renesas Lager board, comprising hotfixes for video
buffer management.

  We are successfully capturing single frames and video with the
complete branch, and intend to follow up with stable patches from
the branch in due course.

  Included here:
[PATCH 1/2] media: rcar_vin: helper function for streaming stop
[PATCH 2/2] media: rcar_vin: move buffer management to .stop_streaming 
handler

Cheers,
  Wills.
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] media: rcar_vin: move buffer management to .stop_streaming handler

2015-01-16 Thread William Towle
This commit moves the buffer in use logic from the .buf_cleanup
handler into .stop_streaming, based on advice that this is its
proper logical home.

By ensuring the list of pointers in priv-queue_buf[] is managed
as soon as possible, we avoid warnings concerning buffers in ACTIVE
state when the system cleans up after streaming stops. This fixes a
problem with modification of buffers after their content has been
cleared for passing to userspace.

Signed-off-by: William Towle william.to...@codethink.co.uk
---
 drivers/media/platform/soc_camera/rcar_vin.c |   47 +-
 1 file changed, 16 insertions(+), 31 deletions(-)

diff --git a/drivers/media/platform/soc_camera/rcar_vin.c 
b/drivers/media/platform/soc_camera/rcar_vin.c
index 89c409b..022fa9d 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -485,37 +485,10 @@ static void rcar_vin_videobuf_release(struct vb2_buffer 
*vb)
struct soc_camera_device *icd = soc_camera_from_vb2q(vb-vb2_queue);
struct soc_camera_host *ici = to_soc_camera_host(icd-parent);
struct rcar_vin_priv *priv = ici-priv;
-   unsigned int i;
-   int buf_in_use = 0;
 
spin_lock_irq(priv-lock);
 
-   /* Is the buffer in use by the VIN hardware? */
-   for (i = 0; i  MAX_BUFFER_NUM; i++) {
-   if (priv-queue_buf[i] == vb) {
-   buf_in_use = 1;
-   break;
-   }
-   }
-
-   if (buf_in_use) {
-   rcar_vin_wait_stop_streaming(priv);
-
-   /*
-* Capturing has now stopped. The buffer we have been asked
-* to release could be any of the current buffers in use, so
-* release all buffers that are in use by HW
-*/
-   for (i = 0; i  MAX_BUFFER_NUM; i++) {
-   if (priv-queue_buf[i]) {
-   vb2_buffer_done(priv-queue_buf[i],
-   VB2_BUF_STATE_ERROR);
-   priv-queue_buf[i] = NULL;
-   }
-   }
-   } else {
-   list_del_init(to_buf_list(vb));
-   }
+   list_del_init(to_buf_list(vb));
 
spin_unlock_irq(priv-lock);
 }
@@ -532,13 +505,25 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
struct soc_camera_host *ici = to_soc_camera_host(icd-parent);
struct rcar_vin_priv *priv = ici-priv;
struct list_head *buf_head, *tmp;
+   int i;
 
spin_lock_irq(priv-lock);
-
rcar_vin_wait_stop_streaming(priv);
-   list_for_each_safe(buf_head, tmp, priv-capture)
-   list_del_init(buf_head);
 
+   for (i = 0; i  MAX_BUFFER_NUM; i++) {
+   if (priv-queue_buf[i]) {
+   vb2_buffer_done(priv-queue_buf[i],
+   VB2_BUF_STATE_ERROR);
+   priv-queue_buf[i] = NULL;
+   }
+   }
+
+   list_for_each_safe(buf_head, tmp, priv-capture) {
+   vb2_buffer_done(list_entry(buf_head,
+   struct rcar_vin_buffer, list)-vb,
+   VB2_BUF_STATE_ERROR);
+   list_del_init(buf_head);
+   }
spin_unlock_irq(priv-lock);
 }
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 0/5] media: rcar_vin: Fixes for buffer management

2014-12-18 Thread Ben Hutchings
This is a re-submission of patches previously sent and archived at
http://thread.gmane.org/gmane.linux.ports.sh.devel/37184/.  Will has
rebased onto 3.18 and added a further patch to address Hans' review
comments.

The driver continues to works for single frame capture, and no longer
provokes a WARNing.  However, video capture has regressed (a gstreamer
capture pipeline yields a zero-length file).

Ben.

Ian Molton (4):
  media: rcar_vin: Dont aggressively retire buffers
  media: rcar_vin: Ensure all in-flight buffers are returned to error
state before stopping.
  media: rcar_vin: Fix race condition terminating stream
  media: rcar_vin: Clean up rcar_vin_irq

William Towle (1):
  media: rcar_vin: move buffer management to .stop_streaming handler

 drivers/media/platform/soc_camera/rcar_vin.c |  109 ++
 1 file changed, 59 insertions(+), 50 deletions(-)

-- 
1.7.10.4



--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 5/5] media: rcar_vin: move buffer management to .stop_streaming handler

2014-12-18 Thread Ben Hutchings
From: William Towle william.to...@codethink.co.uk

Move the buffer state test in the .buf_cleanup handler into
.stop_streaming so that a) the vb2_queue API is not subverted, and
b) tracking of active-state buffers via priv-queue_buf[] is handled
as early as is possible

Signed-off-by: William Towle william.to...@codethink.co.uk
---
 drivers/media/platform/soc_camera/rcar_vin.c |   36 ++
 1 file changed, 14 insertions(+), 22 deletions(-)

diff --git a/drivers/media/platform/soc_camera/rcar_vin.c 
b/drivers/media/platform/soc_camera/rcar_vin.c
index 20dbedf..bf60074 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -486,28 +486,8 @@ static void rcar_vin_videobuf_release(struct vb2_buffer 
*vb)
struct soc_camera_device *icd = soc_camera_from_vb2q(vb-vb2_queue);
struct soc_camera_host *ici = to_soc_camera_host(icd-parent);
struct rcar_vin_priv *priv = ici-priv;
-   unsigned int i;
-   int buf_in_use = 0;
-   spin_lock_irq(priv-lock);
-
-   /* Is the buffer in use by the VIN hardware? */
-   for (i = 0; i  MAX_BUFFER_NUM; i++) {
-   if (priv-queue_buf[i] == vb) {
-   buf_in_use = 1;
-   break;
-   }
-   }
 
-   if (buf_in_use) {
-   rcar_vin_wait_stop_streaming(priv);
-
-   /*
-* Capturing has now stopped. The buffer we have been asked
-* to release could be any of the current buffers in use, so
-* release all buffers that are in use by HW
-*/
-   priv-queue_buf[i] = NULL;
-   }
+   spin_lock_irq(priv-lock);
 
list_del_init(to_buf_list(vb));
 
@@ -533,8 +513,20 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
rcar_vin_wait_stop_streaming(priv);
 
for (i = 0; i  vq-num_buffers; ++i)
-   if (vq-bufs[i]-state == VB2_BUF_STATE_ACTIVE)
+   if (vq-bufs[i]-state == VB2_BUF_STATE_ACTIVE) {
+   int j;
+
+   /*  Is this a buffer we have told the
+*  hardware about? Update the associated
+*  list, if so
+*/
+   for (j = 0; j  MAX_BUFFER_NUM; j++) {
+   if (priv-queue_buf[j] == vq-bufs[i]) {
+   priv-queue_buf[j] = NULL;
+   }
+   }
vb2_buffer_done(vq-bufs[i], VB2_BUF_STATE_ERROR);
+   }
 
list_for_each_safe(buf_head, tmp, priv-capture)
list_del_init(buf_head);
-- 
1.7.10.4



--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 5/5] media: rcar_vin: move buffer management to .stop_streaming handler

2014-12-18 Thread Sergei Shtylyov

Hello.

On 12/18/2014 05:50 PM, Ben Hutchings wrote:


From: William Towle william.to...@codethink.co.uk



Move the buffer state test in the .buf_cleanup handler into
.stop_streaming so that a) the vb2_queue API is not subverted, and
b) tracking of active-state buffers via priv-queue_buf[] is handled
as early as is possible



Signed-off-by: William Towle william.to...@codethink.co.uk
---
  drivers/media/platform/soc_camera/rcar_vin.c |   36 ++
  1 file changed, 14 insertions(+), 22 deletions(-)



diff --git a/drivers/media/platform/soc_camera/rcar_vin.c 
b/drivers/media/platform/soc_camera/rcar_vin.c
index 20dbedf..bf60074 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c

[...]

@@ -533,8 +513,20 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
rcar_vin_wait_stop_streaming(priv);

for (i = 0; i  vq-num_buffers; ++i)
-   if (vq-bufs[i]-state == VB2_BUF_STATE_ACTIVE)
+   if (vq-bufs[i]-state == VB2_BUF_STATE_ACTIVE) {
+   int j;
+
+   /*  Is this a buffer we have told the
+*  hardware about? Update the associated
+*  list, if so
+*/
+   for (j = 0; j  MAX_BUFFER_NUM; j++) {
+   if (priv-queue_buf[j] == vq-bufs[i]) {
+   priv-queue_buf[j] = NULL;
+   }


   Don't need {} here.


+   }
vb2_buffer_done(vq-bufs[i], VB2_BUF_STATE_ERROR);
+   }


WBR, Sergei

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/5] media: rcar_vin: Fixes for buffer management

2014-12-18 Thread Sergei Shtylyov

Hello.

On 12/18/2014 05:47 PM, Ben Hutchings wrote:


This is a re-submission of patches previously sent and archived at
http://thread.gmane.org/gmane.linux.ports.sh.devel/37184/.  Will has
rebased onto 3.18 and added a further patch to address Hans' review
comments.



The driver continues to works for single frame capture, and no longer
provokes a WARNing.  However, video capture has regressed (a gstreamer
capture pipeline yields a zero-length file).



Ben.



Ian Molton (4):
   media: rcar_vin: Dont aggressively retire buffers
   media: rcar_vin: Ensure all in-flight buffers are returned to error
 state before stopping.
   media: rcar_vin: Fix race condition terminating stream
   media: rcar_vin: Clean up rcar_vin_irq



William Towle (1):
   media: rcar_vin: move buffer management to .stop_streaming handler


   Having actual fixes and clean-ups in a single series is not a good idea...

WBR, Sergei

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] video-buffer management optimizations

2011-02-21 Thread Guennadi Liakhovetski
Agenda:
===

User-space applications need more flexibility in managing their video-
(multimedia-) buffers to achieve their goals. A popular example is a photo-
camera with a preview. Currently the application has to first enter the
preview mode:

* set the preview format
* allocate buffers (if they are allocated in the kernel, i.e., per MMAP, their
  size will be calculated, based on frame size and pixel format). If the READ or
  the USERPTR method is used, the buffer allocation task is handled in the user-
  space.
* queue buffers
* start streaming

Then, at some point during the running preview, the user presses the release
button, at which time the application has to

* stop streaming
* free the queue (REQBUFS with .count = 0)
* set the still image format
* allocate buffers
* queue buffers
* start streaming

The above switching takes a long time. A part of it comes from having to wait
for the current frame completion. A reasonable preview can be expected to run
at 25 / 30fps, i.e., spend 40 / 33ms per frame. The second component,
contributing to the delay, is the memory management. Depending on the type of
memory used and the camera resolution and the data format, it can take hundreds
of milliseconds to switch to a new buffer queue.

Another popular use-case is passing buffers between hardware entities with
or without intermediate data processing in the user-space. Depending, whether
CPU processing is required or not, caches do or do not have to be invalidated.
In this case buffers have to either be allocated from a globally-accessible pool
(buffer pool), or USERPTR or READ has to be used. Presently, no such global pool
solution exists in the kernel, and allocating buffers in user-space does not
normally support specifying caching requirements.

Further, in some cases performance can be critical for the applpication, in
others it might be essential to try to save memory.

Goals:
==

Minimize the delay by eliminating expansive memory allocation and cache
invalidation operations.

Possible memory configurations and requirements:


Currently there are three videobuffer management algorithms in the kernel:

* VMALLOC
* DMA_CONTIG
* DMA_SG

in videobuf version 1 and 2. Both DMA_* helpers are, logically, used, when DMA
is used to fill buffers. DMA_SG buffers are allocated with a page-size
granularity, which makes their reuse simple. DMA_CONTIG buffers are more
difficult to allocate (without an IOMMU) and to re-use for different frame sizes
due to likely memory fragmentation.

Further, there are three ways in which data can be retrieved by applications:

* using mmap(2) with buffers of type V4L2_MEMORY_MMAP
* using user-space buffers of type V4L2_MEMORY_USERPTR
* using read(2) with generic user-space memory

Finally, the obtained data can be used in one of the following two ways:

* using CPU once to read out the data
* using CPU multiple times to process the data in-place
* passing them further to other bus-masters for hardware processing / output

If the cpu-access is required, cache has to be invalidated before passing
buffers back to the user per DQBUF or upon queuing them per QBUF. If the buffers
have to be accessed only ones by the CPU, it might be better to allocate buffers
in uncached memory and let applications try to compensate uncached access by
implementing some low-level optimizations. OTOH, even in this case applications
can benefit from pre-fetching the data a cache-line at a time. Generally,
using non-coherent DMA-able contiguous memory and implementing a suitable cache
management seems to be preferable over using coherent memory.

Use-cases:
==

The most interesting case for us, is when the buffers are allocated in the V4L
driver context, i.e., the V4L2_MEMORY_MMAP method is used.

Example 1:
--

MMAP, DMA-Contiguous, CPU access required, optimize for performance.

Best result is achieved by pre-allocating and pre-queuing two buffer sizes.
Pre-queuing them eliminates the expensive cache invalidation when switching to
the still image mode. Switching is then performed in the following steps:

* stop streaming
* switch to the big-buffer queue
* set the still image format
* start streaming

Required extensions:

1. allocate multiple queues per device
2. switch between queues
3. specify buffer size explicitly, before the image format is known to the
   driver

Example 2:
--

MMAP, DMA-Contiguous, CPU access required, optimize for memory.

In this case we can sacrifice some performance, by taking the cache-invalidation
hit, but save memory by re-using the buffers. The easiest case - allocate a huge
chunk of memory, use it either for smaller, or for bigger buffers. CMA can be
useful for this. The advantage is, that new buffers do not have to be allocated,
only the same chunk of memory shall be split into differently sized buffers. A
single buffer queue shall be used.

Required extensions:

REQBUFS shall be extended to 

Re: buffer management

2010-06-30 Thread Marko Ristola
23.06.2010 15:43, Steven Toth kirjoitti:
 Now, on each video interrupt, I know which SG list i need to read
 from. At this stage i do need to copy the
 buffers associated with each of the SG lists at once. In this
 scenario, I don't see how videobuf could be used,
 while I keep getting this feeling that a simple copy_to_user of the
 entire buffer could do the whole job in a
 better way, since the buffers themselves are already managed and
 initialized already. Am I correct in thinking
 so, or is it that I am overlooking something ?

I've thought this a bit. I didn't find any good easy solution for
copying directly into users pace.


Here are the easiest trivial speed improvements I found:
dvb_core: dvb_dmx_swfilter(_204) functions:
- avoid unnecessary packet copying.
- I emailed those patches. You can see the difference with perf top
easilly
  (Fedora at least has perf).
  So with this the copying into ringbuffer remains as an unnecessary thing.
Mantis: Don't do busy looping on mantis_i2c.c


Harder algorithm that does only copy_to_user(), but avoids ring buffer
copying too:

Here is an algorithm that how you could do just the copy_to_user() from
the DMA buffer directly rather safely.
The algorithm is for 204 sized packets, but is
trivial to convert for 188 sized packets too.

I don't know if this is worth it though.

I found with Mantis that packets from DMA aren't always sized as 204
bytes (random sized garbage).
Even with this, you could do 204 - 188 conversion, without moving data:
1. Reserve first 256 bytes of each 4K DMA buffer page outside of the DMA
transfer.
2. DMA of buf[0][256 - 4095].
3. Do 204 - 188 conversion for buf[0][256 - 4095].
4. Copy remaining overflowed 45 bytes into buf[1][256 - 45], just
before second DMA start.
5. Deliver an array of pointers for 188 sized packets for
dvb_dmx_swfilter_nocopy_packets().
6. DMA of buf[1][256 - 4095].
7. Do 204 - 188 conversion for buf[1][(256 - 45) - 4095].
8. Copy remaining overflowed 25 bytes into buf[2][256 - 25], just
before third DMA start.
9. Deliver a second array of pointers for 188 sized packets for
dvb_dmx_swfilter_nocopy_packets().

dvb_dmx_swfilter_nocopy_packets would then have to deliver just the
pointers with sizes
into a new style ring buffer.

Then you would wake up the waiting ringbuffer reader, and it would
do the copy_to_user() as is done now.

Some or most of the DMA buffer management could be in dvb_core/ side,
because it is so generic.
On Mantis side, you must grab DMA interrupt and call a function like
dvb_dmabuf_set_busy_buf(bufno).
Other thing is, that you must traverse DMA buffers for RISC programming,
like:
for (i=0; i  dvb_dmabuf_count(dmabuf); i++) {
RISC_DMA(dvb_dmabuf_dma_pos(dmabuf, i) | MAKE_IRQ);
}
RISC_JUMP(risc_dma);
   
Other buffer management code isn't driver specific.

One possible problem that remains with this approach, is that what if
the DMA buffer gets overwritten?
Then the pointers in the ringbuffer might become garbage.

Another possible (cache coherency) problem is, that in this scenario
you both read and write to the DMA buffer.
Maybe with x86 computers this isn't a problem:
you never have to modify the same cache line
from both the DMA side and tasklet side at the same time.

Best regards,
Marko Ristola

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: buffer management

2010-06-23 Thread Steven Toth

Now, on each video interrupt, I know which SG list i need to read
from. At this stage i do need to copy the
buffers associated with each of the SG lists at once. In this
scenario, I don't see how videobuf could be used,
while I keep getting this feeling that a simple copy_to_user of the
entire buffer could do the whole job in a
better way, since the buffers themselves are already managed and
initialized already. Am I correct in thinking
so, or is it that I am overlooking something ?


Manu,

SAA7164 suffers from this. If you find a solution I'd love to hear it.

Regards,

- Steve

--
Steven Toth - Kernel Labs
http://www.kernellabs.com

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: buffer management

2010-06-23 Thread Marko Ristola

23.06.2010 15:43, Steven Toth kirjoitti:

Now, on each video interrupt, I know which SG list i need to read
from. At this stage i do need to copy the
buffers associated with each of the SG lists at once. In this
scenario, I don't see how videobuf could be used,
while I keep getting this feeling that a simple copy_to_user of the
entire buffer could do the whole job in a
better way, since the buffers themselves are already managed and
initialized already. Am I correct in thinking
so, or is it that I am overlooking something ?


How to activate DMA transfers only if there is empty space for the DMA 
transfer?


Regards,
Marko



Manu,

SAA7164 suffers from this. If you find a solution I'd love to hear it.

Regards,

- Steve



--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


buffer management

2010-06-22 Thread Manu Abraham
Hi All,

While working on a driver, i stumbled up on this question. I have a
driver where the driver allocates it's buffers
(maybe it's better to term that the hardware requires it that way) in
the following fashion:

Buffer 1: SG list 1
Buffer 2: SG list 2
Buffer 3: SG list 3
Buffer 4: SG list 4
Buffer 5: SG list 5
Buffer 6: SG list 6
Buffer 7: SG list 7
Buffer 8: SG list 8

Now, on each video interrupt, I know which SG list i need to read
from. At this stage i do need to copy the
buffers associated with each of the SG lists at once. In this
scenario, I don't see how videobuf could be used,
while I keep getting this feeling that a simple copy_to_user of the
entire buffer could do the whole job in a
better way, since the buffers themselves are already managed and
initialized already. Am I correct in thinking
so, or is it that I am overlooking something ?

Comments ?

Thanks,
Manu
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html