| From: Sidhartha Kumar <sidhartha.kumar@oracle.com> |
| Subject: mm/hugetlb: add folio support to hugetlb specific flag macros |
| Date: Thu, 22 Sep 2022 10:42:03 -0500 |
| |
| Patch series "begin converting hugetlb code to folios", v4. |
| |
| This patch series starts the conversion of the hugetlb code to operate on |
| struct folios rather than struct pages. This removes the ambiguitiy of |
| whether functions are operating on head pages, tail pages of compound |
| pages, or base pages. |
| |
| This series passes the linux test project hugetlb test cases. |
| |
| Patch 1 adds hugeltb specific page macros that can operate on folios. |
| |
| Patch 2 adds the private field of the first tail page to struct page. For |
| 32-bit, _private_1 alinging with page[1].private was confirmed by using |
| pahole. |
| |
| Patch 3 introduces hugetlb subpool helper functions which operate on |
| struct folios. These patches were tested using the hugepage-mmap.c |
| selftest along with the migratepages command. |
| |
| Patch 4 converts hugetlb_delete_from_page_cache() to use folios. |
| |
| Patch 5 adds a folio_hstate() function to get hstate information from a |
| folio and adds a user of folio_hstate(). |
| |
| Bpftrace was used to track time spent in the free_huge_pages function |
| during the ltp test cases as it is a caller of the hugetlb subpool |
| functions. From the histogram, the performance is similar before and |
| after the patch series. |
| |
| Time spent in 'free_huge_page' |
| |
| 6.0.0-rc2.master.20220823 |
| @nsecs: |
| [256, 512) 14770 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| |@@@@@@@@@@@@@@@@@@@@@@@@@ | |
| [512, 1K) 155 | | |
| [1K, 2K) 169 | | |
| [2K, 4K) 50 | | |
| [4K, 8K) 14 | | |
| [8K, 16K) 3 | | |
| [16K, 32K) 3 | | |
| |
| |
| 6.0.0-rc2.master.20220823 + patch series |
| @nsecs: |
| [256, 512) 13678 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
| |@@@@@@@@@@@@@@@@@@@@@@@@@ | |
| [512, 1K) 142 | | |
| [1K, 2K) 199 | | |
| [2K, 4K) 44 | | |
| [4K, 8K) 13 | | |
| [8K, 16K) 4 | | |
| [16K, 32K) 1 | | |
| |
| |
| This patch (of 5): |
| |
| Allow the macros which test, set, and clear hugetlb specific page flags to |
| take a hugetlb folio as an input. The macrros are generated as |
| folio_{test, set, clear}_hugetlb_{restore_reserve, migratable, temporary, |
| freed, vmemmap_optimized, raw_hwp_unreliable}. |
| |
| Link: https://lkml.kernel.org/r/20220922154207.1575343-1-sidhartha.kumar@oracle.com |
| Link: https://lkml.kernel.org/r/20220922154207.1575343-2-sidhartha.kumar@oracle.com |
| Signed-off-by: Sidhartha Kumar <sidhartha.kumar@oracle.com> |
| Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com> |
| Reviewed-by: Muchun Song <songmuchun@bytedance.com> |
| Cc: Arnd Bergmann <arnd@arndb.de> |
| Cc: Colin Cross <ccross@google.com> |
| Cc: David Howells <dhowells@redhat.com> |
| Cc: "Eric W . Biederman" <ebiederm@xmission.com> |
| Cc: Hugh Dickins <hughd@google.com> |
| Cc: kernel test robot <lkp@intel.com> |
| Cc: Matthew Wilcox <willy@infradead.org> |
| Cc: Peter Xu <peterx@redhat.com> |
| Cc: Vlastimil Babka <vbabka@suse.cz> |
| Cc: William Kucharski <william.kucharski@oracle.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| include/linux/hugetlb.h | 24 ++++++++++++++++++++++++ |
| 1 file changed, 24 insertions(+) |
| |
| --- a/include/linux/hugetlb.h~mm-hugetlb-add-folio-support-to-hugetlb-specific-flag-macros |
| +++ a/include/linux/hugetlb.h |
| @@ -589,26 +589,50 @@ enum hugetlb_page_flags { |
| */ |
| #ifdef CONFIG_HUGETLB_PAGE |
| #define TESTHPAGEFLAG(uname, flname) \ |
| +static __always_inline \ |
| +bool folio_test_hugetlb_##flname(struct folio *folio) \ |
| + { void *private = &folio->private; \ |
| + return test_bit(HPG_##flname, private); \ |
| + } \ |
| static inline int HPage##uname(struct page *page) \ |
| { return test_bit(HPG_##flname, &(page->private)); } |
| |
| #define SETHPAGEFLAG(uname, flname) \ |
| +static __always_inline \ |
| +void folio_set_hugetlb_##flname(struct folio *folio) \ |
| + { void *private = &folio->private; \ |
| + set_bit(HPG_##flname, private); \ |
| + } \ |
| static inline void SetHPage##uname(struct page *page) \ |
| { set_bit(HPG_##flname, &(page->private)); } |
| |
| #define CLEARHPAGEFLAG(uname, flname) \ |
| +static __always_inline \ |
| +void folio_clear_hugetlb_##flname(struct folio *folio) \ |
| + { void *private = &folio->private; \ |
| + clear_bit(HPG_##flname, private); \ |
| + } \ |
| static inline void ClearHPage##uname(struct page *page) \ |
| { clear_bit(HPG_##flname, &(page->private)); } |
| #else |
| #define TESTHPAGEFLAG(uname, flname) \ |
| +static inline bool \ |
| +folio_test_hugetlb_##flname(struct folio *folio) \ |
| + { return 0; } \ |
| static inline int HPage##uname(struct page *page) \ |
| { return 0; } |
| |
| #define SETHPAGEFLAG(uname, flname) \ |
| +static inline void \ |
| +folio_set_hugetlb_##flname(struct folio *folio) \ |
| + { } \ |
| static inline void SetHPage##uname(struct page *page) \ |
| { } |
| |
| #define CLEARHPAGEFLAG(uname, flname) \ |
| +static inline void \ |
| +folio_clear_hugetlb_##flname(struct folio *folio) \ |
| + { } \ |
| static inline void ClearHPage##uname(struct page *page) \ |
| { } |
| #endif |
| _ |