|
|
#define ARCH_HAS_HUGEPAGE_ONLY_RANGE | #define ARCH_HAS_HUGEPAGE_ONLY_RANGE |
#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE | #define ARCH_HAS_PREPARE_HUGEPAGE_RANGE |
| |
#define touches_hugepage_low_range(addr, len) \ |
#define touches_hugepage_low_range(mm, addr, len) \ |
(LOW_ESID_MASK((addr), (len)) & current->mm->context.htlb_segs) |
(LOW_ESID_MASK((addr), (len)) & mm->context.htlb_segs) |
#define touches_hugepage_high_range(addr, len) \ | #define touches_hugepage_high_range(addr, len) \ |
(((addr) > (TASK_HPAGE_BASE-(len))) && ((addr) < TASK_HPAGE_END)) | (((addr) > (TASK_HPAGE_BASE-(len))) && ((addr) < TASK_HPAGE_END)) |
| |
|
|
#define within_hugepage_high_range(addr, len) (((addr) >= TASK_HPAGE_BASE) \ | #define within_hugepage_high_range(addr, len) (((addr) >= TASK_HPAGE_BASE) \ |
&& ((addr)+(len) <= TASK_HPAGE_END) && ((addr)+(len) >= (addr))) | && ((addr)+(len) <= TASK_HPAGE_END) && ((addr)+(len) >= (addr))) |
| |
#define is_hugepage_only_range(addr, len) \ |
#define is_hugepage_only_range(mm, addr, len) \ |
(touches_hugepage_high_range((addr), (len)) || \ | (touches_hugepage_high_range((addr), (len)) || \ |
touches_hugepage_low_range((addr), (len))) |
touches_hugepage_low_range((mm), (addr), (len))) |
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA | #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA |
| |
#define in_hugepage_area(context, addr) \ | #define in_hugepage_area(context, addr) \ |
|
Lines 137-143
typedef union ia64_va {
|
Link Here
|
|---|
|
# define htlbpage_to_page(x) (((unsigned long) REGION_NUMBER(x) << 61) \ | # define htlbpage_to_page(x) (((unsigned long) REGION_NUMBER(x) << 61) \ |
| (REGION_OFFSET(x) >> (HPAGE_SHIFT-PAGE_SHIFT))) | | (REGION_OFFSET(x) >> (HPAGE_SHIFT-PAGE_SHIFT))) |
# define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) | # define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) |
# define is_hugepage_only_range(addr, len) \ |
# define is_hugepage_only_range(mm, addr, len) \ |
(REGION_NUMBER(addr) == REGION_HPAGE && \ | (REGION_NUMBER(addr) == REGION_HPAGE && \ |
REGION_NUMBER((addr)+(len)) == REGION_HPAGE) | REGION_NUMBER((addr)+(len)) == REGION_HPAGE) |
extern unsigned int hpage_shift; | extern unsigned int hpage_shift; |
|
Lines 36-42
extern const unsigned long hugetlb_zero,
|
Link Here
|
|---|
|
extern int sysctl_hugetlb_shm_group; | extern int sysctl_hugetlb_shm_group; |
| |
#ifndef ARCH_HAS_HUGEPAGE_ONLY_RANGE | #ifndef ARCH_HAS_HUGEPAGE_ONLY_RANGE |
#define is_hugepage_only_range(addr, len) 0 |
#define is_hugepage_only_range(mm, addr, len) 0 |
#define hugetlb_free_pgtables(tlb, prev, start, end) do { } while (0) | #define hugetlb_free_pgtables(tlb, prev, start, end) do { } while (0) |
#endif | #endif |
| |
|
Lines 71-77
static inline unsigned long hugetlb_tota
|
Link Here
|
|---|
|
#define is_aligned_hugepage_range(addr, len) 0 | #define is_aligned_hugepage_range(addr, len) 0 |
#define prepare_hugepage_range(addr, len) (-EINVAL) | #define prepare_hugepage_range(addr, len) (-EINVAL) |
#define pmd_huge(x) 0 | #define pmd_huge(x) 0 |
#define is_hugepage_only_range(addr, len) 0 |
#define is_hugepage_only_range(mm, addr, len) 0 |
#define hugetlb_free_pgtables(tlb, prev, start, end) do { } while (0) | #define hugetlb_free_pgtables(tlb, prev, start, end) do { } while (0) |
#define alloc_huge_page() ({ NULL; }) | #define alloc_huge_page() ({ NULL; }) |
#define free_huge_page(p) ({ (void)(p); BUG(); }) | #define free_huge_page(p) ({ (void)(p); BUG(); }) |
|
Lines 513-519
unsigned long arch_get_unmapped_area(str
|
Link Here
|
|---|
|
vma = find_vma(mm, addr); | vma = find_vma(mm, addr); |
if (((TASK_SIZE - len) >= addr) | if (((TASK_SIZE - len) >= addr) |
&& (!vma || (addr+len) <= vma->vm_start) | && (!vma || (addr+len) <= vma->vm_start) |
&& !is_hugepage_only_range(addr,len)) |
&& !is_hugepage_only_range(mm, addr,len)) |
return addr; | return addr; |
} | } |
start_addr = addr = mm->free_area_cache; | start_addr = addr = mm->free_area_cache; |
|
|
while (TASK_SIZE - len >= addr) { | while (TASK_SIZE - len >= addr) { |
BUG_ON(vma && (addr >= vma->vm_end)); | BUG_ON(vma && (addr >= vma->vm_end)); |
| |
if (touches_hugepage_low_range(addr, len)) { |
if (touches_hugepage_low_range(mm, addr, len)) { |
addr = ALIGN(addr+1, 1<<SID_SHIFT); | addr = ALIGN(addr+1, 1<<SID_SHIFT); |
vma = find_vma(mm, addr); | vma = find_vma(mm, addr); |
continue; | continue; |
|
Lines 584-590
arch_get_unmapped_area_topdown(struct fi
|
Link Here
|
|---|
|
vma = find_vma(mm, addr); | vma = find_vma(mm, addr); |
if (TASK_SIZE - len >= addr && | if (TASK_SIZE - len >= addr && |
(!vma || addr + len <= vma->vm_start) | (!vma || addr + len <= vma->vm_start) |
&& !is_hugepage_only_range(addr,len)) |
&& !is_hugepage_only_range(mm, addr,len)) |
return addr; | return addr; |
} | } |
| |
|
|
addr = (mm->free_area_cache - len) & PAGE_MASK; | addr = (mm->free_area_cache - len) & PAGE_MASK; |
do { | do { |
hugepage_recheck: | hugepage_recheck: |
if (touches_hugepage_low_range(addr, len)) { |
if (touches_hugepage_low_range(mm, addr, len)) { |
addr = (addr & ((~0) << SID_SHIFT)) - len; | addr = (addr & ((~0) << SID_SHIFT)) - len; |
goto hugepage_recheck; | goto hugepage_recheck; |
} else if (touches_hugepage_high_range(addr, len)) { | } else if (touches_hugepage_high_range(addr, len)) { |
|
Lines 1316-1322
get_unmapped_area(struct file *file, uns
|
Link Here
|
|---|
|
* reserved hugepage range. For some archs like IA-64, | * reserved hugepage range. For some archs like IA-64, |
* there is a separate region for hugepages. | * there is a separate region for hugepages. |
*/ | */ |
ret = is_hugepage_only_range(addr, len); |
ret = is_hugepage_only_range(current->mm, addr, len); |
} | } |
if (ret) | if (ret) |
return -EINVAL; | return -EINVAL; |
|
Lines 1687-1693
static void unmap_region(struct mm_struc
|
Link Here
|
|---|
|
unmap_vmas(&tlb, mm, vma, start, end, &nr_accounted, NULL); | unmap_vmas(&tlb, mm, vma, start, end, &nr_accounted, NULL); |
vm_unacct_memory(nr_accounted); | vm_unacct_memory(nr_accounted); |
| |
if (is_hugepage_only_range(start, end - start)) |
if (is_hugepage_only_range(mm, start, end - start)) |
hugetlb_free_pgtables(tlb, prev, start, end); | hugetlb_free_pgtables(tlb, prev, start, end); |
else | else |
free_pgtables(tlb, prev, start, end); | free_pgtables(tlb, prev, start, end); |