X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fmm.c;h=d71cb968e0467216e5db02141b162868320c2950;hb=5f9290a9547c1497c6070b35e32caa7fc388d189;hp=04dcab32787bd96ea20c7aa962fc98853180badc;hpb=ed7cae62acb31ddd833c7efb0f6cda1b4915e7cb;p=palacios.git diff --git a/linux_module/mm.c b/linux_module/mm.c index 04dcab3..d71cb96 100644 --- a/linux_module/mm.c +++ b/linux_module/mm.c @@ -9,6 +9,9 @@ #include //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,10 +98,12 @@ 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); } } + ERROR("ALERT ALERT Allocation of Large Number of Contiguous Pages FAILED\n"); + return 0; } @@ -99,50 +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_DMA, order); + pgs = alloc_pages(GFP_DMA32, order); - WARN(!pgs, "Could not allocate pages\n"); - - printk("%llu pages (order=%d) aquired from alloc_pages\n", - num_pages, order); + if (!pgs) { + ERROR("Could not allocate small number of contigious pages\n"); + return 0; + } + + /* 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 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)); } } @@ -157,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; } @@ -185,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; @@ -194,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; }