page-flags-layout.h 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. #else
  19. #error ZONES_SHIFT -- too many zones configured adjust calculation
  20. #endif
  21. #ifdef CONFIG_SPARSEMEM
  22. #include <asm/sparsemem.h>
  23. /* SECTION_SHIFT #bits space required to store a section # */
  24. #define SECTIONS_SHIFT (MAX_PHYSMEM_BITS - SECTION_SIZE_BITS)
  25. #endif /* CONFIG_SPARSEMEM */
  26. /*
  27. * page->flags layout:
  28. *
  29. * There are five possibilities for how page->flags get laid out. The first
  30. * pair is for the normal case without sparsemem. The second pair is for
  31. * sparsemem when there is plenty of space for node and section information.
  32. * The last is when there is insufficient space in page->flags and a separate
  33. * lookup is necessary.
  34. *
  35. * No sparsemem or sparsemem vmemmap: | NODE | ZONE | ... | FLAGS |
  36. * " plus space for last_cpupid: | NODE | ZONE | LAST_CPUPID ... | FLAGS |
  37. * classic sparse with space for node:| SECTION | NODE | ZONE | ... | FLAGS |
  38. * " plus space for last_cpupid: | SECTION | NODE | ZONE | LAST_CPUPID ... | FLAGS |
  39. * classic sparse no space for node: | SECTION | ZONE | ... | FLAGS |
  40. */
  41. #if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP)
  42. #define SECTIONS_WIDTH SECTIONS_SHIFT
  43. #else
  44. #define SECTIONS_WIDTH 0
  45. #endif
  46. #define ZONES_WIDTH ZONES_SHIFT
  47. #if SECTIONS_WIDTH+ZONES_WIDTH+NODES_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS
  48. #define NODES_WIDTH NODES_SHIFT
  49. #else
  50. #ifdef CONFIG_SPARSEMEM_VMEMMAP
  51. #error "Vmemmap: No space for nodes field in page flags"
  52. #endif
  53. #define NODES_WIDTH 0
  54. #endif
  55. #ifdef CONFIG_NUMA_BALANCING
  56. #define LAST__PID_SHIFT 8
  57. #define LAST__PID_MASK ((1 << LAST__PID_SHIFT)-1)
  58. #define LAST__CPU_SHIFT NR_CPUS_BITS
  59. #define LAST__CPU_MASK ((1 << LAST__CPU_SHIFT)-1)
  60. #define LAST_CPUPID_SHIFT (LAST__PID_SHIFT+LAST__CPU_SHIFT)
  61. #else
  62. #define LAST_CPUPID_SHIFT 0
  63. #endif
  64. #if SECTIONS_WIDTH+ZONES_WIDTH+NODES_SHIFT+LAST_CPUPID_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS
  65. #define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT
  66. #else
  67. #define LAST_CPUPID_WIDTH 0
  68. #endif
  69. /*
  70. * We are going to use the flags for the page to node mapping if its in
  71. * there. This includes the case where there is no node, so it is implicit.
  72. */
  73. #if !(NODES_WIDTH > 0 || NODES_SHIFT == 0)
  74. #define NODE_NOT_IN_PAGE_FLAGS
  75. #endif
  76. #if defined(CONFIG_NUMA_BALANCING) && LAST_CPUPID_WIDTH == 0
  77. #define LAST_CPUPID_NOT_IN_PAGE_FLAGS
  78. #endif
  79. #endif /* _LINUX_PAGE_FLAGS_LAYOUT */