From: acevest Date: Tue, 2 Nov 2021 06:16:40 +0000 (+0800) Subject: 加快一点bootmem分配 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=291c1981f2a5d57deb9434f5c4f8066ef8f13920;p=kernel.git 加快一点bootmem分配 --- diff --git a/include/boot/boot.h b/include/boot/boot.h index 840cf18..ee2a068 100644 --- a/include/boot/boot.h +++ b/include/boot/boot.h @@ -49,8 +49,8 @@ typedef struct bootmem_data { unsigned long min_pfn; unsigned long max_pfn; - unsigned long last_offset; // offset to pfn2pa(this->min_pfn); - unsigned long last_hit_pfn; // last hit index in bitmap + // 准备分配的超始pfn + unsigned long prepare_alloc_pfn; void *bitmap; unsigned long mapsize; diff --git a/mm/bootmem.c b/mm/bootmem.c index d491194..12d3570 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -92,7 +92,7 @@ void e820_init_bootmem_data() { printk("pfn_min: %d pfn_max: %d\n", bootmem_data.min_pfn, bootmem_data.max_pfn); - bootmem_data.last_hit_pfn = bootmem_data.min_pfn; + bootmem_data.prepare_alloc_pfn = bootmem_data.min_pfn; } void register_bootmem_pages() { @@ -179,7 +179,7 @@ void *alloc_from_bootmem(unsigned long size, char *title) { bootmem_data_t *pbd = &bootmem_data; // 从该处开始查找空闲区间 - unsigned long search_bgn_pfn = pbd->min_pfn; + unsigned long search_bgn_pfn = pbd->prepare_alloc_pfn; find_next_block: // 先找到第一个空闲的pfn @@ -214,80 +214,7 @@ find_next_block: reserve_bootmem(bgn_pfn, end_pfn); region = pfn2va(bgn_pfn); - return region; -} - -void *alloc_bootmem(unsigned long size, unsigned long align) { - bootmem_data_t *pbd = &bootmem_data; - - assert(size != 0); - assert((align & (align - 1)) == 0); // must be power of 2 - - unsigned long fallback = 0; - unsigned long bgn_pfn, end_pfn, step; - - step = align >> PAGE_SHIFT; - step = step > 0 ? step : 1; - - bgn_pfn = ALIGN(pbd->min_pfn, step); - end_pfn = pbd->max_pfn; - - // start from last position - if (pbd->last_hit_pfn > bgn_pfn) { - fallback = bgn_pfn + 1; - bgn_pfn = ALIGN(pbd->last_hit_pfn, step); - } - - while (1) { - int merge; - void *region; - unsigned long i, search_end_pfn; - unsigned long start_off, end_off; - - find_block: - - bgn_pfn = find_next_zero_bit(pbd->bitmap, end_pfn, bgn_pfn); - bgn_pfn = ALIGN(bgn_pfn, step); - - search_end_pfn = bgn_pfn + PFN_UP(size); - - if (bgn_pfn >= end_pfn || search_end_pfn > end_pfn) break; + pbd->prepare_alloc_pfn = end_pfn; - for (i = bgn_pfn; i < search_end_pfn; ++i) { - if (bootmem_page_state(i) != BOOTMEM_PAGE_FREE) { // space not enough - bgn_pfn = ALIGN(i, step); - if (bgn_pfn == i) bgn_pfn += step; - - goto find_block; - } - } - - // try to use the unused part of last page - if (pbd->last_offset & (PAGE_SIZE - 1) && PFN_DW(pbd->last_offset) + 1 == bgn_pfn) - start_off = ALIGN(pbd->last_offset, align); - else - start_off = pfn2pa(bgn_pfn); - - merge = PFN_DW(start_off) < bgn_pfn; - end_off = start_off + size; - - pbd->last_offset = end_off; - pbd->last_hit_pfn = PFN_UP(end_off); - - reserve_bootmem(PFN_DW(start_off) + merge, PFN_UP(end_off)); - - region = pa2va(start_off); - - memset(region, 0, size); - - return region; - } - - if (fallback) { - bgn_pfn = ALIGN(fallback - 1, step); - fallback = 0; - goto find_block; - } - - return 0; + return region; } \ No newline at end of file