mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
hugetlbfs: handle pages higher order than MAX_ORDER
When working with hugepages, hugetlbfs assumes that those hugepages are smaller than MAX_ORDER. Specifically it assumes that the mem_map is contigious and uses that to optimise access to the elements of the mem_map that represent the hugepage. Gigantic pages (such as 16GB pages on powerpc) by definition are of greater order than MAX_ORDER (larger than MAX_ORDER_NR_PAGES in size). This means that we can no longer make use of the buddy alloctor guarentees for the contiguity of the mem_map, which ensures that the mem_map is at least contigious for maximmally aligned areas of MAX_ORDER_NR_PAGES pages. This patch adds new mem_map accessors and iterator helpers which handle any discontiguity at MAX_ORDER_NR_PAGES boundaries. It then uses these to implement gigantic page versions of copy_huge_page and clear_huge_page, and to allow follow_hugetlb_page handle gigantic pages. Signed-off-by: Andy Whitcroft <[email protected]> Cc: Jon Tollefson <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Nick Piggin <[email protected]> Cc: Christoph Lameter <[email protected]> Cc: <[email protected]> [2.6.27.x] Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
22bece00dc
commit
69d177c2fc
2 changed files with 64 additions and 1 deletions
|
|
@ -175,6 +175,34 @@ static inline void free_page_mlock(struct page *page) { }
|
|||
|
||||
#endif /* CONFIG_UNEVICTABLE_LRU */
|
||||
|
||||
/*
|
||||
* Return the mem_map entry representing the 'offset' subpage within
|
||||
* the maximally aligned gigantic page 'base'. Handle any discontiguity
|
||||
* in the mem_map at MAX_ORDER_NR_PAGES boundaries.
|
||||
*/
|
||||
static inline struct page *mem_map_offset(struct page *base, int offset)
|
||||
{
|
||||
if (unlikely(offset >= MAX_ORDER_NR_PAGES))
|
||||
return pfn_to_page(page_to_pfn(base) + offset);
|
||||
return base + offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterator over all subpages withing the maximally aligned gigantic
|
||||
* page 'base'. Handle any discontiguity in the mem_map.
|
||||
*/
|
||||
static inline struct page *mem_map_next(struct page *iter,
|
||||
struct page *base, int offset)
|
||||
{
|
||||
if (unlikely((offset & (MAX_ORDER_NR_PAGES - 1)) == 0)) {
|
||||
unsigned long pfn = page_to_pfn(base) + offset;
|
||||
if (!pfn_valid(pfn))
|
||||
return NULL;
|
||||
return pfn_to_page(pfn);
|
||||
}
|
||||
return iter + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* FLATMEM and DISCONTIGMEM configurations use alloc_bootmem_node,
|
||||
* so all functions starting at paging_init should be marked __init
|
||||
|
|
|
|||
Loading…
Reference in a new issue