Re: OMAPFB: CMA allocation failures

From: Tomi Valkeinen
Date: Thu Dec 05 2013 - 06:25:56 EST


On 2013-11-30 12:00, Ivajlo Dimitrov wrote:
> Ping?
>
> ----- Original Message ----- From: "ÐÐÐÐÐÐ ÐÐÐÐÑÑÐÐ" <freemangordon@xxxxxx>
> To: "Tomi Valkeinen" <tomi.valkeinen@xxxxxx>
> Cc: <minchan@xxxxxxxxxx>; <pavel@xxxxxx>; <sre@xxxxxxxxxx>;
> <pali.rohar@xxxxxxxxx>; <pc+n900@xxxxxxxx>;
> <linux-kernel@xxxxxxxxxxxxxxx>; <linux-mm@xxxxxxxxx>
> Sent: Tuesday, November 05, 2013 9:55 PM
> Subject: Re: OMAPFB: CMA allocation failures
>
>
>>
>>
>>
>>
>>
>> >-------- ÐÑÐÐÐÐÐÐÐÐ ÐÐÑÐÐ --------
>> >ÐÑ: Tomi Valkeinen
>> >ÐÑÐÐÑÐÐ: Re: OMAPFB: CMA allocation failures
>> >ÐÐ: ÐÐÐÐÐÐ ÐÐÐÐÑÑÐÐ
>> >ÐÐÐÑÐÑÐÐÐ ÐÐ: ÐÑÑÐÐ, 2013, ÐÐÑÐÐÐÑÐ 30 14:19:32 EET
>> >
>> >I really dislike the idea of adding the omap vram allocator back. Then
>> >again, if the CMA doesn't work, something has to be done.
>> >
>>
>> If I got Minchan Kim's explanation correctly, CMA simply can't be used
>> for allocation of framebuffer memory, because it is unreliable.

Well. All memory allocation is unreliable. And
include/linux/dma-contiguous.h even clearly states that CMA is something
to be used in cases like omapfb.

>> >Pre-allocating is possible, but that won't work if there's any need to
>> >re-allocating the framebuffers. Except if the omapfb would retain and
>> >manage the pre-allocated buffers, but that would just be more or less
>> >the old vram allocator again.
>> >
>> >So, as I see it, the best option would be to have the standard dma_alloc
>> >functions get the memory for omapfb from a private pool, which is not
>> >used for anything else.
>> >
>> >I wonder if that's possible already? It sounds quite trivial to me.
>>
>> dma_alloc functions use either CMA or (iirc) get_pages_exact if CMA is
>> disabled. Both of those fail easily. AFAIK there are several
>> implementations with similar functionality, like CMEM and ION but
>> (correct me if I am wrong) neither of them is upstreamed. In the
>> current kernel I don't see anything that can be used for the purpose
>> of reliable allocation of big chunks of contiguous memory.
>> So, something should be done, but honestly, I can't think of anything
>> but bringing VRAM allocator back. Not that I like the idea of bringing
>> back ~700 lines of code, but I see no other option if omapfb driver is
>> to be actually useful.

How about the patch below? If I'm not mistaken (and I might) it reserves
separate memory area for omapfb, which is not used by CMA.

If it works, it should be extended to get the parameters via kernel
cmdline, and use that alloc only if the user requests it.


diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c
index 2dabb9ecb986..9beecded0380 100644
--- a/arch/arm/mach-omap2/common.c
+++ b/arch/arm/mach-omap2/common.c
@@ -33,4 +33,5 @@ void __init omap_reserve(void)
omap_dsp_reserve_sdram_memblock();
omap_secure_ram_reserve_memblock();
omap_barrier_reserve_memblock();
+ omap_fb_reserve_memblock();
}
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 48e9cd34cae0..874786f05ec3 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -40,6 +40,8 @@

#include "usb.h"

+void __init omap_fb_reserve_memblock(void);
+
#define OMAP_INTC_START NR_IRQS

#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP2)
diff --git a/arch/arm/mach-omap2/fb.c b/arch/arm/mach-omap2/fb.c
index 26e28e94f625..8f339e88c7cd 100644
--- a/arch/arm/mach-omap2/fb.c
+++ b/arch/arm/mach-omap2/fb.c
@@ -30,9 +30,11 @@
#include <linux/dma-mapping.h>

#include <asm/mach/map.h>
+#include <asm/memblock.h>

#include "soc.h"
#include "display.h"
+#include "common.h"

#ifdef CONFIG_OMAP2_VRFB

@@ -106,9 +108,41 @@ static struct platform_device omap_fb_device = {
.num_resources = 0,
};

+static phys_addr_t omapfb_mem_base __initdata;
+static phys_addr_t omapfb_mem_size __initdata;
+
+void __init omap_fb_reserve_memblock(void)
+{
+ omapfb_mem_size = ALIGN(1920*1200*4*3, SZ_2M);
+ omapfb_mem_base = arm_memblock_steal(omapfb_mem_size, SZ_2M);
+ if (omapfb_mem_base)
+ pr_info("omapfb: reserved %u bytes at %x\n",
+ omapfb_mem_size, omapfb_mem_base);
+ else
+ pr_err("omapfb: arm_memblock_steal failed\n");
+}
+
int __init omap_init_fb(void)
{
- return platform_device_register(&omap_fb_device);
+ int r;
+ int dma;
+
+ r = platform_device_register(&omap_fb_device);
+ if (r)
+ return r;
+
+ if (!omapfb_mem_base)
+ return 0;
+
+ dma = dma_declare_coherent_memory(&omap_fb_device.dev,
+ omapfb_mem_base, omapfb_mem_base,
+ omapfb_mem_size,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+ if (!(dma & DMA_MEMORY_MAP))
+ pr_err("omapfb: dma_declare_coherent_memory failed\n");
+
+ return 0;
}
#else
int __init omap_init_fb(void) { return 0; }


Attachment: signature.asc
Description: OpenPGP digital signature