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

Reply via email to