hugetlb: add support for 1GB huge page allocation at runtime
Subsystems (3)
RFC PATCH 1/1 hugetlb: add support for 1GB huge page allocation at runtime
Currently, 1GB huge page allocation is only possible at boottime, by means of the hugepages= command-line option. This has a number of drawbacks, the most important of them being:
1. On a NUMA machine, the kernel will evenly distribute page allocation among nodes. For example, if you have a NUMA machine with 4 nodes and want to allocate four 1GB huge pages, the kernel will try to allocate one page per node.
On the other hand, we have users who want to be able to specify from which node an allocation should be made. For example, they want to be able to allocate two 1GB huge pages from node 1 only. Supporting this use-case is the main motivation for this feature.
2. Once allocated, boottime huge pages can't be freed
This commit solves both issues by adding support for allocating 1GB huge pages during runtime, just like 2MB huge pages, which supports NUMA and has a standard use interface in sysfs.
For example, to allocate two 1GB huge pages from node 1, one can do:
# echo 2 > \ /sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages
(You need hugeTLB properly configured to have that sysfs entry)
The one problem with 1GB huge page runtime allocation is that such gigantic allocation can't be serviced by the buddy allocator, which is limited to allocating 2048 pages on most archs. To overcome that problem, we scan all zones from a node looking for a 1GB contiguous region. When one is found, it's allocated by using CMA, that is, we call alloc_contig_range().
One expected issue with 1GB huge page support is that free 1GB contiguous regions tend to vanish as time goes by. The best way to avoid this for now is to make 1GB huge pages allocations very early during boot, say from a init script. Other possible optimization include using compaction, which is already supported by CMA but is not explicitly used by this commit.
This patch is quite complete and works, I'm labelling it RFC because of the following:
1. I haven't tested surplus pages, cgroup support, allocating through hugetlbfs and a few other things
2. I haven't looked at adding 1GB huge page support to alloc_huge_page_node(), which seems to allocate huge pages on demand. Do we need this for the first merge?
3. Should 1GB huge page allocation code update HTLB_BUDDY_PGALLOC and HTLB_BUDDY_PGALLOC_FAIL? I think it shouldn't, as we don't allocate from the buddy
---
This patch is a follow up for this series:
http://marc.info/?l=linux-mm&m=139234006724423&w=2
That series introduced a command-line option to allow the user to specify from which NUMA node a 1GB hugepage allocation should be made. In that discussion is was suggested that having support for runtime allocation was a better solution.
arch/x86/include/asm/hugetlb.h | 10 +++ include/linux/hugetlb.h | 5 ++ mm/hugetlb.c | 176 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 181 insertions(+), 10 deletions(-)
arch/x86/include/asm/hugetlb.h +10 -0
@@ -91,6 +91,16 @@ static inline void arch_release_hugepage(struct page *page) { } +static inline int arch_prepare_gigantic_page (struct page *page) +{ +return 0 ; +} + +static inline void arch_release_gigantic_page (struct page *page) +{ +} + +static inline void arch_clear_hugepage_flags (struct page *page) { }
include/linux/hugetlb.h +5 -0
@@ -333,6 +333,11 @@ static inline unsigned huge_page_shift(struct hstate *h)return h->order +PAGE_SHIFT ; } +static inline bool hstate_is_gigantic (struct hstate *h) +{ +return huge_page_order (h) >=MAX_ORDER ; +} +static inline unsigned int pages_per_huge_page (struct hstate *h) {return 1 << h->order;
mm/hugetlb.c +166 -10
228 lines not on this page · raw message
Signature · 7 lines
1.8.1.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>