Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


update palacios mempool status when onlining memory in userspace
[palacios.git] / linux_module / mm.c
index 166cfd2..d71cb96 100644 (file)
@@ -9,6 +9,9 @@
 #include <linux/mm.h>
 //static struct list_head pools;
 
+#include "palacios.h"
+
+#define OFFLINE_POOL_THRESHOLD 12
 
 struct mempool {
     uintptr_t base_addr;
@@ -42,22 +45,30 @@ static inline void clear_page_bit(int index) {
 }
 
 
+uintptr_t get_palacios_base_addr(void) {
+    return pool.base_addr;
+}
+
+u64 get_palacios_num_pages(void) {
+    return pool.num_pages;
+}
+
 
 static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) {
     int step = 1;
     int i = 0;
     int start = 0;
 
-    printk("Allocating %llu pages (align=%lu)\n", 
+    DEBUG("Allocating %llu pages (align=%lu)\n", 
           num_pages, (unsigned long)alignment);
 
     if (pool.bitmap == NULL) {
-       printk("ERROR: Attempting to allocate from non initialized memory\n");
+       ERROR("ERROR: Attempting to allocate from non initialized memory\n");
        return 0;
     }
 
     if (alignment > 0) {
-       step = alignment / 4096;
+       step = alignment / PAGE_SIZE;
     }
 
     // Start the search at the correct alignment 
@@ -65,7 +76,7 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) {
        start = ((alignment - (pool.base_addr % alignment)) >> 12);
     }
 
-    printk("\t Start idx %d (base_addr=%p)\n", start, (void *)(u64)pool.base_addr);
+    DEBUG("\t Start idx %d (base_addr=%p)\n", start, (void *)(u64)pool.base_addr);
 
     for (i = start; i < (pool.num_pages - num_pages); i += step) {
        if (get_page_bit(i) == 0) {
@@ -87,11 +98,11 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) {
                set_page_bit(j);
            }
 
-           return pool.base_addr + (i * 4096);
+           return pool.base_addr + (i * PAGE_SIZE);
        }
     }
 
-    /* printk("PALACIOS BAD: LARGE PAGE ALLOCATION FAILED\n"); */
+    ERROR("ALERT ALERT Allocation of Large Number of Contiguous Pages FAILED\n"); 
 
     return 0;
 }
@@ -101,52 +112,84 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) {
 uintptr_t alloc_palacios_pgs(u64 num_pages, u32 alignment) {
     uintptr_t addr = 0; 
 
-    if ((num_pages < 12)) {
+    if (num_pages < OFFLINE_POOL_THRESHOLD) {
        struct page * pgs = NULL;
+       void *temp;
        int order = get_order(num_pages * PAGE_SIZE);
         
        pgs = alloc_pages(GFP_DMA32, order);
     
-       WARN(!pgs, "Could not allocate pages\n");
+       if (!pgs) { 
+           ERROR("Could not allocate small number of contigious pages\n");
+           return 0;
+       }
  
-        /* if (!pgs) { printk("PALACIOS BAD: SMALL PAGE ALLOCATION FAILED\n");  } */
-       
-       /* printk("%llu pages (order=%d) aquired from alloc_pages\n", 
+       /* DEBUG("%llu pages (order=%d) aquired from alloc_pages\n", 
               num_pages, order); */
 
        addr = page_to_pfn(pgs) << PAGE_SHIFT; 
+
+       temp = (void*)addr;
+
+       if ( (temp>=(void*)(pool.base_addr) && 
+             (temp<((void*)(pool.base_addr)+pool.num_pages*PAGE_SIZE))) 
+            || ((temp+num_pages*PAGE_SIZE)>=(void*)(pool.base_addr) && 
+                ((temp+num_pages*PAGE_SIZE)<((void*)(pool.base_addr)+pool.num_pages*PAGE_SIZE))) ) {
+
+           ERROR("ALERT ALERT Allocation of small number of contiguous pages returned block that "
+                 "OVERLAPS with the offline page pool addr=%p, addr+numpages=%p, "
+                 "pool.base_addr=%p, pool.base_addr+pool.numpages=%p\n", 
+                 temp, temp+num_pages*PAGE_SIZE, (void*)(pool.base_addr), 
+                 (void*)(pool.base_addr)+pool.num_pages*PAGE_SIZE);
+       }
+
+       
     } else {
-       //printk("Allocating %llu pages from bitmap allocator\n", num_pages);
+       //DEBUG("Allocating %llu pages from bitmap allocator\n", num_pages);
        //addr = pool.base_addr;
        addr = alloc_contig_pgs(num_pages, alignment);
+       if (!addr) { 
+           ERROR("Could not allocate large number of contiguous pages\n");
+       }
     }
 
 
-    //printk("Returning from alloc addr=%p, vaddr=%p\n", (void *)addr, __va(addr));
+    //DEBUG("Returning from alloc addr=%p, vaddr=%p\n", (void *)addr, __va(addr));
     return addr;
 }
 
 
 
 void free_palacios_pgs(uintptr_t pg_addr, int num_pages) {
-    //printk("Freeing Memory page %p\n", (void *)pg_addr);
+    //DEBUG("Freeing Memory page %p\n", (void *)pg_addr);
 
     if ((pg_addr >= pool.base_addr) && 
-       (pg_addr < pool.base_addr + (4096 * pool.num_pages))) {
-       int pg_idx = (pg_addr - pool.base_addr) / 4096;
+       (pg_addr < pool.base_addr + (PAGE_SIZE * pool.num_pages))) {
+       int pg_idx = (pg_addr - pool.base_addr) / PAGE_SIZE;
        int i = 0;
 
+
+       if (num_pages<OFFLINE_POOL_THRESHOLD) { 
+           ERROR("ALERT ALERT  small page deallocation from offline pool\n");
+           return;
+        }      
+
        if ((pg_idx + num_pages) > pool.num_pages) {
-           printk("Freeing memory bounds exceeded\n");
+           ERROR("Freeing memory bounds exceeded for offline pool\n");
            return;
        }
 
        for (i = 0; i < num_pages; i++) {
-           WARN(get_page_bit(pg_idx + i) == 0, "Trying to free unallocated page\n");
-
+           if (get_page_bit(pg_idx + i) == 0) { 
+               ERROR("Trying to free unallocated page from offline pool\n");
+           }
            clear_page_bit(pg_idx + i);
        }
+       
     } else {
+       if (num_pages>=OFFLINE_POOL_THRESHOLD) {
+          ERROR("ALERT ALERT Large page deallocation from linux pool\n");
+       }
        __free_pages(pfn_to_page(pg_addr >> PAGE_SHIFT), get_order(num_pages * PAGE_SIZE));
     }
 }
@@ -161,20 +204,20 @@ int add_palacios_memory(uintptr_t base_addr, u64 num_pages) {
     int bitmap_size = (num_pages / 8) + ((num_pages % 8) > 0); 
 
     if (pool.num_pages != 0) {
-       printk("ERROR: Memory has already been added\n");
+       ERROR("ERROR: Memory has already been added\n");
        return -1;
     }
 
-    printk("Managing %dMB of memory starting at %llu (%lluMB)\n", 
-          (unsigned int)(num_pages * 4096) / (1024 * 1024), 
+    DEBUG("Managing %dMB of memory starting at %llu (%lluMB)\n", 
+          (unsigned int)(num_pages * PAGE_SIZE) / (1024 * 1024), 
           (unsigned long long)base_addr, 
           (unsigned long long)(base_addr / (1024 * 1024)));
 
 
-    pool.bitmap = kmalloc(bitmap_size, GFP_KERNEL);
+    pool.bitmap = palacios_alloc(bitmap_size);
     
     if (IS_ERR(pool.bitmap)) {
-       printk("Error allocating Palacios MM bitmap\n");
+       ERROR("Error allocating Palacios MM bitmap\n");
        return -1;
     }
     
@@ -189,7 +232,7 @@ int add_palacios_memory(uintptr_t base_addr, u64 num_pages) {
 
 
 int palacios_init_mm( void ) {
-    //    INIT_LIST_HEAD(&(pools));
+
     pool.base_addr = 0;
     pool.num_pages = 0;
     pool.bitmap = NULL;
@@ -198,7 +241,15 @@ int palacios_init_mm( void ) {
 }
 
 int palacios_deinit_mm( void ) {
-    kfree(pool.bitmap);
+
+    palacios_free(pool.bitmap);
+
+    pool.bitmap=0;
+    pool.base_addr=0;
+    pool.num_pages=0;
+
+    // note that the memory is not onlined here - offlining and onlining
+    // is the resposibility of the caller
     
     return 0;
 }