Re: [PATCH v2] media: vb2: vmalloc-based allocator user pointer handling

2011-12-11 Thread Laurent Pinchart
Hi Sylwester,

On Thursday 08 December 2011 22:43:00 Sylwester Nawrocki wrote:
 Hi Laurent,
 
 On 12/08/2011 11:56 AM, Laurent Pinchart wrote:
  On Wednesday 07 December 2011 17:29:06 Marek Szyprowski wrote:
  From: Andrzej Pietrasiewicz andrze...@samsung.com
 
 [...]
 
  -  printk(KERN_DEBUG Allocated vmalloc buffer of size %ld at
  vaddr=%p\n, - buf-size, buf-vaddr);
  +  pr_err(Allocated vmalloc buffer of size %ld at vaddr=%p\n,
  buf-size, +  buf-vaddr);
  
  Turning KERN_DEBUG into pr_err() is a bit harsh :-) In my opinion even
  KERN_DEBUG is too much here, I don't want to get messages printed to the
  kernel log every time I allocate buffers.
 
 Indeed, pr_err looks like an overkill:) I think pr_debug() would be fine
 here.
 
 return buf;
   
   }
  
  @@ -59,13 +63,87 @@ static void vb2_vmalloc_put(void *buf_priv)
  
 struct vb2_vmalloc_buf *buf = buf_priv;
 
 if (atomic_dec_and_test(buf-refcount)) {
  
  -  printk(KERN_DEBUG %s: Freeing vmalloc mem at vaddr=%p\n,
  -  __func__, buf-vaddr);
  +  pr_debug(%s: Freeing vmalloc mem at vaddr=%p\n, __func__,
  +   buf-vaddr);
  
  Same here. Should we get rid of those two messages, or at least
  conditionally- compile them out of the kernel by default ?
 
 During compilation pr_debug() will most likely be optimized away if DEBUG
 and CONFIG_DYNAMIC_DEBUG isn't defined, as it is then defined as:
 
 static inline __printf(1, 2)
 int no_printk(const char *fmt, ...)
 {
   return 0;
 }
 
 Plus it's easy with pr_debug() to enable debug trace while dynamic printk()
 is enabled in the kernel configuration.

My bad. pr_debug() is fine.

-- 
Regards,

Laurent Pinchart
--
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 v2] media: vb2: vmalloc-based allocator user pointer handling

2011-12-08 Thread Laurent Pinchart
Hi Marek and Andrzej,

Thanks for the patch.

On Wednesday 07 December 2011 17:29:06 Marek Szyprowski wrote:
 From: Andrzej Pietrasiewicz andrze...@samsung.com
 
 This patch adds support for user pointer memory buffers to vmalloc
 videobuf2 allocator.
 
 Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 ---
  drivers/media/video/videobuf2-vmalloc.c |   97
 --- 1 files changed, 89 insertions(+), 8
 deletions(-)
 
 diff --git a/drivers/media/video/videobuf2-vmalloc.c
 b/drivers/media/video/videobuf2-vmalloc.c index a3a8842..8843ad0 100644
 --- a/drivers/media/video/videobuf2-vmalloc.c
 +++ b/drivers/media/video/videobuf2-vmalloc.c
 @@ -12,6 +12,7 @@
 
  #include linux/module.h
  #include linux/mm.h
 +#include linux/sched.h
  #include linux/slab.h
  #include linux/vmalloc.h
 
 @@ -20,7 +21,10 @@
 
  struct vb2_vmalloc_buf {
   void*vaddr;
 + struct page **pages;
 + int write;
   unsigned long   size;
 + unsigned intn_pages;
   atomic_trefcount;
   struct vb2_vmarea_handler   handler;
  };
 @@ -42,14 +46,14 @@ static void *vb2_vmalloc_alloc(void *alloc_ctx,
 unsigned long size) buf-handler.arg = buf;
 
   if (!buf-vaddr) {
 - printk(KERN_ERR vmalloc of size %ld failed\n, buf-size);
 + pr_err(vmalloc of size %ld failed\n, buf-size);
   kfree(buf);
   return NULL;
   }
 
   atomic_inc(buf-refcount);
 - printk(KERN_DEBUG Allocated vmalloc buffer of size %ld at vaddr=%p\n,
 - buf-size, buf-vaddr);
 + pr_err(Allocated vmalloc buffer of size %ld at vaddr=%p\n, buf-size,
 +buf-vaddr);

Turning KERN_DEBUG into pr_err() is a bit harsh :-) In my opinion even 
KERN_DEBUG is too much here, I don't want to get messages printed to the 
kernel log every time I allocate buffers.

   return buf;
  }
 @@ -59,13 +63,87 @@ static void vb2_vmalloc_put(void *buf_priv)
   struct vb2_vmalloc_buf *buf = buf_priv;
 
   if (atomic_dec_and_test(buf-refcount)) {
 - printk(KERN_DEBUG %s: Freeing vmalloc mem at vaddr=%p\n,
 - __func__, buf-vaddr);
 + pr_debug(%s: Freeing vmalloc mem at vaddr=%p\n, __func__,
 +  buf-vaddr);

Same here. Should we get rid of those two messages, or at least conditionally-
compile them out of the kernel by default ?

   vfree(buf-vaddr);
   kfree(buf);
   }
  }
 
 +static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr,
 +  unsigned long size, int write)
 +{
 + struct vb2_vmalloc_buf *buf;
 +

No need for a blank line.

 + unsigned long first, last;
 + int n_pages_from_user, offset;

You seem to like long names :-) I'd use n_pages, and I would also shorten the 
labels below, but that's just me.

 + buf = kzalloc(sizeof *buf, GFP_KERNEL);

The kernel coding style encourages parenthesis after the sizeof operator: 
sizeof(*buf).

 + if (!buf)
 + return NULL;
 +
 + buf-write = write;
 + offset = vaddr  ~PAGE_MASK;
 + buf-size = size;
 +
 + first = (vaddr  PAGE_MASK)  PAGE_SHIFT;
 + last  = ((vaddr + size - 1)  PAGE_MASK)  PAGE_SHIFT;

If you shift right anyway is there a need to  PAGE_MASK first ?

 + buf-n_pages = last - first + 1;
 + buf-pages = kzalloc(buf-n_pages * sizeof(struct page *), GFP_KERNEL);

It's a common practice in the kernel to use variables instead of types when 
possible with the sizeof operator: sizeof(buf-pages). That's up to you.

 + if (!buf-pages)
 + goto userptr_fail_pages_array_alloc;
 +
 + /* current-mm-mmap_sem is taken by videobuf core */
 + n_pages_from_user = get_user_pages(current, current-mm,
 +  vaddr  PAGE_MASK,
 +  buf-n_pages,
 +  write,
 +  1, /* force */
 +  buf-pages,
 +  NULL);
 + if (n_pages_from_user != buf-n_pages)
 + goto userptr_fail_get_user_pages;
 +
 + buf-vaddr = vm_map_ram(buf-pages, buf-n_pages, -1, PAGE_KERNEL);
 +

No need for a blank line.

 + if (!buf-vaddr)
 + goto userptr_fail_get_user_pages;
 +
 + buf-vaddr += offset;
 + return buf;
 +
 +userptr_fail_get_user_pages:
 + pr_debug(get_user_pages requested/got: %d/%d]\n, n_pages_from_user,
 +  buf-n_pages);
 + while (--n_pages_from_user = 0)
 + put_page(buf-pages[n_pages_from_user]);
 + kfree(buf-pages);
 +
 +userptr_fail_pages_array_alloc:
 + 

[PATCH v2] media: vb2: vmalloc-based allocator user pointer handling

2011-12-07 Thread Marek Szyprowski
From: Andrzej Pietrasiewicz andrze...@samsung.com

This patch adds support for user pointer memory buffers to vmalloc
videobuf2 allocator.

Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/media/video/videobuf2-vmalloc.c |   97 ---
 1 files changed, 89 insertions(+), 8 deletions(-)

diff --git a/drivers/media/video/videobuf2-vmalloc.c 
b/drivers/media/video/videobuf2-vmalloc.c
index a3a8842..8843ad0 100644
--- a/drivers/media/video/videobuf2-vmalloc.c
+++ b/drivers/media/video/videobuf2-vmalloc.c
@@ -12,6 +12,7 @@
 
 #include linux/module.h
 #include linux/mm.h
+#include linux/sched.h
 #include linux/slab.h
 #include linux/vmalloc.h
 
@@ -20,7 +21,10 @@
 
 struct vb2_vmalloc_buf {
void*vaddr;
+   struct page **pages;
+   int write;
unsigned long   size;
+   unsigned intn_pages;
atomic_trefcount;
struct vb2_vmarea_handler   handler;
 };
@@ -42,14 +46,14 @@ static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned 
long size)
buf-handler.arg = buf;
 
if (!buf-vaddr) {
-   printk(KERN_ERR vmalloc of size %ld failed\n, buf-size);
+   pr_err(vmalloc of size %ld failed\n, buf-size);
kfree(buf);
return NULL;
}
 
atomic_inc(buf-refcount);
-   printk(KERN_DEBUG Allocated vmalloc buffer of size %ld at vaddr=%p\n,
-   buf-size, buf-vaddr);
+   pr_err(Allocated vmalloc buffer of size %ld at vaddr=%p\n, buf-size,
+  buf-vaddr);
 
return buf;
 }
@@ -59,13 +63,87 @@ static void vb2_vmalloc_put(void *buf_priv)
struct vb2_vmalloc_buf *buf = buf_priv;
 
if (atomic_dec_and_test(buf-refcount)) {
-   printk(KERN_DEBUG %s: Freeing vmalloc mem at vaddr=%p\n,
-   __func__, buf-vaddr);
+   pr_debug(%s: Freeing vmalloc mem at vaddr=%p\n, __func__,
+buf-vaddr);
vfree(buf-vaddr);
kfree(buf);
}
 }
 
+static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr,
+unsigned long size, int write)
+{
+   struct vb2_vmalloc_buf *buf;
+
+   unsigned long first, last;
+   int n_pages_from_user, offset;
+
+   buf = kzalloc(sizeof *buf, GFP_KERNEL);
+   if (!buf)
+   return NULL;
+
+   buf-write = write;
+   offset = vaddr  ~PAGE_MASK;
+   buf-size = size;
+
+   first = (vaddr  PAGE_MASK)  PAGE_SHIFT;
+   last  = ((vaddr + size - 1)  PAGE_MASK)  PAGE_SHIFT;
+   buf-n_pages = last - first + 1;
+   buf-pages = kzalloc(buf-n_pages * sizeof(struct page *), GFP_KERNEL);
+   if (!buf-pages)
+   goto userptr_fail_pages_array_alloc;
+
+   /* current-mm-mmap_sem is taken by videobuf core */
+   n_pages_from_user = get_user_pages(current, current-mm,
+vaddr  PAGE_MASK,
+buf-n_pages,
+write,
+1, /* force */
+buf-pages,
+NULL);
+   if (n_pages_from_user != buf-n_pages)
+   goto userptr_fail_get_user_pages;
+
+   buf-vaddr = vm_map_ram(buf-pages, buf-n_pages, -1, PAGE_KERNEL);
+
+   if (!buf-vaddr)
+   goto userptr_fail_get_user_pages;
+
+   buf-vaddr += offset;
+   return buf;
+
+userptr_fail_get_user_pages:
+   pr_debug(get_user_pages requested/got: %d/%d]\n, n_pages_from_user,
+buf-n_pages);
+   while (--n_pages_from_user = 0)
+   put_page(buf-pages[n_pages_from_user]);
+   kfree(buf-pages);
+
+userptr_fail_pages_array_alloc:
+   kfree(buf);
+
+   return NULL;
+}
+
+static void vb2_vmalloc_put_userptr(void *buf_priv)
+{
+   struct vb2_vmalloc_buf *buf = buf_priv;
+
+   unsigned int i;
+   int offset = (unsigned long)buf-vaddr  ~PAGE_MASK;
+
+   if (buf-vaddr)
+   vm_unmap_ram((const void *)((unsigned long)buf-vaddr - offset),
+buf-n_pages);
+   for (i = 0; i  buf-n_pages; ++i) {
+   if (buf-write)
+   set_page_dirty_lock(buf-pages[i]);
+   put_page(buf-pages[i]);
+   }
+   kfree(buf-pages);
+   kfree(buf);
+}
+
 static void *vb2_vmalloc_vaddr(void *buf_priv)
 {
struct vb2_vmalloc_buf *buf = buf_priv;
@@ -73,7 +151,8 @@ static void *vb2_vmalloc_vaddr(void *buf_priv)
BUG_ON(!buf);
 
if (!buf-vaddr) {
-   printk(KERN_ERR Address of