diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2005-08-11 02:55:21 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-08-28 20:53:38 -0400 |
commit | c594adad5653491813959277fb87a2fef54c4e05 (patch) | |
tree | baefdce10a0b490017b0a5acbe9dbeb8cb14c003 /include | |
parent | 9a5573e378c5c8976c6000a7643b52e2a0481688 (diff) |
[PATCH] Dynamic hugepage addresses for ppc64
Paulus, I think this is now a reasonable candidate for the post-2.6.13
queue.
Relax address restrictions for hugepages on ppc64
Presently, 64-bit applications on ppc64 may only use hugepages in the
address region from 1-1.5T. Furthermore, if hugepages are enabled in
the kernel config, they may only use hugepages and never normal pages
in this area. This patch relaxes this restriction, allowing any
address to be used with hugepages, but with a 1TB granularity. That
is if you map a hugepage anywhere in the region 1TB-2TB, that entire
area will be reserved exclusively for hugepages for the remainder of
the process's lifetime. This works analagously to hugepages in 32-bit
applications, where hugepages can be mapped anywhere, but with 256MB
(mmu segment) granularity.
This patch applies on top of the four level pagetable patch
(http://patchwork.ozlabs.org/linuxppc64/patch?id=1936).
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-ppc64/mmu.h | 2 | ||||
-rw-r--r-- | include/asm-ppc64/page.h | 29 |
2 files changed, 18 insertions, 13 deletions
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h index 789c2693483c..ad36bb28de29 100644 --- a/include/asm-ppc64/mmu.h +++ b/include/asm-ppc64/mmu.h | |||
@@ -307,7 +307,7 @@ typedef unsigned long mm_context_id_t; | |||
307 | typedef struct { | 307 | typedef struct { |
308 | mm_context_id_t id; | 308 | mm_context_id_t id; |
309 | #ifdef CONFIG_HUGETLB_PAGE | 309 | #ifdef CONFIG_HUGETLB_PAGE |
310 | u16 htlb_segs; /* bitmask */ | 310 | u16 low_htlb_areas, high_htlb_areas; |
311 | #endif | 311 | #endif |
312 | } mm_context_t; | 312 | } mm_context_t; |
313 | 313 | ||
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h index 7e7b18ea986e..a79a08df62bd 100644 --- a/include/asm-ppc64/page.h +++ b/include/asm-ppc64/page.h | |||
@@ -37,40 +37,45 @@ | |||
37 | 37 | ||
38 | #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) | 38 | #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) |
39 | 39 | ||
40 | /* For 64-bit processes the hugepage range is 1T-1.5T */ | 40 | #define HTLB_AREA_SHIFT 40 |
41 | #define TASK_HPAGE_BASE ASM_CONST(0x0000010000000000) | 41 | #define HTLB_AREA_SIZE (1UL << HTLB_AREA_SHIFT) |
42 | #define TASK_HPAGE_END ASM_CONST(0x0000018000000000) | 42 | #define GET_HTLB_AREA(x) ((x) >> HTLB_AREA_SHIFT) |
43 | 43 | ||
44 | #define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \ | 44 | #define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \ |
45 | - (1U << GET_ESID(addr))) & 0xffff) | 45 | - (1U << GET_ESID(addr))) & 0xffff) |
46 | #define HTLB_AREA_MASK(addr, len) (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \ | ||
47 | - (1U << GET_HTLB_AREA(addr))) & 0xffff) | ||
46 | 48 | ||
47 | #define ARCH_HAS_HUGEPAGE_ONLY_RANGE | 49 | #define ARCH_HAS_HUGEPAGE_ONLY_RANGE |
48 | #define ARCH_HAS_PREPARE_HUGEPAGE_RANGE | 50 | #define ARCH_HAS_PREPARE_HUGEPAGE_RANGE |
49 | #define ARCH_HAS_SETCLEAR_HUGE_PTE | 51 | #define ARCH_HAS_SETCLEAR_HUGE_PTE |
50 | 52 | ||
51 | #define touches_hugepage_low_range(mm, addr, len) \ | 53 | #define touches_hugepage_low_range(mm, addr, len) \ |
52 | (LOW_ESID_MASK((addr), (len)) & mm->context.htlb_segs) | 54 | (LOW_ESID_MASK((addr), (len)) & (mm)->context.low_htlb_areas) |
53 | #define touches_hugepage_high_range(addr, len) \ | 55 | #define touches_hugepage_high_range(mm, addr, len) \ |
54 | (((addr) > (TASK_HPAGE_BASE-(len))) && ((addr) < TASK_HPAGE_END)) | 56 | (HTLB_AREA_MASK((addr), (len)) & (mm)->context.high_htlb_areas) |
55 | 57 | ||
56 | #define __within_hugepage_low_range(addr, len, segmask) \ | 58 | #define __within_hugepage_low_range(addr, len, segmask) \ |
57 | ((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask)) | 59 | ((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask)) |
58 | #define within_hugepage_low_range(addr, len) \ | 60 | #define within_hugepage_low_range(addr, len) \ |
59 | __within_hugepage_low_range((addr), (len), \ | 61 | __within_hugepage_low_range((addr), (len), \ |
60 | current->mm->context.htlb_segs) | 62 | current->mm->context.low_htlb_areas) |
61 | #define within_hugepage_high_range(addr, len) (((addr) >= TASK_HPAGE_BASE) \ | 63 | #define __within_hugepage_high_range(addr, len, zonemask) \ |
62 | && ((addr)+(len) <= TASK_HPAGE_END) && ((addr)+(len) >= (addr))) | 64 | ((HTLB_AREA_MASK((addr), (len)) | (zonemask)) == (zonemask)) |
65 | #define within_hugepage_high_range(addr, len) \ | ||
66 | __within_hugepage_high_range((addr), (len), \ | ||
67 | current->mm->context.high_htlb_areas) | ||
63 | 68 | ||
64 | #define is_hugepage_only_range(mm, addr, len) \ | 69 | #define is_hugepage_only_range(mm, addr, len) \ |
65 | (touches_hugepage_high_range((addr), (len)) || \ | 70 | (touches_hugepage_high_range((mm), (addr), (len)) || \ |
66 | touches_hugepage_low_range((mm), (addr), (len))) | 71 | touches_hugepage_low_range((mm), (addr), (len))) |
67 | #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA | 72 | #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA |
68 | 73 | ||
69 | #define in_hugepage_area(context, addr) \ | 74 | #define in_hugepage_area(context, addr) \ |
70 | (cpu_has_feature(CPU_FTR_16M_PAGE) && \ | 75 | (cpu_has_feature(CPU_FTR_16M_PAGE) && \ |
71 | ( (((addr) >= TASK_HPAGE_BASE) && ((addr) < TASK_HPAGE_END)) || \ | 76 | ( ((1 << GET_HTLB_AREA(addr)) & (context).high_htlb_areas) || \ |
72 | ( ((addr) < 0x100000000L) && \ | 77 | ( ((addr) < 0x100000000L) && \ |
73 | ((1 << GET_ESID(addr)) & (context).htlb_segs) ) ) ) | 78 | ((1 << GET_ESID(addr)) & (context).low_htlb_areas) ) ) ) |
74 | 79 | ||
75 | #else /* !CONFIG_HUGETLB_PAGE */ | 80 | #else /* !CONFIG_HUGETLB_PAGE */ |
76 | 81 | ||