page_ext.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __LINUX_PAGE_EXT_H
  3. #define __LINUX_PAGE_EXT_H
  4. #include <linux/types.h>
  5. #include <linux/stacktrace.h>
  6. #include <linux/stackdepot.h>
  7. struct pglist_data;
  8. struct page_ext_operations {
  9. size_t offset;
  10. size_t size;
  11. bool (*need)(void);
  12. void (*init)(void);
  13. };
  14. #ifdef CONFIG_PAGE_EXTENSION
  15. enum page_ext_flags {
  16. PAGE_EXT_OWNER,
  17. PAGE_EXT_OWNER_ALLOCATED,
  18. #if defined(CONFIG_PAGE_PINNER)
  19. /* page refcount was increased by GUP or follow_page(FOLL_GET) */
  20. PAGE_EXT_GET,
  21. /* page migration failed */
  22. PAGE_EXT_PINNER_MIGRATION_FAILED,
  23. #endif
  24. #if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT)
  25. PAGE_EXT_YOUNG,
  26. PAGE_EXT_IDLE,
  27. #endif
  28. };
  29. /*
  30. * Page Extension can be considered as an extended mem_map.
  31. * A page_ext page is associated with every page descriptor. The
  32. * page_ext helps us add more information about the page.
  33. * All page_ext are allocated at boot or memory hotplug event,
  34. * then the page_ext for pfn always exists.
  35. */
  36. struct page_ext {
  37. unsigned long flags;
  38. };
  39. extern unsigned long page_ext_size;
  40. extern void pgdat_page_ext_init(struct pglist_data *pgdat);
  41. #ifdef CONFIG_SPARSEMEM
  42. static inline void page_ext_init_flatmem(void)
  43. {
  44. }
  45. extern void page_ext_init(void);
  46. #else
  47. extern void page_ext_init_flatmem(void);
  48. static inline void page_ext_init(void)
  49. {
  50. }
  51. #endif
  52. struct page_ext *lookup_page_ext(const struct page *page);
  53. extern struct page_ext *page_ext_get(struct page *page);
  54. extern void page_ext_put(struct page_ext *page_ext);
  55. static inline struct page_ext *page_ext_next(struct page_ext *curr)
  56. {
  57. void *next = curr;
  58. next += page_ext_size;
  59. return next;
  60. }
  61. #else /* !CONFIG_PAGE_EXTENSION */
  62. struct page_ext;
  63. static inline void pgdat_page_ext_init(struct pglist_data *pgdat)
  64. {
  65. }
  66. static inline void page_ext_init(void)
  67. {
  68. }
  69. static inline void page_ext_init_flatmem(void)
  70. {
  71. }
  72. static inline struct page_ext *page_ext_get(struct page *page)
  73. {
  74. return NULL;
  75. }
  76. static inline void page_ext_put(struct page_ext *page_ext)
  77. {
  78. }
  79. #endif /* CONFIG_PAGE_EXTENSION */
  80. #endif /* __LINUX_PAGE_EXT_H */