Module: xenomai-3 Branch: wip/dovetail Commit: 00ecc7cb46166bf983209b6e9a5090b05dc6472c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=00ecc7cb46166bf983209b6e9a5090b05dc6472c
Author: Philippe Gerum <r...@xenomai.org> Date: Sun Feb 28 08:23:32 2016 +0100 cobalt/init: get main heap memory from vmalloc() There is no reason to ask for physically contiguous memory from alloc_pages[_exact]() for the main heap: real-time heaps are certainly no place for getting DMA-suitable buffers from. Using alloc_pages*() for common Cobalt heaps is a problem: - this raises the probability of getting allocation failures in case of memory fragmentation (although seldom at boot time, some Cobalt-based modules also using such services could fail allocating their heap later on). - this restricts the maximum heap size to MAX_ORDER (currently 4Mb), which may be too small in some configurations. Therefore, switch from alloc_pages_exact() to vmalloc(). --- include/cobalt/kernel/heap.h | 4 ++++ kernel/cobalt/heap.c | 28 ++++++++++++++++++++++++++++ kernel/cobalt/init.c | 7 +++---- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/include/cobalt/kernel/heap.h b/include/cobalt/kernel/heap.h index 988004f..a1cea69 100644 --- a/include/cobalt/kernel/heap.h +++ b/include/cobalt/kernel/heap.h @@ -130,6 +130,10 @@ static inline void xnheap_cleanup_proc(void) { } /* Public interface. */ +void *xnheap_vmalloc(size_t size); + +void xnheap_vfree(void *p); + int xnheap_init(struct xnheap *heap, void *membase, u32 size); void xnheap_set_name(struct xnheap *heap, diff --git a/kernel/cobalt/heap.c b/kernel/cobalt/heap.c index 70f1c8f..2fcb6ba 100644 --- a/kernel/cobalt/heap.c +++ b/kernel/cobalt/heap.c @@ -21,6 +21,8 @@ #include <linux/slab.h> #include <linux/kernel.h> #include <linux/log2.h> +#include <linux/kconfig.h> +#include <asm/pgtable.h> #include <cobalt/kernel/assert.h> #include <cobalt/kernel/heap.h> #include <cobalt/kernel/vfile.h> @@ -655,4 +657,30 @@ out: } EXPORT_SYMBOL_GPL(xnheap_check_block); +void *xnheap_vmalloc(size_t size) +{ + /* + * We want memory used in real-time context to be pulled from + * ZONE_NORMAL, however we don't need it to be physically + * contiguous. + * + * 32bit systems which would need HIGHMEM for running a Cobalt + * configuration would also be required to support PTE + * pinning, which not all architectures provide. Moreover, + * pinning PTEs eagerly for a potentially (very) large amount + * of memory may quickly degrade performance. + * + * If using a different kernel/user memory split cannot be the + * answer for those configs, it's likely that basing such + * software on a 32bit system had to be wrong in the first + * place anyway. + */ + return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL); +} + +void xnheap_vfree(void *p) +{ + vfree(p); +} + /** @} */ diff --git a/kernel/cobalt/init.c b/kernel/cobalt/init.c index 0eab3be..6cbb67b 100644 --- a/kernel/cobalt/init.c +++ b/kernel/cobalt/init.c @@ -18,6 +18,7 @@ */ #include <linux/init.h> #include <linux/module.h> +#include <linux/vmalloc.h> #include <linux/ipipe_tickdev.h> #include <xenomai/version.h> #include <cobalt/kernel/sched.h> @@ -127,7 +128,6 @@ static void sys_shutdown(void) struct xnthread *thread, *tmp; struct xnsched *sched; void *membase; - u32 memsize; int cpu; spl_t s; @@ -155,9 +155,8 @@ static void sys_shutdown(void) xnregistry_cleanup(); membase = xnheap_get_membase(&cobalt_heap); - memsize = xnheap_get_size(&cobalt_heap); xnheap_destroy(&cobalt_heap); - free_pages_exact(membase, memsize); + vfree(membase); } static int __init mach_setup(void) @@ -290,7 +289,7 @@ static __init int sys_init(void) if (sysheap_size_arg == 0) sysheap_size_arg = CONFIG_XENO_OPT_SYS_HEAPSZ; - heapaddr = alloc_pages_exact(sysheap_size_arg * 1024, GFP_KERNEL); + heapaddr = vmalloc(sysheap_size_arg * 1024); if (heapaddr == NULL || xnheap_init(&cobalt_heap, heapaddr, sysheap_size_arg * 1024)) { return -ENOMEM; _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git