X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fmm.c;h=d71cb968e0467216e5db02141b162868320c2950;hb=25569fd796d1e1bb160b1b25ece9d4d3422720be;hp=ef6e1bddaaf4a5b354d70c994e8e95082a8eb473;hpb=791ea2f3e21cfbc9c47341efbb98995c33d86fcb;p=palacios.git diff --git a/linux_module/mm.c b/linux_module/mm.c index ef6e1bd..d71cb96 100644 --- a/linux_module/mm.c +++ b/linux_module/mm.c @@ -11,6 +11,8 @@ #include "palacios.h" +#define OFFLINE_POOL_THRESHOLD 12 + struct mempool { uintptr_t base_addr; u64 num_pages; @@ -43,6 +45,14 @@ 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; @@ -58,7 +68,7 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) { } if (alignment > 0) { - step = alignment / 4096; + step = alignment / PAGE_SIZE; } // Start the search at the correct alignment @@ -66,7 +76,7 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) { start = ((alignment - (pool.base_addr % alignment)) >> 12); } - ERROR("\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) { @@ -88,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); } } - /* ERROR("PALACIOS BAD: LARGE PAGE ALLOCATION FAILED\n"); */ + ERROR("ALERT ALERT Allocation of Large Number of Contiguous Pages FAILED\n"); return 0; } @@ -102,24 +112,45 @@ 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) { ERROR("PALACIOS BAD: SMALL PAGE ALLOCATION FAILED\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 { //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"); + } } @@ -133,21 +164,32 @@ void free_palacios_pgs(uintptr_t pg_addr, int num_pages) { //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) { - ERROR("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)); } } @@ -167,15 +209,15 @@ int add_palacios_memory(uintptr_t base_addr, u64 num_pages) { } DEBUG("Managing %dMB of memory starting at %llu (%lluMB)\n", - (unsigned int)(num_pages * 4096) / (1024 * 1024), + (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)) { - WARNING("Error allocating Palacios MM bitmap\n"); + ERROR("Error allocating Palacios MM bitmap\n"); return -1; } @@ -190,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; @@ -199,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; }