[v4,1/3] videobuf2-dma-contig: user can specify GFP flags

Message ID 1357493343-13090-1-git-send-email-federico.vaga@gmail.com (mailing list archive)
State RFC, archived
Headers

Commit Message

Federico Vaga Jan. 6, 2013, 5:29 p.m. UTC
  This is useful when you need to specify specific GFP flags during memory
allocation (e.g. GFP_DMA).

Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 7 ++-----
 include/media/videobuf2-dma-contig.h           | 5 +++++
 2 file modificati, 7 inserzioni(+), 5 rimozioni(-)
  

Comments

Marek Szyprowski Jan. 8, 2013, 6:53 a.m. UTC | #1
Hello,

On 1/6/2013 6:29 PM, Federico Vaga wrote:
> This is useful when you need to specify specific GFP flags during memory
> allocation (e.g. GFP_DMA).
>
> Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
> ---
>   drivers/media/v4l2-core/videobuf2-dma-contig.c | 7 ++-----
>   include/media/videobuf2-dma-contig.h           | 5 +++++
>   2 file modificati, 7 inserzioni(+), 5 rimozioni(-)
>
> diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
> index 10beaee..bb411c0 100644
> --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
> +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
> @@ -21,10 +21,6 @@
>   #include <media/videobuf2-dma-contig.h>
>   #include <media/videobuf2-memops.h>
>   
> -struct vb2_dc_conf {
> -	struct device		*dev;
> -};
> -
>   struct vb2_dc_buf {
>   	struct device			*dev;
>   	void				*vaddr;
> @@ -165,7 +161,8 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
>   	/* align image size to PAGE_SIZE */
>   	size = PAGE_ALIGN(size);
>   
> -	buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL);
> +	buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr,
> +									GFP_KERNEL | conf->mem_flags);

I think we can add GFP_DMA flag unconditionally to the vb2_dc_contig 
allocator.
It won't hurt existing clients as most of nowadays platforms doesn't 
have DMA
zone (GFP_DMA is ignored in such case), but it should fix the issues 
with some
older and non-standard systems.

>   	if (!buf->vaddr) {
>   		dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
>   		kfree(buf);
> diff --git a/include/media/videobuf2-dma-contig.h b/include/media/videobuf2-dma-contig.h
> index 8197f87..22733f4 100644
> --- a/include/media/videobuf2-dma-contig.h
> +++ b/include/media/videobuf2-dma-contig.h
> @@ -16,6 +16,11 @@
>   #include <media/videobuf2-core.h>
>   #include <linux/dma-mapping.h>
>   
> +struct vb2_dc_conf {
> +	struct device		*dev;
> +	gfp_t				mem_flags;
> +};
> +
>   static inline dma_addr_t
>   vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no)
>   {

Best regards
  
Federico Vaga Jan. 8, 2013, 10:15 a.m. UTC | #2
> > @@ -165,7 +161,8 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned
> > long size)> 
> >   	/* align image size to PAGE_SIZE */
> >   	size = PAGE_ALIGN(size);
> > 
> > -	buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, 
GFP_KERNEL);
> > +	buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr,
> > +									
GFP_KERNEL | conf->mem_flags);
> 
> I think we can add GFP_DMA flag unconditionally to the vb2_dc_contig
> allocator.
> It won't hurt existing clients as most of nowadays platforms doesn't
> have DMA
> zone (GFP_DMA is ignored in such case), but it should fix the issues
> with some
> older and non-standard systems.

I did not set GFP_DMA fixed in the allocator because I do not want to brake 
something in the future. On x86 platform GFP_DMA allocates under 16MB and this 
limit can be too strict. When many other drivers use GFP_DMA we can saturate 
this tiny zone.
As you said, this fix the issue with _older_ and _non-standard_ (like sta2x11) 
systems. But this fix has effect on every other standard and new systems. 
That's why I preferred to set the flag optionally.
  
Marek Szyprowski Jan. 8, 2013, 10:40 a.m. UTC | #3
Hello,

On 1/8/2013 11:15 AM, Federico Vaga wrote:
> > > @@ -165,7 +161,8 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned
> > > long size)>
> > >   	/* align image size to PAGE_SIZE */
> > >   	size = PAGE_ALIGN(size);
> > >
> > > -	buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr,
> GFP_KERNEL);
> > > +	buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr,
> > > +									
> GFP_KERNEL | conf->mem_flags);
> >
> > I think we can add GFP_DMA flag unconditionally to the vb2_dc_contig
> > allocator.
> > It won't hurt existing clients as most of nowadays platforms doesn't
> > have DMA
> > zone (GFP_DMA is ignored in such case), but it should fix the issues
> > with some
> > older and non-standard systems.
>
> I did not set GFP_DMA fixed in the allocator because I do not want to brake
> something in the future. On x86 platform GFP_DMA allocates under 16MB and this
> limit can be too strict. When many other drivers use GFP_DMA we can saturate
> this tiny zone.
> As you said, this fix the issue with _older_ and _non-standard_ (like sta2x11)
> systems. But this fix has effect on every other standard and new systems.
> That's why I preferred to set the flag optionally.

Ok, then I would simply pass the flags from the driver without any 
alternation
in the allocator itself, so drivers can pass 'GFP_KERNEL' or
'GFP_KERNEL | GFP_DMA' depending on their preference. Please also update 
all
the existing clients of vb2_dma_dc allocator.

Best regards
  
Federico Vaga Jan. 8, 2013, 2:58 p.m. UTC | #4
> Ok, then I would simply pass the flags from the driver without any
> alternation
> in the allocator itself, so drivers can pass 'GFP_KERNEL' or
> 'GFP_KERNEL | GFP_DMA' depending on their preference. Please also update
> all
> the existing clients of vb2_dma_dc allocator.

I taked a look at drivers that use dma-contig. They use the structure 
vb2_alloc_ctx which is just a name, there is not a real vb2_alloc_ctx 
structure implementation. "Now" driver must gain access to vb2_dc_conf to set 
the correct flags.

I have the following ideas:

  1.  replace all the names and expose vb2_dc_conf to all drivers (like dma-
sg, it export vb2_dma_sg_desc to all its users)

  2.  create an helper which configure flags. This maintain the vb2_dc_conf 
private
      vb2_set_mem_flags(struct vb2_alloc_ctx *alloc_ctx, gfp_t flags)

  3.  rename vb2_dc_conf to vb2_alloc_ctx because it is an implementation 
vb2_alloc_ctx and (at the moment) it is used only by dma-contig
  

Patch

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 10beaee..bb411c0 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -21,10 +21,6 @@ 
 #include <media/videobuf2-dma-contig.h>
 #include <media/videobuf2-memops.h>
 
-struct vb2_dc_conf {
-	struct device		*dev;
-};
-
 struct vb2_dc_buf {
 	struct device			*dev;
 	void				*vaddr;
@@ -165,7 +161,8 @@  static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 	/* align image size to PAGE_SIZE */
 	size = PAGE_ALIGN(size);
 
-	buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL);
+	buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr,
+									GFP_KERNEL | conf->mem_flags);
 	if (!buf->vaddr) {
 		dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
 		kfree(buf);
diff --git a/include/media/videobuf2-dma-contig.h b/include/media/videobuf2-dma-contig.h
index 8197f87..22733f4 100644
--- a/include/media/videobuf2-dma-contig.h
+++ b/include/media/videobuf2-dma-contig.h
@@ -16,6 +16,11 @@ 
 #include <media/videobuf2-core.h>
 #include <linux/dma-mapping.h>
 
+struct vb2_dc_conf {
+	struct device		*dev;
+	gfp_t				mem_flags;
+};
+
 static inline dma_addr_t
 vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no)
 {