Re: Regression after commit 19809c2da28a ("mm, vmalloc: use __GFP_HIGHMEM implicitly")

From: Matthew Wilcox
Date: Thu Feb 08 2018 - 18:20:13 EST


On Thu, Feb 08, 2018 at 05:06:49AM -0800, Matthew Wilcox wrote:
> On Thu, Feb 08, 2018 at 02:29:57PM +0800, Kai Heng Feng wrote:
> > A user with i386 instead of AMD64 machine reports [1] that commit 19809c2da28a ("mm, vmalloc: use __GFP_HIGHMEM implicitlyâ) causes a regression.
> > BUG_ON(PageHighMem(pg)) in drivers/media/common/saa7146/saa7146_core.c always gets triggered after that commit.
>
> Well, the BUG_ON is wrong. You can absolutely have pages which are both
> HighMem and under the 4GB boundary. Only the first 896MB (iirc) are LowMem,
> and the next 3GB of pages are available to vmalloc_32().

... nevertheless, 19809c2da28a does in fact break vmalloc_32 on 32-bit. Look:

#if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL
#elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA)
#define GFP_VMALLOC32 GFP_DMA | GFP_KERNEL
#else
#define GFP_VMALLOC32 GFP_KERNEL
#endif

So we pass in GFP_KERNEL to __vmalloc_node, which calls __vmalloc_node_range
which calls __vmalloc_area_node, which ORs in __GFP_HIGHMEM.

So ... we could enable ZONE_DMA32 on 32-bit architectures. I don't know
what side-effects that might have; it's clearly only been tested on 64-bit
architectures so far.

It might be best to just revert 19809c2da28a and the follow-on 704b862f9efd.