* [RFC 1/3] mm/page_alloc: Fix pageblock_order when HUGETLB_PAGE_ORDER >= MAX_ORDER
2021-02-04 7:01 [RFC 0/3] mm/page_alloc: Fix pageblock_order with HUGETLB_PAGE_SIZE_VARIABLE Anshuman Khandual
@ 2021-02-04 7:01 ` Anshuman Khandual
2021-02-04 7:01 ` [RFC 2/3] arm64/hugetlb: Enable HUGETLB_PAGE_SIZE_VARIABLE Anshuman Khandual
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Anshuman Khandual @ 2021-02-04 7:01 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, akpm
Cc: Anshuman Khandual, Will Deacon, Robin Murphy, Marek Szyprowski,
Christoph Hellwig, iommu, linux-kernel
With HUGETLB_PAGE_SIZE_VARIABLE enabled, pageblock_order cannot be assigned
as HUGETLB_PAGE_ORDER when it is greater than or equal to MAX_ORDER during
set_pageblock_order(). Otherwise the following warning is triggered during
boot as detected on an arm64 platform.
WARNING: CPU: 5 PID: 124 at mm/vmstat.c:1080 __fragmentation_index+0xa4/0xc0
Modules linked in:
CPU: 5 PID: 124 Comm: kswapd0 Not tainted 5.11.0-rc6-00004-ga0ea7d62002 #159
Hardware name: linux,dummy-virt (DT)
[ 8.810673] pstate: 20400005 (nzCv daif +PAN -UAO -TCO BTYPE=--)
[ 8.811732] pc : __fragmentation_index+0xa4/0xc0
[ 8.812555] lr : fragmentation_index+0xf8/0x138
[ 8.813360] sp : ffff0000864079b0
[ 8.813958] x29: ffff0000864079b0 x28: 0000000000000372
[ 8.814901] x27: 0000000000007682 x26: ffff8000135b3948
[ 8.815847] x25: 1fffe00010c80f48 x24: 0000000000000000
[ 8.816805] x23: 0000000000000000 x22: 000000000000000d
[ 8.817764] x21: 0000000000000030 x20: ffff0005ffcb4d58
[ 8.818712] x19: 000000000000000b x18: 0000000000000000
[ 8.819656] x17: 0000000000000000 x16: 0000000000000000
[ 8.820613] x15: 0000000000000000 x14: ffff8000114c6258
[ 8.821560] x13: ffff6000bff969ba x12: 1fffe000bff969b9
[ 8.822514] x11: 1fffe000bff969b9 x10: ffff6000bff969b9
[ 8.823461] x9 : dfff800000000000 x8 : ffff0005ffcb4dcf
[ 8.824415] x7 : 0000000000000001 x6 : 0000000041b58ab3
[ 8.825359] x5 : ffff600010c80f48 x4 : dfff800000000000
[ 8.826313] x3 : ffff8000102be670 x2 : 0000000000000007
[ 8.827259] x1 : ffff000086407a60 x0 : 000000000000000d
[ 8.828218] Call trace:
[ 8.828667] __fragmentation_index+0xa4/0xc0
[ 8.829436] fragmentation_index+0xf8/0x138
[ 8.830194] compaction_suitable+0x98/0xb8
[ 8.830934] wakeup_kcompactd+0xdc/0x128
[ 8.831640] balance_pgdat+0x71c/0x7a0
[ 8.832327] kswapd+0x31c/0x520
[ 8.832902] kthread+0x224/0x230
[ 8.833491] ret_from_fork+0x10/0x30
[ 8.834150] ---[ end trace 472836f79c15516b ]---
The above warning happens because pageblock_order exceeds MAX_ORDER, caused
by large HUGETLB_PAGE_ORDER on certain platforms like arm64. Lets prevent
the scenario by first checking HUGETLB_PAGE_ORDER against MAX_ORDER, before
its assignment as pageblock_order.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
mm/page_alloc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 519a60d5b6f7..36473f2fa683 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6798,7 +6798,7 @@ void __init set_pageblock_order(void)
if (pageblock_order)
return;
- if (HPAGE_SHIFT > PAGE_SHIFT)
+ if ((HPAGE_SHIFT > PAGE_SHIFT) && (HUGETLB_PAGE_ORDER < MAX_ORDER))
order = HUGETLB_PAGE_ORDER;
else
order = MAX_ORDER - 1;
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 2/3] arm64/hugetlb: Enable HUGETLB_PAGE_SIZE_VARIABLE
2021-02-04 7:01 [RFC 0/3] mm/page_alloc: Fix pageblock_order with HUGETLB_PAGE_SIZE_VARIABLE Anshuman Khandual
2021-02-04 7:01 ` [RFC 1/3] mm/page_alloc: Fix pageblock_order when HUGETLB_PAGE_ORDER >= MAX_ORDER Anshuman Khandual
@ 2021-02-04 7:01 ` Anshuman Khandual
2021-02-05 8:20 ` David Hildenbrand
2021-02-04 7:01 ` [RFC 3/3] dma-contiguous: Type cast MAX_ORDER as unsigned int Anshuman Khandual
2021-02-08 4:40 ` [RFC 0/3] mm/page_alloc: Fix pageblock_order with HUGETLB_PAGE_SIZE_VARIABLE Anshuman Khandual
3 siblings, 1 reply; 7+ messages in thread
From: Anshuman Khandual @ 2021-02-04 7:01 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, akpm
Cc: Anshuman Khandual, Will Deacon, Robin Murphy, Marek Szyprowski,
Christoph Hellwig, iommu, linux-kernel
MAX_ORDER which invariably depends on FORCE_MAX_ZONEORDER can be a variable
for a given page size, depending on whether TRANSPARENT_HUGEPAGE is enabled
or not. In certain page size and THP combinations HUGETLB_PAGE_ORDER can be
greater than MAX_ORDER, making it unusable as pageblock_order.
This enables HUGETLB_PAGE_SIZE_VARIABLE making pageblock_order a variable
rather than the compile time constant HUGETLB_PAGE_ORDER which could break
MAX_ORDER rule for certain configurations.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/arm64/Kconfig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 175914f2f340..c4acf8230f20 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1918,6 +1918,10 @@ config ARCH_ENABLE_THP_MIGRATION
def_bool y
depends on TRANSPARENT_HUGEPAGE
+config HUGETLB_PAGE_SIZE_VARIABLE
+ def_bool y
+ depends on HUGETLB_PAGE
+
menu "Power management options"
source "kernel/power/Kconfig"
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RFC 2/3] arm64/hugetlb: Enable HUGETLB_PAGE_SIZE_VARIABLE
2021-02-04 7:01 ` [RFC 2/3] arm64/hugetlb: Enable HUGETLB_PAGE_SIZE_VARIABLE Anshuman Khandual
@ 2021-02-05 8:20 ` David Hildenbrand
2021-02-05 8:30 ` Anshuman Khandual
0 siblings, 1 reply; 7+ messages in thread
From: David Hildenbrand @ 2021-02-05 8:20 UTC (permalink / raw)
To: Anshuman Khandual, linux-mm, linux-arm-kernel, catalin.marinas, akpm
Cc: Will Deacon, Robin Murphy, Marek Szyprowski, Christoph Hellwig,
iommu, linux-kernel
On 04.02.21 08:01, Anshuman Khandual wrote:
> MAX_ORDER which invariably depends on FORCE_MAX_ZONEORDER can be a variable
> for a given page size, depending on whether TRANSPARENT_HUGEPAGE is enabled
> or not. In certain page size and THP combinations HUGETLB_PAGE_ORDER can be
> greater than MAX_ORDER, making it unusable as pageblock_order.
Just so I understand correctly, this does not imply that we have THP
that exceed the pageblock size / MAX_ORDER size, correct?
>
> This enables HUGETLB_PAGE_SIZE_VARIABLE making pageblock_order a variable
> rather than the compile time constant HUGETLB_PAGE_ORDER which could break
> MAX_ORDER rule for certain configurations.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm64/Kconfig | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 175914f2f340..c4acf8230f20 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1918,6 +1918,10 @@ config ARCH_ENABLE_THP_MIGRATION
> def_bool y
> depends on TRANSPARENT_HUGEPAGE
>
> +config HUGETLB_PAGE_SIZE_VARIABLE
> + def_bool y
> + depends on HUGETLB_PAGE
> +
> menu "Power management options"
>
> source "kernel/power/Kconfig"
>
--
Thanks,
David / dhildenb
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 2/3] arm64/hugetlb: Enable HUGETLB_PAGE_SIZE_VARIABLE
2021-02-05 8:20 ` David Hildenbrand
@ 2021-02-05 8:30 ` Anshuman Khandual
0 siblings, 0 replies; 7+ messages in thread
From: Anshuman Khandual @ 2021-02-05 8:30 UTC (permalink / raw)
To: David Hildenbrand, linux-mm, linux-arm-kernel, catalin.marinas, akpm
Cc: Will Deacon, Robin Murphy, Marek Szyprowski, Christoph Hellwig,
iommu, linux-kernel
On 2/5/21 1:50 PM, David Hildenbrand wrote:
> On 04.02.21 08:01, Anshuman Khandual wrote:
>> MAX_ORDER which invariably depends on FORCE_MAX_ZONEORDER can be a variable
>> for a given page size, depending on whether TRANSPARENT_HUGEPAGE is enabled
>> or not. In certain page size and THP combinations HUGETLB_PAGE_ORDER can be
>> greater than MAX_ORDER, making it unusable as pageblock_order.
>
> Just so I understand correctly, this does not imply that we have THP that exceed the pageblock size / MAX_ORDER size, correct?
Correct. MAX_ORDER gets incremented when THP is enabled.
config FORCE_MAX_ZONEORDER
int
default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
default "11"
^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC 3/3] dma-contiguous: Type cast MAX_ORDER as unsigned int
2021-02-04 7:01 [RFC 0/3] mm/page_alloc: Fix pageblock_order with HUGETLB_PAGE_SIZE_VARIABLE Anshuman Khandual
2021-02-04 7:01 ` [RFC 1/3] mm/page_alloc: Fix pageblock_order when HUGETLB_PAGE_ORDER >= MAX_ORDER Anshuman Khandual
2021-02-04 7:01 ` [RFC 2/3] arm64/hugetlb: Enable HUGETLB_PAGE_SIZE_VARIABLE Anshuman Khandual
@ 2021-02-04 7:01 ` Anshuman Khandual
2021-02-08 4:40 ` [RFC 0/3] mm/page_alloc: Fix pageblock_order with HUGETLB_PAGE_SIZE_VARIABLE Anshuman Khandual
3 siblings, 0 replies; 7+ messages in thread
From: Anshuman Khandual @ 2021-02-04 7:01 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, akpm
Cc: Anshuman Khandual, Will Deacon, Robin Murphy, Marek Szyprowski,
Christoph Hellwig, iommu, linux-kernel
Type cast MAX_ORDER as unsigned int to fix the following build warning.
In file included from ./include/linux/kernel.h:14,
from ./include/asm-generic/bug.h:20,
from ./arch/arm64/include/asm/bug.h:26,
from ./include/linux/bug.h:5,
from ./include/linux/mmdebug.h:5,
from ./arch/arm64/include/asm/memory.h:166,
from ./arch/arm64/include/asm/page.h:42,
from kernel/dma/contiguous.c:46:
kernel/dma/contiguous.c: In function ‘rmem_cma_setup’:
./include/linux/minmax.h:18:28: warning: comparison of distinct pointer
types lacks a cast
(!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
^~
./include/linux/minmax.h:32:4: note: in expansion of macro ‘__typecheck’
(__typecheck(x, y) && __no_side_effects(x, y))
^~~~~~~~~~~
./include/linux/minmax.h:42:24: note: in expansion of macro ‘__safe_cmp’
__builtin_choose_expr(__safe_cmp(x, y), \
^~~~~~~~~~
./include/linux/minmax.h:58:19: note: in expansion of macro
‘__careful_cmp’
#define max(x, y) __careful_cmp(x, y, >)
^~~~~~~~~~~~~
kernel/dma/contiguous.c:402:35: note: in expansion of macro ‘max’
phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
Cc: Christoph Hellwig <hch@lst.de>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: iommu@lists.linux-foundation.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
kernel/dma/contiguous.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index 3d63d91cba5c..1c2782349d71 100644
--- a/kernel/dma/contiguous.c
+++ b/kernel/dma/contiguous.c
@@ -399,7 +399,7 @@ static const struct reserved_mem_ops rmem_cma_ops = {
static int __init rmem_cma_setup(struct reserved_mem *rmem)
{
- phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
+ phys_addr_t align = PAGE_SIZE << max((unsigned int)MAX_ORDER - 1, pageblock_order);
phys_addr_t mask = align - 1;
unsigned long node = rmem->fdt_node;
bool default_cma = of_get_flat_dt_prop(node, "linux,cma-default", NULL);
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RFC 0/3] mm/page_alloc: Fix pageblock_order with HUGETLB_PAGE_SIZE_VARIABLE
2021-02-04 7:01 [RFC 0/3] mm/page_alloc: Fix pageblock_order with HUGETLB_PAGE_SIZE_VARIABLE Anshuman Khandual
` (2 preceding siblings ...)
2021-02-04 7:01 ` [RFC 3/3] dma-contiguous: Type cast MAX_ORDER as unsigned int Anshuman Khandual
@ 2021-02-08 4:40 ` Anshuman Khandual
3 siblings, 0 replies; 7+ messages in thread
From: Anshuman Khandual @ 2021-02-08 4:40 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, akpm
Cc: Will Deacon, Robin Murphy, Marek Szyprowski, Christoph Hellwig,
iommu, linux-kernel, Michal Hocko, Vlastimil Babka, Mike Kravetz,
Matthew Wilcox
On 2/4/21 12:31 PM, Anshuman Khandual wrote:
> The following warning gets triggered while trying to boot a 64K page size
> without THP config kernel on arm64 platform.
>
> WARNING: CPU: 5 PID: 124 at mm/vmstat.c:1080 __fragmentation_index+0xa4/0xc0
> Modules linked in:
> CPU: 5 PID: 124 Comm: kswapd0 Not tainted 5.11.0-rc6-00004-ga0ea7d62002 #159
> Hardware name: linux,dummy-virt (DT)
> [ 8.810673] pstate: 20400005 (nzCv daif +PAN -UAO -TCO BTYPE=--)
> [ 8.811732] pc : __fragmentation_index+0xa4/0xc0
> [ 8.812555] lr : fragmentation_index+0xf8/0x138
> [ 8.813360] sp : ffff0000864079b0
> [ 8.813958] x29: ffff0000864079b0 x28: 0000000000000372
> [ 8.814901] x27: 0000000000007682 x26: ffff8000135b3948
> [ 8.815847] x25: 1fffe00010c80f48 x24: 0000000000000000
> [ 8.816805] x23: 0000000000000000 x22: 000000000000000d
> [ 8.817764] x21: 0000000000000030 x20: ffff0005ffcb4d58
> [ 8.818712] x19: 000000000000000b x18: 0000000000000000
> [ 8.819656] x17: 0000000000000000 x16: 0000000000000000
> [ 8.820613] x15: 0000000000000000 x14: ffff8000114c6258
> [ 8.821560] x13: ffff6000bff969ba x12: 1fffe000bff969b9
> [ 8.822514] x11: 1fffe000bff969b9 x10: ffff6000bff969b9
> [ 8.823461] x9 : dfff800000000000 x8 : ffff0005ffcb4dcf
> [ 8.824415] x7 : 0000000000000001 x6 : 0000000041b58ab3
> [ 8.825359] x5 : ffff600010c80f48 x4 : dfff800000000000
> [ 8.826313] x3 : ffff8000102be670 x2 : 0000000000000007
> [ 8.827259] x1 : ffff000086407a60 x0 : 000000000000000d
> [ 8.828218] Call trace:
> [ 8.828667] __fragmentation_index+0xa4/0xc0
> [ 8.829436] fragmentation_index+0xf8/0x138
> [ 8.830194] compaction_suitable+0x98/0xb8
> [ 8.830934] wakeup_kcompactd+0xdc/0x128
> [ 8.831640] balance_pgdat+0x71c/0x7a0
> [ 8.832327] kswapd+0x31c/0x520
> [ 8.832902] kthread+0x224/0x230
> [ 8.833491] ret_from_fork+0x10/0x30
> [ 8.834150] ---[ end trace 472836f79c15516b ]---
>
> This warning comes from __fragmentation_index() when the requested order
> is greater than MAX_ORDER.
>
> static int __fragmentation_index(unsigned int order,
> struct contig_page_info *info)
> {
> unsigned long requested = 1UL << order;
>
> if (WARN_ON_ONCE(order >= MAX_ORDER)) <===== Triggered here
> return 0;
>
> Digging it further reveals that pageblock_order has been assigned a value
> which is greater than MAX_ORDER failing the above check. But why this
> happened ? Because HUGETLB_PAGE_ORDER for the given config on arm64 is
> greater than MAX_ORDER.
>
> The solution involves enabling HUGETLB_PAGE_SIZE_VARIABLE which would make
> pageblock_order a variable instead of constant HUGETLB_PAGE_ORDER. But that
> change alone also did not really work as pageblock_order still got assigned
> as HUGETLB_PAGE_ORDER in set_pageblock_order(). HUGETLB_PAGE_ORDER needs to
> be less than MAX_ORDER for its appropriateness as pageblock_order otherwise
> just fallback to MAX_ORDER - 1 as before. While here it also fixes a build
> problem via type casting MAX_ORDER in rmem_cma_setup().
>
> This series applies in v5.11-rc6 and has been slightly tested on arm64. But
> looking for some early feedbacks particularly with respect to concerns in
> subscribing HUGETLB_PAGE_SIZE_VARIABLE on a platform where the hugetlb page
> size is config dependent but not really a runtime variable. Even though it
> appears that HUGETLB_PAGE_SIZE_VARIABLE is used only while computing the
> pageblock_order, could there be other implications ?
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Robin Murphy <robin.murphy@arm.com>
> Cc: Marek Szyprowski <m.szyprowski@samsung.com>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: iommu@lists.linux-foundation.org
> Cc: linux-mm@kvack.org
> Cc: linux-kernel@vger.kernel.org
Probably missed some more folks, adding them here.
+ Michal Hocko <mhocko@kernel.org>
+ Vlastimil Babka <vbabka@suse.cz>
+ Mike Kravetz <mike.kravetz@oracle.com>
+ Matthew Wilcox <willy@infradead.org>
^ permalink raw reply [flat|nested] 7+ messages in thread