diff options
-rw-r--r-- | include/linux/hugetlb.h | 16 | ||||
-rw-r--r-- | kernel/futex.c | 3 | ||||
-rw-r--r-- | mm/hugetlb.c | 17 |
3 files changed, 35 insertions, 1 deletions
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 6b4890fa57e7..feaf0c7fb7d8 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h | |||
@@ -358,6 +358,17 @@ static inline int hstate_index(struct hstate *h) | |||
358 | return h - hstates; | 358 | return h - hstates; |
359 | } | 359 | } |
360 | 360 | ||
361 | pgoff_t __basepage_index(struct page *page); | ||
362 | |||
363 | /* Return page->index in PAGE_SIZE units */ | ||
364 | static inline pgoff_t basepage_index(struct page *page) | ||
365 | { | ||
366 | if (!PageCompound(page)) | ||
367 | return page->index; | ||
368 | |||
369 | return __basepage_index(page); | ||
370 | } | ||
371 | |||
361 | #else /* CONFIG_HUGETLB_PAGE */ | 372 | #else /* CONFIG_HUGETLB_PAGE */ |
362 | struct hstate {}; | 373 | struct hstate {}; |
363 | #define alloc_huge_page_node(h, nid) NULL | 374 | #define alloc_huge_page_node(h, nid) NULL |
@@ -378,6 +389,11 @@ static inline unsigned int pages_per_huge_page(struct hstate *h) | |||
378 | } | 389 | } |
379 | #define hstate_index_to_shift(index) 0 | 390 | #define hstate_index_to_shift(index) 0 |
380 | #define hstate_index(h) 0 | 391 | #define hstate_index(h) 0 |
392 | |||
393 | static inline pgoff_t basepage_index(struct page *page) | ||
394 | { | ||
395 | return page->index; | ||
396 | } | ||
381 | #endif /* CONFIG_HUGETLB_PAGE */ | 397 | #endif /* CONFIG_HUGETLB_PAGE */ |
382 | 398 | ||
383 | #endif /* _LINUX_HUGETLB_H */ | 399 | #endif /* _LINUX_HUGETLB_H */ |
diff --git a/kernel/futex.c b/kernel/futex.c index b26dcfc02c94..49dacfb45745 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <linux/nsproxy.h> | 61 | #include <linux/nsproxy.h> |
62 | #include <linux/ptrace.h> | 62 | #include <linux/ptrace.h> |
63 | #include <linux/sched/rt.h> | 63 | #include <linux/sched/rt.h> |
64 | #include <linux/hugetlb.h> | ||
64 | 65 | ||
65 | #include <asm/futex.h> | 66 | #include <asm/futex.h> |
66 | 67 | ||
@@ -365,7 +366,7 @@ again: | |||
365 | } else { | 366 | } else { |
366 | key->both.offset |= FUT_OFF_INODE; /* inode-based key */ | 367 | key->both.offset |= FUT_OFF_INODE; /* inode-based key */ |
367 | key->shared.inode = page_head->mapping->host; | 368 | key->shared.inode = page_head->mapping->host; |
368 | key->shared.pgoff = page_head->index; | 369 | key->shared.pgoff = basepage_index(page); |
369 | } | 370 | } |
370 | 371 | ||
371 | get_futex_key_refs(key); | 372 | get_futex_key_refs(key); |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index e2bfbf73a551..5cf99bf8cce2 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -690,6 +690,23 @@ int PageHuge(struct page *page) | |||
690 | } | 690 | } |
691 | EXPORT_SYMBOL_GPL(PageHuge); | 691 | EXPORT_SYMBOL_GPL(PageHuge); |
692 | 692 | ||
693 | pgoff_t __basepage_index(struct page *page) | ||
694 | { | ||
695 | struct page *page_head = compound_head(page); | ||
696 | pgoff_t index = page_index(page_head); | ||
697 | unsigned long compound_idx; | ||
698 | |||
699 | if (!PageHuge(page_head)) | ||
700 | return page_index(page); | ||
701 | |||
702 | if (compound_order(page_head) >= MAX_ORDER) | ||
703 | compound_idx = page_to_pfn(page) - page_to_pfn(page_head); | ||
704 | else | ||
705 | compound_idx = page - page_head; | ||
706 | |||
707 | return (index << compound_order(page_head)) + compound_idx; | ||
708 | } | ||
709 | |||
693 | static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) | 710 | static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) |
694 | { | 711 | { |
695 | struct page *page; | 712 | struct page *page; |