hugetlb_vmemmap.h 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * HugeTLB Vmemmap Optimization (HVO)
  4. *
  5. * Copyright (c) 2020, ByteDance. All rights reserved.
  6. *
  7. * Author: Muchun Song <songmuchun@bytedance.com>
  8. */
  9. #ifndef _LINUX_HUGETLB_VMEMMAP_H
  10. #define _LINUX_HUGETLB_VMEMMAP_H
  11. #include <linux/hugetlb.h>
  12. #include <linux/io.h>
  13. #include <linux/memblock.h>
  14. /*
  15. * Reserve one vmemmap page, all vmemmap addresses are mapped to it. See
  16. * Documentation/mm/vmemmap_dedup.rst.
  17. */
  18. #define HUGETLB_VMEMMAP_RESERVE_SIZE PAGE_SIZE
  19. #define HUGETLB_VMEMMAP_RESERVE_PAGES (HUGETLB_VMEMMAP_RESERVE_SIZE / sizeof(struct page))
  20. #ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
  21. int hugetlb_vmemmap_restore_folio(const struct hstate *h, struct folio *folio);
  22. long hugetlb_vmemmap_restore_folios(const struct hstate *h,
  23. struct list_head *folio_list,
  24. struct list_head *non_hvo_folios);
  25. void hugetlb_vmemmap_optimize_folio(const struct hstate *h, struct folio *folio);
  26. void hugetlb_vmemmap_optimize_folios(struct hstate *h, struct list_head *folio_list);
  27. void hugetlb_vmemmap_optimize_bootmem_folios(struct hstate *h, struct list_head *folio_list);
  28. #ifdef CONFIG_SPARSEMEM_VMEMMAP_PREINIT
  29. void hugetlb_vmemmap_init_early(int nid);
  30. void hugetlb_vmemmap_init_late(int nid);
  31. #endif
  32. static inline unsigned int hugetlb_vmemmap_size(const struct hstate *h)
  33. {
  34. return pages_per_huge_page(h) * sizeof(struct page);
  35. }
  36. /*
  37. * Return how many vmemmap size associated with a HugeTLB page that can be
  38. * optimized and can be freed to the buddy allocator.
  39. */
  40. static inline unsigned int hugetlb_vmemmap_optimizable_size(const struct hstate *h)
  41. {
  42. int size = hugetlb_vmemmap_size(h) - HUGETLB_VMEMMAP_RESERVE_SIZE;
  43. if (!is_power_of_2(sizeof(struct page)))
  44. return 0;
  45. return size > 0 ? size : 0;
  46. }
  47. #else
  48. static inline int hugetlb_vmemmap_restore_folio(const struct hstate *h, struct folio *folio)
  49. {
  50. return 0;
  51. }
  52. static inline long hugetlb_vmemmap_restore_folios(const struct hstate *h,
  53. struct list_head *folio_list,
  54. struct list_head *non_hvo_folios)
  55. {
  56. list_splice_init(folio_list, non_hvo_folios);
  57. return 0;
  58. }
  59. static inline void hugetlb_vmemmap_optimize_folio(const struct hstate *h, struct folio *folio)
  60. {
  61. }
  62. static inline void hugetlb_vmemmap_optimize_folios(struct hstate *h, struct list_head *folio_list)
  63. {
  64. }
  65. static inline void hugetlb_vmemmap_optimize_bootmem_folios(struct hstate *h,
  66. struct list_head *folio_list)
  67. {
  68. }
  69. static inline void hugetlb_vmemmap_init_early(int nid)
  70. {
  71. }
  72. static inline void hugetlb_vmemmap_init_late(int nid)
  73. {
  74. }
  75. static inline unsigned int hugetlb_vmemmap_optimizable_size(const struct hstate *h)
  76. {
  77. return 0;
  78. }
  79. #endif /* CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP */
  80. static inline bool hugetlb_vmemmap_optimizable(const struct hstate *h)
  81. {
  82. return hugetlb_vmemmap_optimizable_size(h) != 0;
  83. }
  84. #endif /* _LINUX_HUGETLB_VMEMMAP_H */