+
+#define GFP_ZONE_TABLE ( \
+ (ZONE_NORMAL << 0 * ZONES_SHIFT) \
+ | (OPT_ZONE_DMA << __GFP_DMA * ZONES_SHIFT) \
+ | (OPT_ZONE_HIGHMEM << __GFP_HIGHMEM * ZONES_SHIFT) \
+ | (OPT_ZONE_DMA32 << __GFP_DMA32 * ZONES_SHIFT) \
+ | (ZONE_NORMAL << __GFP_MOVABLE * ZONES_SHIFT) \
+ | (OPT_ZONE_DMA << (__GFP_MOVABLE | __GFP_DMA) * ZONES_SHIFT) \
+ | (ZONE_MOVABLE << (__GFP_MOVABLE | __GFP_HIGHMEM) * ZONES_SHIFT)\
+ | (OPT_ZONE_DMA32 << (__GFP_MOVABLE | __GFP_DMA32) * ZONES_SHIFT)\
+)
+
+/*
+ * GFP_ZONE_BAD is a bitmap for all combinations of __GFP_DMA, __GFP_DMA32
+ * __GFP_HIGHMEM and __GFP_MOVABLE that are not permitted. One flag per
+ * entry starting with bit 0. Bit is set if the combination is not
+ * allowed.
+ */
+#define GFP_ZONE_BAD ( \
+ 1 << (__GFP_DMA | __GFP_HIGHMEM) \
+ | 1 << (__GFP_DMA | __GFP_DMA32) \
+ | 1 << (__GFP_DMA32 | __GFP_HIGHMEM) \
+ | 1 << (__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM) \
+ | 1 << (__GFP_MOVABLE | __GFP_HIGHMEM | __GFP_DMA) \
+ | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_DMA) \
+ | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_HIGHMEM) \
+ | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_DMA | __GFP_HIGHMEM)\
+)
+
+static inline enum zone_type gfp_zone(gfp_t flags)
+{
+ enum zone_type z;
+ int bit = flags & GFP_ZONEMASK;
+
+ z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) &
+ ((1 << ZONES_SHIFT) - 1);
+
+ if (__builtin_constant_p(bit))
+ MAYBE_BUILD_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
+ else {
+#ifdef CONFIG_DEBUG_VM
+ BUG_ON((GFP_ZONE_BAD >> bit) & 1);
+#endif
+ }
+ return z;