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.


Cleanup and sanity-checking of integer overflow, null comparisons, dead code (Coverit...
[palacios.git] / linux_module / mm.c
index c5ec916..8eb8fc9 100644 (file)
@@ -21,20 +21,9 @@ static uintptr_t * seed_addrs = NULL;
 
 
 // alignment is in bytes
-uintptr_t alloc_palacios_pgs(u64 num_pages, u32 alignment, int node_id, int constraints) {
+uintptr_t alloc_palacios_pgs(u64 num_pages, u32 alignment, int node_id, int (*filter_func)(void *paddr, void *filter_state), void *filter_state) {
     uintptr_t addr = 0; 
     int any = node_id==-1; // can allocate on any
-    int buddy_constraints=0;
-
-    if (constraints && constraints!=V3_ALLOC_PAGES_CONSTRAINT_4GB) { 
-       ERROR("Unknown constraint mask 0x%x\n",constraints);
-       return 0;
-    }
-    
-    if (constraints & V3_ALLOC_PAGES_CONSTRAINT_4GB) { 
-       buddy_constraints |= LWK_BUDDY_CONSTRAINT_4GB;
-    }
-
 
     if (node_id == -1) {
        int cpu_id = get_cpu();
@@ -50,14 +39,14 @@ uintptr_t alloc_palacios_pgs(u64 num_pages, u32 alignment, int node_id, int cons
        return 0;
     }
 
-    addr = buddy_alloc(memzones[node_id], get_order(num_pages * PAGE_SIZE) + PAGE_SHIFT, buddy_constraints);
+    addr = buddy_alloc(memzones[node_id], get_order(num_pages * PAGE_SIZE) + PAGE_SHIFT, filter_func, filter_state);
 
     if (!addr && any) { 
        int i;
        // do a scan to see if we can satisfy request on any node
        for (i=0; i< numa_num_nodes(); i++) { 
            if (i!=node_id) { 
-               addr = buddy_alloc(memzones[i], get_order(num_pages * PAGE_SIZE) + PAGE_SHIFT, buddy_constraints);
+               addr = buddy_alloc(memzones[i], get_order(num_pages * PAGE_SIZE) + PAGE_SHIFT, filter_func, filter_state);
                if (addr) {
                    break;
                }
@@ -76,7 +65,19 @@ void free_palacios_pgs(uintptr_t pg_addr, u64 num_pages) {
     int node_id = numa_addr_to_node(pg_addr);
 
     //DEBUG("Freeing Memory page %p\n", (void *)pg_addr);
-    buddy_free(memzones[node_id], pg_addr, get_order(num_pages * PAGE_SIZE) + PAGE_SHIFT);
+    if (buddy_free(memzones[node_id], pg_addr, get_order(num_pages * PAGE_SIZE) + PAGE_SHIFT)) {
+      // it is possible that the allocation was actually on a different zone,
+      // so, just to be sure, we'll try to dellocate on each
+      for (node_id=0;node_id<numa_num_nodes();node_id++) { 
+        if (!buddy_free(memzones[node_id], pg_addr, get_order(num_pages * PAGE_SIZE) + PAGE_SHIFT)) {
+         // successfully freed on different zone, which is also OK
+         break;
+        }
+      }
+      if (node_id==numa_num_nodes()) { 
+       ERROR("Unable to free pages -addr=%p, numpages=%llu on any node\n",(void*)pg_addr,num_pages);
+      }
+    }
     
     return;
 }
@@ -89,16 +90,34 @@ unsigned long long pow2(int i)
     return x;
 }
 
+static unsigned long long get_palacios_mem_block_size(void)
+{
+    char *s = v3_lookup_option("mem_block_size");
+
+    if (!s) { 
+        return V3_CONFIG_MEM_BLOCK_SIZE;
+    } else {
+        unsigned long long temp;
+
+        if (strict_strtoull(s,0,&temp)) { 
+            return V3_CONFIG_MEM_BLOCK_SIZE; // odd...
+        } else {
+            return temp;
+        }
+    }
+}
+
 int add_palacios_memory(struct v3_mem_region *r) {
     int pool_order = 0;
     int node_id = 0;
 
+
     struct v3_mem_region *keep;
 
     INFO("Palacios Memory Add Request: type=%d, node=%d, base_addr=0x%llx, num_pages=%llu\n",r->type,r->node,r->base_addr,r->num_pages);
 
     // fixup request regardless of its type
-    if (r->num_pages*4096 < V3_CONFIG_MEM_BLOCK_SIZE) { 
+    if (r->num_pages*4096 < get_palacios_mem_block_size()) { 
        WARNING("Allocating a memory pool smaller than the Palacios block size - may not be useful\n");
     }
 
@@ -130,7 +149,7 @@ int add_palacios_memory(struct v3_mem_region *r) {
            ERROR("Unable to satisfy allocation request\n");
            palacios_free(keep);
            return -1;
-       }
+       } 
        r->base_addr = page_to_pfn(pgs) << PAGE_SHIFT;
     }
        
@@ -270,30 +289,44 @@ int palacios_init_mm( void ) {
 
        {
            struct page * pgs;
-
+           int actual_node;
+             
            // attempt to first allocate below 4 GB for compatibility with
            // 32 bit shadow paging
            pgs = alloc_pages_node(node_id, GFP_DMA32, MAX_ORDER - 1);
 
+
            if (!pgs) {
                INFO("Could not allocate initial memory block for node %d below 4GB\n", node_id);
                
                pgs = alloc_pages_node(node_id, GFP_KERNEL, MAX_ORDER - 1);
 
                if (!pgs) {
-                   INFO("Could not allocate initial memory block for node %d beloew 4GB\n", node_id);
+                   INFO("Could not allocate initial memory block for node %d below 4GB\n", node_id);
                    if (!pgs) {
                        ERROR("Could not allocate initial memory block for node %d without restrictions\n", node_id);
-                       BUG_ON(!pgs);
                        palacios_deinit_mm();
                        return -1;
                    }
+               } else {
+                 actual_node=numa_addr_to_node((uintptr_t)(page_to_pfn(pgs) << PAGE_SHIFT));
+                 if (actual_node != node_id) { 
+                   WARNING("Initial 64 bit allocation attempt for node %d resulted in allocation on node %d\n",node_id,actual_node);
+                 }
                }
+                 
+           } else {
+             actual_node=numa_addr_to_node((uintptr_t)(page_to_pfn(pgs) << PAGE_SHIFT));
+             if (actual_node != node_id) { 
+               WARNING("Initial 32bit-limited allocation attempt for node %d resulted in allocation on node %d\n",node_id,actual_node);
+             }
            }
 
            seed_addrs[node_id] = page_to_pfn(pgs) << PAGE_SHIFT;
        }
 
+    // Initialization is done using the compile-time memory block size since
+    // at this point, we do not yet know what the run-time size is
        zone = buddy_init(get_order(V3_CONFIG_MEM_BLOCK_SIZE) + PAGE_SHIFT, PAGE_SHIFT, node_id);
 
        if (zone == NULL) {