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