Message ID | 20180301061340.17494-2-kai.heng.feng@canonical.com |
---|---|
State | New |
Headers | show |
Series | [SRU,Artful,1/1] vmalloc: fix __GFP_HIGHMEM usage for vmalloc_32 on 32b systems | expand |
On 2018-03-01 14:13:40 , Kai-Heng Feng wrote: > From: Michal Hocko <mhocko@suse.com> > > BugLink: https://bugs.launchpad.net/bugs/1742316 > > Kai Heng Feng has noticed that BUG_ON(PageHighMem(pg)) triggers in > drivers/media/common/saa7146/saa7146_core.c since 19809c2da28a ("mm, > vmalloc: use __GFP_HIGHMEM implicitly"). > > saa7146_vmalloc_build_pgtable uses vmalloc_32 and it is reasonable to > expect that the resulting page is not in highmem. The above commit > aimed to add __GFP_HIGHMEM only for those requests which do not specify > any zone modifier gfp flag. vmalloc_32 relies on GFP_VMALLOC32 which > should do the right thing. Except it has been missed that GFP_VMALLOC32 > is an alias for GFP_KERNEL on 32b architectures. Thanks to Matthew to > notice this. > > Fix the problem by unconditionally setting GFP_DMA32 in GFP_VMALLOC32 > for !64b arches (as a bailout). This should do the right thing and use > ZONE_NORMAL which should be always below 4G on 32b systems. > > Debugged by Matthew Wilcox. > > [akpm@linux-foundation.org: coding-style fixes] > Link: http://lkml.kernel.org/r/20180212095019.GX21609@dhcp22.suse.cz > Fixes: 19809c2da28a ("mm, vmalloc: use __GFP_HIGHMEM implicitly”) > Signed-off-by: Michal Hocko <mhocko@suse.com> > Reported-by: Kai Heng Feng <kai.heng.feng@canonical.com> > Cc: Matthew Wilcox <willy@infradead.org> > Cc: Laura Abbott <labbott@redhat.com> > Cc: <stable@vger.kernel.org> > Signed-off-by: Andrew Morton <akpm@linux-foundation.org> > Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> > (cherry picked from commit 698d0831ba87b92ae10b15e8203cfd59f5a59a35) > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> > --- > mm/vmalloc.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > index ceacc6e01904..07b4deef6faa 100644 > --- a/mm/vmalloc.c > +++ b/mm/vmalloc.c > @@ -1945,11 +1945,15 @@ void *vmalloc_exec(unsigned long size) > } > > #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32) > -#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL > +#define GFP_VMALLOC32 (GFP_DMA32 | GFP_KERNEL) > #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA) > -#define GFP_VMALLOC32 GFP_DMA | GFP_KERNEL > +#define GFP_VMALLOC32 (GFP_DMA | GFP_KERNEL) > #else > -#define GFP_VMALLOC32 GFP_KERNEL > +/* > + * 64b systems should always have either DMA or DMA32 zones. For others > + * GFP_DMA32 should do the right thing and use the normal zone. > + */ > +#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL > #endif > > /** Acked-by: Khalid Elmously <khalid.elmously@canonical.com>
On 03/01/18 07:13, Kai-Heng Feng wrote: > From: Michal Hocko <mhocko@suse.com> > > BugLink: https://bugs.launchpad.net/bugs/1742316 > > Kai Heng Feng has noticed that BUG_ON(PageHighMem(pg)) triggers in > drivers/media/common/saa7146/saa7146_core.c since 19809c2da28a ("mm, > vmalloc: use __GFP_HIGHMEM implicitly"). > > saa7146_vmalloc_build_pgtable uses vmalloc_32 and it is reasonable to > expect that the resulting page is not in highmem. The above commit > aimed to add __GFP_HIGHMEM only for those requests which do not specify > any zone modifier gfp flag. vmalloc_32 relies on GFP_VMALLOC32 which > should do the right thing. Except it has been missed that GFP_VMALLOC32 > is an alias for GFP_KERNEL on 32b architectures. Thanks to Matthew to > notice this. > > Fix the problem by unconditionally setting GFP_DMA32 in GFP_VMALLOC32 > for !64b arches (as a bailout). This should do the right thing and use > ZONE_NORMAL which should be always below 4G on 32b systems. > > Debugged by Matthew Wilcox. > > [akpm@linux-foundation.org: coding-style fixes] > Link: http://lkml.kernel.org/r/20180212095019.GX21609@dhcp22.suse.cz > Fixes: 19809c2da28a ("mm, vmalloc: use __GFP_HIGHMEM implicitly”) > Signed-off-by: Michal Hocko <mhocko@suse.com> > Reported-by: Kai Heng Feng <kai.heng.feng@canonical.com> > Cc: Matthew Wilcox <willy@infradead.org> > Cc: Laura Abbott <labbott@redhat.com> > Cc: <stable@vger.kernel.org> > Signed-off-by: Andrew Morton <akpm@linux-foundation.org> > Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> > (cherry picked from commit 698d0831ba87b92ae10b15e8203cfd59f5a59a35) > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> > --- > mm/vmalloc.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > index ceacc6e01904..07b4deef6faa 100644 > --- a/mm/vmalloc.c > +++ b/mm/vmalloc.c > @@ -1945,11 +1945,15 @@ void *vmalloc_exec(unsigned long size) > } > > #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32) > -#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL > +#define GFP_VMALLOC32 (GFP_DMA32 | GFP_KERNEL) > #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA) > -#define GFP_VMALLOC32 GFP_DMA | GFP_KERNEL > +#define GFP_VMALLOC32 (GFP_DMA | GFP_KERNEL) > #else > -#define GFP_VMALLOC32 GFP_KERNEL > +/* > + * 64b systems should always have either DMA or DMA32 zones. For others > + * GFP_DMA32 should do the right thing and use the normal zone. > + */ > +#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL > #endif > > /** > Good test results, also backported for the stable trees. Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index ceacc6e01904..07b4deef6faa 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1945,11 +1945,15 @@ void *vmalloc_exec(unsigned long size) } #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32) -#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL +#define GFP_VMALLOC32 (GFP_DMA32 | GFP_KERNEL) #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA) -#define GFP_VMALLOC32 GFP_DMA | GFP_KERNEL +#define GFP_VMALLOC32 (GFP_DMA | GFP_KERNEL) #else -#define GFP_VMALLOC32 GFP_KERNEL +/* + * 64b systems should always have either DMA or DMA32 zones. For others + * GFP_DMA32 should do the right thing and use the normal zone. + */ +#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL #endif /**