Commit 9f993ac3f708b661207ed7de521f245586217a68

Authored by FUJITA Tomonori
Committed by Ingo Molnar
1 parent 9d5ce73a64

bootmem: Add free_bootmem_late()

Add a new function for freeing bootmem after the bootmem
allocator has been released and the unreserved pages given to
the page allocator.

This allows us to reserve bootmem and then release it if we
later discover it was not needed.

( This new API will be used by the swiotlb code to recover
  a significant amount of RAM (64MB). )

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: chrisw@sous-sol.org
Cc: dwmw2@infradead.org
Cc: joerg.roedel@amd.com
Cc: muli@il.ibm.com
Cc: hannes@cmpxchg.org
Cc: tj@kernel.org
Cc: akpm@linux-foundation.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
LKML-Reference: <1257849980-22640-7-git-send-email-fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 2 changed files with 25 additions and 0 deletions Side-by-side Diff

include/linux/bootmem.h
... ... @@ -53,6 +53,7 @@
53 53 unsigned long addr,
54 54 unsigned long size);
55 55 extern void free_bootmem(unsigned long addr, unsigned long size);
  56 +extern void free_bootmem_late(unsigned long addr, unsigned long size);
56 57  
57 58 /*
58 59 * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE,
... ... @@ -143,6 +143,30 @@
143 143 return init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages);
144 144 }
145 145  
  146 +/*
  147 + * free_bootmem_late - free bootmem pages directly to page allocator
  148 + * @addr: starting address of the range
  149 + * @size: size of the range in bytes
  150 + *
  151 + * This is only useful when the bootmem allocator has already been torn
  152 + * down, but we are still initializing the system. Pages are given directly
  153 + * to the page allocator, no bootmem metadata is updated because it is gone.
  154 + */
  155 +void __init free_bootmem_late(unsigned long addr, unsigned long size)
  156 +{
  157 + unsigned long cursor, end;
  158 +
  159 + kmemleak_free_part(__va(addr), size);
  160 +
  161 + cursor = PFN_UP(addr);
  162 + end = PFN_DOWN(addr + size);
  163 +
  164 + for (; cursor < end; cursor++) {
  165 + __free_pages_bootmem(pfn_to_page(cursor), 0);
  166 + totalram_pages++;
  167 + }
  168 +}
  169 +
146 170 static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
147 171 {
148 172 int aligned;