Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: hugetlb: gather discrete indexes of tail page

For HugeTLB page, there are more metadata to save in the struct page. But
the head struct page cannot meet our needs, so we have to abuse other tail
struct page to store the metadata. In order to avoid conflicts caused by
subsequent use of more tail struct pages, we can gather these discrete
indexes of tail struct page. In this case, it will be easier to add a new
tail page index later.

Link: https://lkml.kernel.org/r/20210510030027.56044-4-songmuchun@bytedance.com
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Reviewed-by: Oscar Salvador <osalvador@suse.de>
Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
Tested-by: Chen Huang <chenhuang5@huawei.com>
Tested-by: Bodeddula Balasubramaniam <bodeddub@amazon.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: Barry Song <song.bao.hua@hisilicon.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Cc: HORIGUCHI NAOYA <naoya.horiguchi@nec.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Joao Martins <joao.m.martins@oracle.com>
Cc: Joerg Roedel <jroedel@suse.de>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Mina Almasry <almasrymina@google.com>
Cc: Oliver Neukum <oneukum@suse.com>
Cc: Paul E. McKenney <paulmck@kernel.org>
Cc: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Xiongchun Duan <duanxiongchun@bytedance.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Muchun Song and committed by
Linus Torvalds
cd39d4e9 6be24bed

+30 -10
+19 -2
include/linux/hugetlb.h
··· 29 29 #include <linux/shm.h> 30 30 #include <asm/tlbflush.h> 31 31 32 + /* 33 + * For HugeTLB page, there are more metadata to save in the struct page. But 34 + * the head struct page cannot meet our needs, so we have to abuse other tail 35 + * struct page to store the metadata. In order to avoid conflicts caused by 36 + * subsequent use of more tail struct pages, we gather these discrete indexes 37 + * of tail struct page here. 38 + */ 39 + enum { 40 + SUBPAGE_INDEX_SUBPOOL = 1, /* reuse page->private */ 41 + #ifdef CONFIG_CGROUP_HUGETLB 42 + SUBPAGE_INDEX_CGROUP, /* reuse page->private */ 43 + SUBPAGE_INDEX_CGROUP_RSVD, /* reuse page->private */ 44 + __MAX_CGROUP_SUBPAGE_INDEX = SUBPAGE_INDEX_CGROUP_RSVD, 45 + #endif 46 + __NR_USED_SUBPAGE, 47 + }; 48 + 32 49 struct hugepage_subpool { 33 50 spinlock_t lock; 34 51 long count; ··· 652 635 */ 653 636 static inline struct hugepage_subpool *hugetlb_page_subpool(struct page *hpage) 654 637 { 655 - return (struct hugepage_subpool *)(hpage+1)->private; 638 + return (void *)page_private(hpage + SUBPAGE_INDEX_SUBPOOL); 656 639 } 657 640 658 641 static inline void hugetlb_set_page_subpool(struct page *hpage, 659 642 struct hugepage_subpool *subpool) 660 643 { 661 - set_page_private(hpage+1, (unsigned long)subpool); 644 + set_page_private(hpage + SUBPAGE_INDEX_SUBPOOL, (unsigned long)subpool); 662 645 } 663 646 664 647 static inline struct hstate *hstate_file(struct file *f)
+11 -8
include/linux/hugetlb_cgroup.h
··· 21 21 struct resv_map; 22 22 struct file_region; 23 23 24 + #ifdef CONFIG_CGROUP_HUGETLB 24 25 /* 25 26 * Minimum page order trackable by hugetlb cgroup. 26 27 * At least 4 pages are necessary for all the tracking information. 27 - * The second tail page (hpage[2]) is the fault usage cgroup. 28 - * The third tail page (hpage[3]) is the reservation usage cgroup. 28 + * The second tail page (hpage[SUBPAGE_INDEX_CGROUP]) is the fault 29 + * usage cgroup. The third tail page (hpage[SUBPAGE_INDEX_CGROUP_RSVD]) 30 + * is the reservation usage cgroup. 29 31 */ 30 - #define HUGETLB_CGROUP_MIN_ORDER 2 32 + #define HUGETLB_CGROUP_MIN_ORDER order_base_2(__MAX_CGROUP_SUBPAGE_INDEX + 1) 31 33 32 - #ifdef CONFIG_CGROUP_HUGETLB 33 34 enum hugetlb_memory_event { 34 35 HUGETLB_MAX, 35 36 HUGETLB_NR_MEMORY_EVENTS, ··· 67 66 if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER) 68 67 return NULL; 69 68 if (rsvd) 70 - return (struct hugetlb_cgroup *)page[3].private; 69 + return (void *)page_private(page + SUBPAGE_INDEX_CGROUP_RSVD); 71 70 else 72 - return (struct hugetlb_cgroup *)page[2].private; 71 + return (void *)page_private(page + SUBPAGE_INDEX_CGROUP); 73 72 } 74 73 75 74 static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page) ··· 91 90 if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER) 92 91 return -1; 93 92 if (rsvd) 94 - page[3].private = (unsigned long)h_cg; 93 + set_page_private(page + SUBPAGE_INDEX_CGROUP_RSVD, 94 + (unsigned long)h_cg); 95 95 else 96 - page[2].private = (unsigned long)h_cg; 96 + set_page_private(page + SUBPAGE_INDEX_CGROUP, 97 + (unsigned long)h_cg); 97 98 return 0; 98 99 } 99 100