diff --git a/lab2/kernel/mm/buddy.c b/lab2/kernel/mm/buddy.c index 37bfd97..88b680b 100644 --- a/lab2/kernel/mm/buddy.c +++ b/lab2/kernel/mm/buddy.c @@ -11,68 +11,66 @@ * The usable memory: [pool_start_addr, pool_start_addr + pool_mem_size). */ void init_buddy(struct phys_mem_pool *pool, struct page *start_page, - vaddr_t start_addr, u64 page_num) -{ - int order; - int page_idx; - struct page *page; + vaddr_t start_addr, u64 page_num) { + int order; + int page_idx; + struct page *page; - /* Init the physical memory pool. */ - pool->pool_start_addr = start_addr; - pool->page_metadata = start_page; - pool->pool_mem_size = page_num * BUDDY_PAGE_SIZE; - /* This field is for unit test only. */ - pool->pool_phys_page_num = page_num; + /* Init the physical memory pool. */ + pool->pool_start_addr = start_addr; + pool->page_metadata = start_page; + pool->pool_mem_size = page_num * BUDDY_PAGE_SIZE; + /* This field is for unit test only. */ + pool->pool_phys_page_num = page_num; - /* Init the free lists */ - for (order = 0; order < BUDDY_MAX_ORDER; ++order) { - pool->free_lists[order].nr_free = 0; - init_list_head(&(pool->free_lists[order].free_list)); - } + /* Init the free lists */ + for (order = 0; order < BUDDY_MAX_ORDER; ++order) { + pool->free_lists[order].nr_free = 0; + init_list_head(&(pool->free_lists[order].free_list)); + } - /* Clear the page_metadata area. */ - memset((char *)start_page, 0, page_num * sizeof(struct page)); + /* Clear the page_metadata area. */ + memset((char *) start_page, 0, page_num * sizeof(struct page)); - /* Init the page_metadata area. */ - for (page_idx = 0; page_idx < page_num; ++page_idx) { - page = start_page + page_idx; - page->allocated = 1; - page->order = 0; - } + /* Init the page_metadata area. */ + for (page_idx = 0; page_idx < page_num; ++page_idx) { + page = start_page + page_idx; + page->allocated = 1; + page->order = 0; + } - /* Put each physical memory page into the free lists. */ - for (page_idx = 0; page_idx < page_num; ++page_idx) { - page = start_page + page_idx; - buddy_free_pages(pool, page); - } + /* Put each physical memory page into the free lists. */ + for (page_idx = 0; page_idx < page_num; ++page_idx) { + page = start_page + page_idx; + buddy_free_pages(pool, page); + } } static struct page *get_buddy_chunk(struct phys_mem_pool *pool, - struct page *chunk) -{ - u64 chunk_addr; - u64 buddy_chunk_addr; - int order; + struct page *chunk) { + u64 chunk_addr; + u64 buddy_chunk_addr; + int order; - /* Get the address of the chunk. */ - chunk_addr = (u64) page_to_virt(pool, chunk); - order = chunk->order; - /* - * Calculate the address of the buddy chunk according to the address - * relationship between buddies. - */ + /* Get the address of the chunk. */ + chunk_addr = (u64) page_to_virt(pool, chunk); + order = chunk->order; + /* + * Calculate the address of the buddy chunk according to the address + * relationship between buddies. + */ #define BUDDY_PAGE_SIZE_ORDER (12) - buddy_chunk_addr = chunk_addr ^ - (1UL << (order + BUDDY_PAGE_SIZE_ORDER)); + buddy_chunk_addr = chunk_addr ^ + (1UL << (order + BUDDY_PAGE_SIZE_ORDER)); - /* Check whether the buddy_chunk_addr belongs to pool. */ - if ((buddy_chunk_addr < pool->pool_start_addr) || - (buddy_chunk_addr >= (pool->pool_start_addr + - pool->pool_mem_size))) { - return NULL; - } + /* Check whether the buddy_chunk_addr belongs to pool. */ + if ((buddy_chunk_addr < pool->pool_start_addr) || + (buddy_chunk_addr >= (pool->pool_start_addr + + pool->pool_mem_size))) { + return NULL; + } - return virt_to_page(pool, (void *)buddy_chunk_addr); + return virt_to_page(pool, (void *) buddy_chunk_addr); } /* @@ -81,104 +79,97 @@ static struct page *get_buddy_chunk(struct phys_mem_pool *pool, * pool @ physical memory structure reserved in the kernel * order @ order for origin page block * page @ splitted page - * + * * Hints: don't forget to substract the free page number for the corresponding free_list. * you can invoke split_page recursively until the given page can not be splitted into two * smaller sub-pages. */ static struct page *split_page(struct phys_mem_pool *pool, u64 order, - struct page *page) -{ - // - struct page *split_page = NULL; - return split_page; - // + struct page *page) { + // + struct page *split_page = NULL; + return split_page; + // } /* * buddy_get_pages: get free page from buddy system. * pool @ physical memory structure reserved in the kernel * order @ get the (1< - struct page *page = NULL; +struct page *buddy_get_pages(struct phys_mem_pool *pool, u64 order) { + // + struct page *page = NULL; - return page; - // + return page; + // } /* * merge_page: merge the given page with the buddy page * pool @ physical memory structure reserved in the kernel * page @ merged page (attempted) - * + * * Hints: you can invoke the merge_page recursively until * there is not corresponding buddy page. get_buddy_chunk * is helpful in this function. */ -static struct page *merge_page(struct phys_mem_pool *pool, struct page *page) -{ - // +static struct page *merge_page(struct phys_mem_pool *pool, struct page *page) { + // - struct page *merge_page = NULL; - return merge_page; - // + struct page *merge_page = NULL; + return merge_page; + // } /* * buddy_free_pages: give back the pages to buddy system * pool @ physical memory structure reserved in the kernel * page @ free page structure - * + * * Hints: you can invoke merge_page. */ -void buddy_free_pages(struct phys_mem_pool *pool, struct page *page) -{ - // +void buddy_free_pages(struct phys_mem_pool *pool, struct page *page) { + // - // + // } -void *page_to_virt(struct phys_mem_pool *pool, struct page *page) -{ - u64 addr; +void *page_to_virt(struct phys_mem_pool *pool, struct page *page) { + u64 addr; - /* page_idx * BUDDY_PAGE_SIZE + start_addr */ - addr = (page - pool->page_metadata) * BUDDY_PAGE_SIZE + - pool->pool_start_addr; - return (void *)addr; + /* page_idx * BUDDY_PAGE_SIZE + start_addr */ + addr = (page - pool->page_metadata) * BUDDY_PAGE_SIZE + + pool->pool_start_addr; + return (void *) addr; } -struct page *virt_to_page(struct phys_mem_pool *pool, void *addr) -{ - struct page *page; +struct page *virt_to_page(struct phys_mem_pool *pool, void *addr) { + struct page *page; - page = pool->page_metadata + - (((u64) addr - pool->pool_start_addr) / BUDDY_PAGE_SIZE); - return page; + page = pool->page_metadata + + (((u64) addr - pool->pool_start_addr) / BUDDY_PAGE_SIZE); + return page; } -u64 get_free_mem_size_from_buddy(struct phys_mem_pool * pool) -{ - int order; - struct free_list *list; - u64 current_order_size; - u64 total_size = 0; +u64 get_free_mem_size_from_buddy(struct phys_mem_pool *pool) { + int order; + struct free_list *list; + u64 current_order_size; + u64 total_size = 0; - for (order = 0; order < BUDDY_MAX_ORDER; order++) { - /* 2^order * 4K */ - current_order_size = BUDDY_PAGE_SIZE * (1 << order); - list = pool->free_lists + order; - total_size += list->nr_free * current_order_size; + for (order = 0; order < BUDDY_MAX_ORDER; order++) { + /* 2^order * 4K */ + current_order_size = BUDDY_PAGE_SIZE * (1 << order); + list = pool->free_lists + order; + total_size += list->nr_free * current_order_size; - /* debug : print info about current order */ - kdebug("buddy memory chunk order: %d, size: 0x%lx, num: %d\n", - order, current_order_size, list->nr_free); - } - return total_size; + /* debug : print info about current order */ + kdebug("buddy memory chunk order: %d, size: 0x%lx, num: %d\n", + order, current_order_size, list->nr_free); + } + return total_size; }