diff mbox series

[SRU,Artful,1/1] vmalloc: fix __GFP_HIGHMEM usage for vmalloc_32 on 32b systems

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

Commit Message

Kai-Heng Feng March 1, 2018, 6:13 a.m. UTC
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(-)

Comments

Khalid Elmously March 2, 2018, 12:39 a.m. UTC | #1
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>
Kleber Sacilotto de Souza March 2, 2018, 11:53 a.m. UTC | #2
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 mbox series

Patch

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
 
 /**