static void __init __free_pages_memory(unsigned long start, unsigned long end) { int i; unsigned long start_aligned, end_aligned; int order = ilog2(BITS_PER_LONG); start_aligned = (start + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1); end_aligned = end & ~(BITS_PER_LONG - 1); if (end_aligned <= start_aligned) { for (i = start; i < end; i++) __free_pages_bootmem(pfn_to_page(i), 0); return; } for (i = start; i < start_aligned; i++) __free_pages_bootmem(pfn_to_page(i), 0); for (i = start_aligned; i < end_aligned; i += BITS_PER_LONG) __free_pages_bootmem(pfn_to_page(i), order); for (i = end_aligned; i < end; i++) __free_pages_bootmem(pfn_to_page(i), 0); }
/* * free_bootmem_late - free bootmem pages directly to page allocator * @addr: starting address of the range * @size: size of the range in bytes * * This is only useful when the bootmem allocator has already been torn * down, but we are still initializing the system. Pages are given directly * to the page allocator, no bootmem metadata is updated because it is gone. */ void __init free_bootmem_late(unsigned long addr, unsigned long size) { unsigned long cursor, end; cursor = PFN_UP(addr); end = PFN_DOWN(addr + size); for (; cursor < end; cursor++) { __free_pages_bootmem(pfn_to_page(cursor), cursor, 0); totalram_pages++; } }
static void __init __free_pages_memory(unsigned long start, unsigned long end) { int order; while (start < end) { /* IAMROOT-12AB: * ------------- * 버디 시스템은 MAX_ORDER-1 단위의 order를 등록하지 않기 때문에 min() 함수로 * 잘라낸다. (arm32: MAX_ORDER=11, 버디시스템에 최대 4M 단위 페이지가 등록된다) * * 메모리 영역의 시작 부분 관련 * - 시작 pfn으로 order를 먼저 결정을 한다. * - 단 MAX_ORDER-1을 넘지 않도록 제한한다. */ order = min(MAX_ORDER - 1UL, __ffs(start)); /* IAMROOT-12AB: * ------------- * 메모리 영역의 끝 부분 관련 * - order를 더해 end를 초과하는 경우 order를 줄여나간다. */ while (start + (1UL << order) > end) order--; /* IAMROOT-12AB: * ------------- * 해재할 메모리를 order 단위로 버디시스템에 돌려준다(free) * * 예) start=0x12345, end=0x13456 * start order * ------- ----- * loop 01: 0x12345 0 * loop 02: 0x12346 1 * loop 03: 0x12348 3 * loop 04: 0x12350 4 * loop 05: 0x12360 5 * loop 06: 0x12380 7 * loop 07: 0x12400 10 * loop 08: 0x12800 10 * loop 09: 0x12c00 10 * loop 10: 0x13000 10 * loop 11: 0x13400 6 * loop 12: 0x13440 4 * loop 13: 0x13450 2 * loop 14: 0x13454 1 */ __free_pages_bootmem(pfn_to_page(start), order); start += (1UL << order); } }
/* * free_bootmem_late - free bootmem pages directly to page allocator * @addr: starting address of the range * @size: size of the range in bytes * * This is only useful when the bootmem allocator has already been torn * down, but we are still initializing the system. Pages are given directly * to the page allocator, no bootmem metadata is updated because it is gone. */ void free_bootmem_late(unsigned long addr, unsigned long size) { unsigned long cursor, end; kmemleak_free_part(__va(addr), size); cursor = PFN_UP(addr); end = PFN_DOWN(addr + size); for (; cursor < end; cursor++) { __free_pages_bootmem(pfn_to_page(cursor), 0); totalram_pages++; } }
static void __init __free_pages_memory(unsigned long start, unsigned long end) { int order; while (start < end) { order = min(MAX_ORDER - 1UL, __ffs(start)); while (start + (1UL << order) > end) order--; __free_pages_bootmem(pfn_to_page(start), start, order); start += (1UL << order); } }