include/linux/gfp.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
When a new zone is added to enum zone_type in mmzone.h, the existing
GFP_ZONE_TABLE macro causes a compile-time shift overflow. This happens
because enum zone_type is of type int. The shift is logically
valid because it has been checked by 16 * GFP_ZONES_SHIFT > BITS_PER_LONG previously.
Fixed this by casting each value in GFP_ZONE_TABLE to type long.
Signed-off-by: Yankai Xu <815559068@qq.com>
---
include/linux/gfp.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index b155929af..e694f3103 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -122,14 +122,14 @@ static inline bool gfpflags_allow_spinning(const gfp_t gfp_flags)
#endif
#define GFP_ZONE_TABLE ( \
- (ZONE_NORMAL << 0 * GFP_ZONES_SHIFT) \
- | (OPT_ZONE_DMA << ___GFP_DMA * GFP_ZONES_SHIFT) \
- | (OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * GFP_ZONES_SHIFT) \
- | (OPT_ZONE_DMA32 << ___GFP_DMA32 * GFP_ZONES_SHIFT) \
- | (ZONE_NORMAL << ___GFP_MOVABLE * GFP_ZONES_SHIFT) \
- | (OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * GFP_ZONES_SHIFT) \
- | (ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * GFP_ZONES_SHIFT)\
- | (OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * GFP_ZONES_SHIFT)\
+ ((long)ZONE_NORMAL << 0 * GFP_ZONES_SHIFT) \
+ | ((long)OPT_ZONE_DMA << ___GFP_DMA * GFP_ZONES_SHIFT) \
+ | ((long)OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * GFP_ZONES_SHIFT) \
+ | ((long)OPT_ZONE_DMA32 << ___GFP_DMA32 * GFP_ZONES_SHIFT) \
+ | ((long)ZONE_NORMAL << ___GFP_MOVABLE * GFP_ZONES_SHIFT) \
+ | ((long)OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * GFP_ZONES_SHIFT) \
+ | ((long)ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * GFP_ZONES_SHIFT)\
+ | ((long)OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * GFP_ZONES_SHIFT)\
)
/*
--
2.43.0
On Thu, 11 Dec 2025 18:24:05 +0800 Yankai Xu <815559068@qq.com> wrote: > > When a new zone is added to enum zone_type in mmzone.h, the existing > GFP_ZONE_TABLE macro causes a compile-time shift overflow. Thanks. Please quote the compiler warning messages and describe how to reproduce this. Please include this info in the patch changelog and maintain it. > This happens > because enum zone_type is of type int. The shift is logically > valid because it has been checked by 16 * GFP_ZONES_SHIFT > BITS_PER_LONG previously. > > Fixed this by casting each value in GFP_ZONE_TABLE to type long. > > ... > > #define GFP_ZONE_TABLE ( \ > - (ZONE_NORMAL << 0 * GFP_ZONES_SHIFT) \ > + ((long)ZONE_NORMAL << 0 * GFP_ZONES_SHIFT) \ It would be nice to find something nicer than this. Perhaps a type of something was poorly chosen.
Hi Andrew, Thanks for the review. > Please quote the compiler warning messages and describe how to > reproduce this. Please include this info in the patch changelog and > maintain it. I have included them in patch v2. Here's the LKML link for reference: https://lore.kernel.org/lkml/tencent_DAB2E2BC61A449B6AC4FA9798C4D75BED705@qq.com/T/#/u > > #define GFP_ZONE_TABLE ( \ > > - (ZONE_NORMAL << 0 * GFP_ZONES_SHIFT) \ > > + ((long)ZONE_NORMAL << 0 * GFP_ZONES_SHIFT) \ > > It would be nice to find something nicer than this. Perhaps a type of > something was poorly chosen. ZONE_NORMAL, ZONE_DMA32, etc. are enum values, which has an underlying type of int. Changing either the underlying type or the enum type itself is not feasible. Moreover, the shift overflow only occurs inside GFP_ZONE_TABLE, modifying other code might be unnecessary. Adding explicit casts seems to be the most straightforward solution here. Thanks, Yankai
© 2016 - 2026 Red Hat, Inc.