page-flags-layout.h 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #ifndef PAGE_FLAGS_LAYOUT_H
  2. #define PAGE_FLAGS_LAYOUT_H
  3. #include <linux/numa.h>
  4. #include <generated/bounds.h>
  5. /*
  6. * When a memory allocation must conform to specific limitations (such
  7. * as being suitable for DMA) the caller will pass in hints to the
  8. * allocator in the gfp_mask, in the zone modifier bits. These bits
  9. * are used to select a priority ordered list of memory zones which
  10. * match the requested limits. See gfp_zone() in include/linux/gfp.h
  11. */
  12. #if MAX_NR_ZONES < 2
  13. #define ZONES_SHIFT 0
  14. #elif MAX_NR_ZONES <= 2
  15. #define ZONES_SHIFT 1
  16. #elif MAX_NR_ZONES <= 4
  17. #define ZONES_SHIFT 2
  18. #elif MAX_NR_ZONES <= 8
  19. #define ZONES_SHIFT 3
  20. #else
  21. #error ZONES_SHIFT -- too many zones configured adjust calculation
  22. #endif
  23. #ifdef CONFIG_SPARSEMEM
  24. #include <asm/sparsemem.h>
  25. /* SECTION_SHIFT #bits space required to store a section # */
  26. #define SECTIONS_SHIFT (MAX_PHYSMEM_BITS - SECTION_SIZE_BITS)
  27. #endif /* CONFIG_SPARSEMEM */
  28. /*
  29. * page->flags layout:
  30. *
  31. * There are five possibilities for how page->flags get laid out. The first
  32. * pair is for the normal case without sparsemem. The second pair is for
  33. * sparsemem when there is plenty of space for node and section information.
  34. * The last is when there is insufficient space in page->flags and a separate
  35. * lookup is necessary.
  36. *
  37. * No sparsemem or sparsemem vmemmap: | NODE | ZONE | ... | FLAGS |
  38. * " plus space for last_cpupid: | NODE | ZONE | LAST_CPUPID ... | FLAGS |
  39. * classic sparse with space for node:| SECTION | NODE | ZONE | ... | FLAGS |
  40. * " plus space for last_cpupid: | SECTION | NODE | ZONE | LAST_CPUPID ... | FLAGS |
  41. * classic sparse no space for node: | SECTION | ZONE | ... | FLAGS |
  42. */
  43. #if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP)
  44. #define SECTIONS_WIDTH SECTIONS_SHIFT
  45. #else
  46. #define SECTIONS_WIDTH 0
  47. #endif
  48. #define ZONES_WIDTH ZONES_SHIFT
  49. #if SECTIONS_WIDTH+ZONES_WIDTH+NODES_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS
  50. #define NODES_WIDTH NODES_SHIFT
  51. #else
  52. #ifdef CONFIG_SPARSEMEM_VMEMMAP
  53. #error "Vmemmap: No space for nodes field in page flags"
  54. #endif
  55. #define NODES_WIDTH 0
  56. #endif
  57. #ifdef CONFIG_NUMA_BALANCING
  58. #define LAST__PID_SHIFT 8
  59. #define LAST__PID_MASK ((1 << LAST__PID_SHIFT)-1)
  60. #define LAST__CPU_SHIFT NR_CPUS_BITS
  61. #define LAST__CPU_MASK ((1 << LAST__CPU_SHIFT)-1)
  62. #define LAST_CPUPID_SHIFT (LAST__PID_SHIFT+LAST__CPU_SHIFT)
  63. #else
  64. #define LAST_CPUPID_SHIFT 0
  65. #endif
  66. #if SECTIONS_WIDTH+ZONES_WIDTH+NODES_SHIFT+LAST_CPUPID_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS
  67. #define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT
  68. #else
  69. #define LAST_CPUPID_WIDTH 0
  70. #endif
  71. /*
  72. * We are going to use the flags for the page to node mapping if its in
  73. * there. This includes the case where there is no node, so it is implicit.
  74. */
  75. #if !(NODES_WIDTH > 0 || NODES_SHIFT == 0)
  76. #define NODE_NOT_IN_PAGE_FLAGS
  77. #endif
  78. #if defined(CONFIG_NUMA_BALANCING) && LAST_CPUPID_WIDTH == 0
  79. #define LAST_CPUPID_NOT_IN_PAGE_FLAGS
  80. #endif
  81. #endif /* _LINUX_PAGE_FLAGS_LAYOUT */