aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/gfp.h111
1 files changed, 96 insertions, 15 deletions
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 06b7e8cc80ac..412178afd423 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -21,7 +21,8 @@ struct vm_area_struct;
21#define __GFP_DMA ((__force gfp_t)0x01u) 21#define __GFP_DMA ((__force gfp_t)0x01u)
22#define __GFP_HIGHMEM ((__force gfp_t)0x02u) 22#define __GFP_HIGHMEM ((__force gfp_t)0x02u)
23#define __GFP_DMA32 ((__force gfp_t)0x04u) 23#define __GFP_DMA32 ((__force gfp_t)0x04u)
24 24#define __GFP_MOVABLE ((__force gfp_t)0x08u) /* Page is movable */
25#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
25/* 26/*
26 * Action modifiers - doesn't change the zoning 27 * Action modifiers - doesn't change the zoning
27 * 28 *
@@ -51,7 +52,6 @@ struct vm_area_struct;
51#define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */ 52#define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */
52#define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */ 53#define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */
53#define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) /* Page is reclaimable */ 54#define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) /* Page is reclaimable */
54#define __GFP_MOVABLE ((__force gfp_t)0x100000u) /* Page is movable */
55 55
56#define __GFP_BITS_SHIFT 21 /* Room for 21 __GFP_FOO bits */ 56#define __GFP_BITS_SHIFT 21 /* Room for 21 __GFP_FOO bits */
57#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) 57#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
@@ -116,24 +116,105 @@ static inline int allocflags_to_migratetype(gfp_t gfp_flags)
116 ((gfp_flags & __GFP_RECLAIMABLE) != 0); 116 ((gfp_flags & __GFP_RECLAIMABLE) != 0);
117} 117}
118 118
119static inline enum zone_type gfp_zone(gfp_t flags) 119#ifdef CONFIG_HIGHMEM
120{ 120#define OPT_ZONE_HIGHMEM ZONE_HIGHMEM
121#else
122#define OPT_ZONE_HIGHMEM ZONE_NORMAL
123#endif
124
121#ifdef CONFIG_ZONE_DMA 125#ifdef CONFIG_ZONE_DMA
122 if (flags & __GFP_DMA) 126#define OPT_ZONE_DMA ZONE_DMA
123 return ZONE_DMA; 127#else
128#define OPT_ZONE_DMA ZONE_NORMAL
124#endif 129#endif
130
125#ifdef CONFIG_ZONE_DMA32 131#ifdef CONFIG_ZONE_DMA32
126 if (flags & __GFP_DMA32) 132#define OPT_ZONE_DMA32 ZONE_DMA32
127 return ZONE_DMA32; 133#else
134#define OPT_ZONE_DMA32 ZONE_NORMAL
128#endif 135#endif
129 if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) == 136
130 (__GFP_HIGHMEM | __GFP_MOVABLE)) 137/*
131 return ZONE_MOVABLE; 138 * GFP_ZONE_TABLE is a word size bitstring that is used for looking up the
132#ifdef CONFIG_HIGHMEM 139 * zone to use given the lowest 4 bits of gfp_t. Entries are ZONE_SHIFT long
133 if (flags & __GFP_HIGHMEM) 140 * and there are 16 of them to cover all possible combinations of
134 return ZONE_HIGHMEM; 141 * __GFP_DMA, __GFP_DMA32, __GFP_MOVABLE and __GFP_HIGHMEM
142 *
143 * The zone fallback order is MOVABLE=>HIGHMEM=>NORMAL=>DMA32=>DMA.
144 * But GFP_MOVABLE is not only a zone specifier but also an allocation
145 * policy. Therefore __GFP_MOVABLE plus another zone selector is valid.
146 * Only 1bit of the lowest 3 bit (DMA,DMA32,HIGHMEM) can be set to "1".
147 *
148 * bit result
149 * =================
150 * 0x0 => NORMAL
151 * 0x1 => DMA or NORMAL
152 * 0x2 => HIGHMEM or NORMAL
153 * 0x3 => BAD (DMA+HIGHMEM)
154 * 0x4 => DMA32 or DMA or NORMAL
155 * 0x5 => BAD (DMA+DMA32)
156 * 0x6 => BAD (HIGHMEM+DMA32)
157 * 0x7 => BAD (HIGHMEM+DMA32+DMA)
158 * 0x8 => NORMAL (MOVABLE+0)
159 * 0x9 => DMA or NORMAL (MOVABLE+DMA)
160 * 0xa => MOVABLE (Movable is valid only if HIGHMEM is set too)
161 * 0xb => BAD (MOVABLE+HIGHMEM+DMA)
162 * 0xc => DMA32 (MOVABLE+HIGHMEM+DMA32)
163 * 0xd => BAD (MOVABLE+DMA32+DMA)
164 * 0xe => BAD (MOVABLE+DMA32+HIGHMEM)
165 * 0xf => BAD (MOVABLE+DMA32+HIGHMEM+DMA)
166 *
167 * ZONES_SHIFT must be <= 2 on 32 bit platforms.
168 */
169
170#if 16 * ZONES_SHIFT > BITS_PER_LONG
171#error ZONES_SHIFT too large to create GFP_ZONE_TABLE integer
172#endif
173
174#define GFP_ZONE_TABLE ( \
175 (ZONE_NORMAL << 0 * ZONES_SHIFT) \
176 | (OPT_ZONE_DMA << __GFP_DMA * ZONES_SHIFT) \
177 | (OPT_ZONE_HIGHMEM << __GFP_HIGHMEM * ZONES_SHIFT) \
178 | (OPT_ZONE_DMA32 << __GFP_DMA32 * ZONES_SHIFT) \
179 | (ZONE_NORMAL << __GFP_MOVABLE * ZONES_SHIFT) \
180 | (OPT_ZONE_DMA << (__GFP_MOVABLE | __GFP_DMA) * ZONES_SHIFT) \
181 | (ZONE_MOVABLE << (__GFP_MOVABLE | __GFP_HIGHMEM) * ZONES_SHIFT)\
182 | (OPT_ZONE_DMA32 << (__GFP_MOVABLE | __GFP_DMA32) * ZONES_SHIFT)\
183)
184
185/*
186 * GFP_ZONE_BAD is a bitmap for all combination of __GFP_DMA, __GFP_DMA32
187 * __GFP_HIGHMEM and __GFP_MOVABLE that are not permitted. One flag per
188 * entry starting with bit 0. Bit is set if the combination is not
189 * allowed.
190 */
191#define GFP_ZONE_BAD ( \
192 1 << (__GFP_DMA | __GFP_HIGHMEM) \
193 | 1 << (__GFP_DMA | __GFP_DMA32) \
194 | 1 << (__GFP_DMA32 | __GFP_HIGHMEM) \
195 | 1 << (__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM) \
196 | 1 << (__GFP_MOVABLE | __GFP_HIGHMEM | __GFP_DMA) \
197 | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_DMA) \
198 | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_HIGHMEM) \
199 | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_DMA | __GFP_HIGHMEM)\
200)
201
202static inline enum zone_type gfp_zone(gfp_t flags)
203{
204 enum zone_type z;
205 int bit = flags & GFP_ZONEMASK;
206
207 z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) &
208 ((1 << ZONES_SHIFT) - 1);
209
210 if (__builtin_constant_p(bit))
211 BUILD_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
212 else {
213#ifdef CONFIG_DEBUG_VM
214 BUG_ON((GFP_ZONE_BAD >> bit) & 1);
135#endif 215#endif
136 return ZONE_NORMAL; 216 }
217 return z;
137} 218}
138 219
139/* 220/*