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