* Re: [PATCH v2 1/2] selftest/vm: Use correct PAGE_SHIFT value for ppc64
From: Mike Rapoport @ 2022-02-11 13:28 UTC (permalink / raw)
To: Aneesh Kumar K V
Cc: Shuah Khan, linux-mm, linux-kselftest, akpm, linuxppc-dev
In-Reply-To: <27a71056-489a-4099-b094-64766bea84db@linux.ibm.com>
Hi Aneesh,
On Fri, Feb 11, 2022 at 05:22:13PM +0530, Aneesh Kumar K V wrote:
> On 2/11/22 16:03, Mike Rapoport wrote:
> > On Fri, Feb 11, 2022 at 12:03:28PM +0530, Aneesh Kumar K.V wrote:
> > > Keep it simple by using a #define and limiting hugepage size to 2M.
> > > This keeps the test simpler instead of dynamically finding the page size
> > > and huge page size.
> > >
> > > Without this tests are broken w.r.t reading /proc/self/pagemap
> > >
> > > if (pread(pagemap_fd, ent, sizeof(ent),
> > > (uintptr_t)ptr >> (PAGE_SHIFT - 3)) != sizeof(ent))
> > > err(2, "read pagemap");
> > >
> > > Cc: Shuah Khan <shuah@kernel.org>
> > > Cc: linux-kselftest@vger.kernel.org
> > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> > > ---
> > > tools/testing/selftests/vm/ksm_tests.c | 9 ++++++++-
> > > tools/testing/selftests/vm/transhuge-stress.c | 9 ++++++++-
> > > 2 files changed, 16 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/tools/testing/selftests/vm/ksm_tests.c b/tools/testing/selftests/vm/ksm_tests.c
> > > index 1436e1a9a3d3..cae72872152b 100644
> > > --- a/tools/testing/selftests/vm/ksm_tests.c
> > > +++ b/tools/testing/selftests/vm/ksm_tests.c
> > > @@ -22,7 +22,14 @@
> > > #define KSM_MERGE_ACROSS_NODES_DEFAULT true
> > > #define MB (1ul << 20)
> > > -#define PAGE_SHIFT 12
> > > +#ifdef __powerpc64__
> > > +#define PAGE_SHIFT 16
> > > +#else
> > > +#define PAGE_SHIFT 12
> > > +#endif
> >
> > Page size can be other than 4096 for other configurations as well. And even
> > on ppc64 it's not necessarily 64k.
> >
>
> But most common test config is with 64K page size.
>
> > Ideally page size in selftests/vm should be sysconf(_SC_PAGESIZE)
>
>
> yes. As explained in commit message, the idea was to keep it simpler.
I think it's simple enough (compile tested on x86 only):
From 219577d87041f19f2c00dc7c23e0fd5aad8b02d5 Mon Sep 17 00:00:00 2001
From: Mike Rapoport <rppt@linux.ibm.com>
Date: Fri, 11 Feb 2022 15:24:13 +0200
Subject: [PATCH] selftest/vm: add helpers to detect PAGE_SIZE and PAGE_SHIFT
PAGE_SIZE is not 4096 in many configurations, particularily ppc64 uses
64K pages in majority of cases.
Add helpers to detect PAGE_SIZE and PAGE_SHIFT dynamically.
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
tools/testing/selftests/vm/gup_test.c | 3 +-
tools/testing/selftests/vm/ksm_tests.c | 8 +----
tools/testing/selftests/vm/transhuge-stress.c | 9 ++----
tools/testing/selftests/vm/util.h | 29 +++++++++++++++++++
4 files changed, 34 insertions(+), 15 deletions(-)
create mode 100644 tools/testing/selftests/vm/util.h
diff --git a/tools/testing/selftests/vm/gup_test.c b/tools/testing/selftests/vm/gup_test.c
index fe043f67798b..cda837a14736 100644
--- a/tools/testing/selftests/vm/gup_test.c
+++ b/tools/testing/selftests/vm/gup_test.c
@@ -10,8 +10,9 @@
#include <assert.h>
#include "../../../../mm/gup_test.h"
+#include "util.h"
+
#define MB (1UL << 20)
-#define PAGE_SIZE sysconf(_SC_PAGESIZE)
/* Just the flags we need, copied from mm.h: */
#define FOLL_WRITE 0x01 /* check pte is writable */
diff --git a/tools/testing/selftests/vm/ksm_tests.c b/tools/testing/selftests/vm/ksm_tests.c
index cae72872152b..7faafd24446f 100644
--- a/tools/testing/selftests/vm/ksm_tests.c
+++ b/tools/testing/selftests/vm/ksm_tests.c
@@ -12,6 +12,7 @@
#include "../kselftest.h"
#include "../../../../include/vdso/time64.h"
+#include "util.h"
#define KSM_SYSFS_PATH "/sys/kernel/mm/ksm/"
#define KSM_FP(s) (KSM_SYSFS_PATH s)
@@ -22,17 +23,10 @@
#define KSM_MERGE_ACROSS_NODES_DEFAULT true
#define MB (1ul << 20)
-#ifdef __powerpc64__
-#define PAGE_SHIFT 16
-#else
-#define PAGE_SHIFT 12
-#endif
/*
* On ppc64 this will only work with radix 2M hugepage size
*/
#define HPAGE_SHIFT 21
-
-#define PAGE_SIZE (1 << PAGE_SHIFT)
#define HPAGE_SIZE (1 << HPAGE_SHIFT)
#define PAGEMAP_PRESENT(ent) (((ent) & (1ull << 63)) != 0)
diff --git a/tools/testing/selftests/vm/transhuge-stress.c b/tools/testing/selftests/vm/transhuge-stress.c
index b1f8d98355c5..baf90a745d28 100644
--- a/tools/testing/selftests/vm/transhuge-stress.c
+++ b/tools/testing/selftests/vm/transhuge-stress.c
@@ -16,17 +16,12 @@
#include <string.h>
#include <sys/mman.h>
-#ifdef __powerpc64__
-#define PAGE_SHIFT 16
-#else
-#define PAGE_SHIFT 12
-#endif
+#include "util.h"
+
/*
* On ppc64 this will only work with radix 2M hugepage size
*/
#define HPAGE_SHIFT 21
-
-#define PAGE_SIZE (1 << PAGE_SHIFT)
#define HPAGE_SIZE (1 << HPAGE_SHIFT)
#define PAGEMAP_PRESENT(ent) (((ent) & (1ull << 63)) != 0)
diff --git a/tools/testing/selftests/vm/util.h b/tools/testing/selftests/vm/util.h
new file mode 100644
index 000000000000..1c85d7583bac
--- /dev/null
+++ b/tools/testing/selftests/vm/util.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __KSELFTEST_VM_UTIL_H
+#define __KSELFTEST_VM_UTIL_H
+
+#include <string.h> /* ffsl() */
+#include <unistd.h> /* _SC_PAGESIZE */
+
+static unsigned __page_size;
+static unsigned __page_shift;
+
+static inline unsigned page_size(void)
+{
+ if (!__page_size)
+ __page_size = sysconf(_SC_PAGESIZE);
+ return __page_size;
+}
+
+static inline unsigned page_shift(void)
+{
+ if (!__page_shift)
+ __page_shift = (ffsl(page_size()) - 1);
+ return __page_shift;
+}
+
+#define PAGE_SHIFT (page_shift())
+#define PAGE_SIZE (page_size())
+
+#endif /* __KSELFTEST_VM_UTIL_H */
--
2.34.1
--
Sincerely yours,
Mike.
^ permalink raw reply related
* Re: [RFC] Upstreaming Linux for Nintendo Wii U
From: Christophe Leroy @ 2022-02-11 13:11 UTC (permalink / raw)
To: Michael Ellerman, Ash Logan, benh@kernel.crashing.org,
paulus@samba.org
Cc: linkmauve@linkmauve.fr, linux-usb@vger.kernel.org,
linux-kernel@vger.kernel.org, amd-gfx@lists.freedesktop.org,
linuxppc-dev@lists.ozlabs.org, j.ne@posteo.net
In-Reply-To: <87ee49sktb.fsf@mpe.ellerman.id.au>
Hi Ash,
Le 11/02/2022 à 12:29, Michael Ellerman a écrit :
> Ash Logan <ash@heyquark.com> writes:
>> - Like the Wii before it, the Wii U has a small amount of RAM at address
>> zero, a gap, then a large amount of RAM at a higher address. Instead of
>> the "map everything and reserve the gap" approach of the Wii, we loop
>> over each memblock and map only true RAM[9]. This seems to work, but as
>> far as I can tell is unique amongst powerpc32 platforms, so it's worth
>> pointing out. (Note: I've been told this doesn't work anymore after some
>> KUAP changes[10], so this point might be moot; haven't investigated)
>
> We'd need more detail on that I guess. Currently all the 32-bit
> platforms use the flat memory model, which assumes RAM is a single
> contiguous block. Though that doesn't mean it all has to be used or
> mapped, like the Wii does. To properly support your layout you should be
> using sparsemem, but it's possible that's more trouble than it's worth,
> I'm not sure. How far apart are the low and high blocks of RAM, and what
> are their sizes?
Can you provide details on what's happening with KUAP changes ?
You are pointing to series https://lkml.org/lkml/2021/6/3/204
Does it work when CONFIG_PPC_KUAP is not selected or doesn't it work
either ?
Are you able to bisect which commit of that series is the culprit ?
Thanks
Christophe
^ permalink raw reply
* Re: [PATCH v2] powerpc/mm: Update default hugetlb size early
From: David Hildenbrand @ 2022-02-11 12:29 UTC (permalink / raw)
To: Aneesh Kumar K.V, linuxppc-dev, mpe, Christophe Leroy; +Cc: linux-mm
In-Reply-To: <87tud5a8x5.fsf@linux.ibm.com>
On 11.02.22 13:23, Aneesh Kumar K.V wrote:
> David Hildenbrand <david@redhat.com> writes:
>
>> On 11.02.22 10:16, Aneesh Kumar K V wrote:
>>> On 2/11/22 14:00, David Hildenbrand wrote:
>>>> On 11.02.22 07:52, Aneesh Kumar K.V wrote:
>>>>> commit: d9c234005227 ("Do not depend on MAX_ORDER when grouping pages by mobility")
>>>>> introduced pageblock_order which will be used to group pages better.
>>>>> The kernel now groups pages based on the value of HPAGE_SHIFT. Hence HPAGE_SHIFT
>>>>> should be set before we call set_pageblock_order.
>>>>>
>>>>> set_pageblock_order happens early in the boot and default hugetlb page size
>>>>> should be initialized before that to compute the right pageblock_order value.
>>>>>
>>>>> Currently, default hugetlbe page size is set via arch_initcalls which happens
>>>>> late in the boot as shown via the below callstack:
>>>>>
>>>>> [c000000007383b10] [c000000001289328] hugetlbpage_init+0x2b8/0x2f8
>>>>> [c000000007383bc0] [c0000000012749e4] do_one_initcall+0x14c/0x320
>>>>> [c000000007383c90] [c00000000127505c] kernel_init_freeable+0x410/0x4e8
>>>>> [c000000007383da0] [c000000000012664] kernel_init+0x30/0x15c
>>>>> [c000000007383e10] [c00000000000cf14] ret_from_kernel_thread+0x5c/0x64
>>>>>
>>>>> and the pageblock_order initialization is done early during the boot.
>>>>>
>>>>> [c0000000018bfc80] [c0000000012ae120] set_pageblock_order+0x50/0x64
>>>>> [c0000000018bfca0] [c0000000012b3d94] sparse_init+0x188/0x268
>>>>> [c0000000018bfd60] [c000000001288bfc] initmem_init+0x28c/0x328
>>>>> [c0000000018bfe50] [c00000000127b370] setup_arch+0x410/0x480
>>>>> [c0000000018bfed0] [c00000000127401c] start_kernel+0xb8/0x934
>>>>> [c0000000018bff90] [c00000000000d984] start_here_common+0x1c/0x98
>>>>>
>>>>> delaying default hugetlb page size initialization implies the kernel will
>>>>> initialize pageblock_order to (MAX_ORDER - 1) which is not an optimal
>>>>> value for mobility grouping. IIUC we always had this issue. But it was not
>>>>> a problem for hash translation mode because (MAX_ORDER - 1) is the same as
>>>>> HUGETLB_PAGE_ORDER (8) in the case of hash (16MB). With radix,
>>>>> HUGETLB_PAGE_ORDER will be 5 (2M size) and hence pageblock_order should be
>>>>> 5 instead of 8.
>>>>
>>>>
>>>> A related question: Can we on ppc still have pageblock_order > MAX_ORDER
>>>> - 1? We have some code for that and I am not so sure if we really need that.
>>>>
>>>
>>> I also have been wondering about the same. On book3s64 I don't think we
>>> need that support for both 64K and 4K page size because with hash
>>> hugetlb size is MAX_ORDER -1. (16MB hugepage size)
>>>
>>> I am not sure about the 256K page support. Christophe may be able to
>>> answer that.
>>>
>>> For the gigantic hugepage support we depend on cma based allocation or
>>> firmware reservation. So I am not sure why we ever considered pageblock
>>> > MAX_ORDER -1 scenario. If you have pointers w.r.t why that was ever
>>> needed, I could double-check whether ppc64 is still dependent on that.
>>
>> commit dc78327c0ea7da5186d8cbc1647bd6088c5c9fa5
>> Author: Michal Nazarewicz <mina86@mina86.com>
>> Date: Wed Jul 2 15:22:35 2014 -0700
>>
>> mm: page_alloc: fix CMA area initialisation when pageblock > MAX_ORDER
>>
>> indicates that at least arm64 used to have cases for that as well.
>>
>> However, nowadays with ARM64_64K_PAGES we have FORCE_MAX_ZONEORDER=14 as
>> default, corresponding to 512MiB.
>>
>> So I'm not sure if this is something worth supporting. If you want
>> somewhat reliable gigantic pages, use CMA or preallocate them during boot.
>>
>> --
>> Thanks,
>>
>> David / dhildenb
>
> I could build a kernel with FORCE_MAX_ZONEORDER=8 and pageblock_order =
> 8. We need to disable THP for such a kernel to boot, because THP do
> check for PMD_ORDER < MAX_ORDER. I was able to boot that kernel on a
> virtualized platform, but then gigantic_page_runtime_supported is not
> supported on such config with hash translation.
>
I'm currently playing with the idea of the following (uncompiled,untested):
From 68e0a158a5060bc1a175d12b20e21794763a33df Mon Sep 17 00:00:00 2001
From: David Hildenbrand <david@redhat.com>
Date: Fri, 11 Feb 2022 11:40:27 +0100
Subject: [PATCH] mm: enforce pageblock_order < MAX_ORDER
Some places in the kernel don't really expect pageblock_order >=
MAX_ORDER, and it looks like this is only possible in corner cases:
1) CONFIG_DEFERRED_STRUCT_PAGE_INIT we'll end up freeing pageblock_order
pages via __free_pages_core(), which cannot possibly work.
2) mm/page_reporting.c won't be reporting any pages with default
page_reporting_order == pageblock_order, as we'll be skipping the
reporting loop inside page_reporting_process_zone().
3) __rmqueue_fallback() will never be able to steal with
ALLOC_NOFRAGMENT.
4) find_zone_movable_pfns_for_nodes() will roundup the ZONE_MOVABLE
start PFN to MAX_ORDER_NR_PAGES. Consequently with a bigger
pageblock_order, we could have pageblocks partially managed by two
zones.
pageblock_order >= MAX_ORDER is weird either way: it's a pure
optimization for making alloc_contig_range(), as used for allcoation of
gigantic pages, a little more reliable to succeed. However, if there is
demand for somewhat reliable allocation of gigantic pages, affected setups
should be using CMA or boottime allocations instead.
So let's make sure that pageblock_order < MAX_ORDER and simplify.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
arch/powerpc/include/asm/fadump-internal.h | 4 +--
drivers/of/of_reserved_mem.c | 8 ++---
include/linux/pageblock-flags.h | 7 +++--
kernel/dma/contiguous.c | 2 +-
mm/Kconfig | 3 ++
mm/cma.c | 6 ++--
mm/page_alloc.c | 34 ++++++----------------
mm/page_isolation.c | 6 ++--
8 files changed, 26 insertions(+), 44 deletions(-)
diff --git a/arch/powerpc/include/asm/fadump-internal.h b/arch/powerpc/include/asm/fadump-internal.h
index 52189928ec08..959c7df15baa 100644
--- a/arch/powerpc/include/asm/fadump-internal.h
+++ b/arch/powerpc/include/asm/fadump-internal.h
@@ -20,9 +20,7 @@
#define memblock_num_regions(memblock_type) (memblock.memblock_type.cnt)
/* Alignment per CMA requirement. */
-#define FADUMP_CMA_ALIGNMENT (PAGE_SIZE << \
- max_t(unsigned long, MAX_ORDER - 1, \
- pageblock_order))
+#define FADUMP_CMA_ALIGNMENT (PAGE_SIZE * MAX_ORDER_NR_PAGES)
/* FAD commands */
#define FADUMP_REGISTER 1
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 9c0fb962c22b..dcbbffca0c57 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -116,12 +116,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
if (IS_ENABLED(CONFIG_CMA)
&& of_flat_dt_is_compatible(node, "shared-dma-pool")
&& of_get_flat_dt_prop(node, "reusable", NULL)
- && !nomap) {
- unsigned long order =
- max_t(unsigned long, MAX_ORDER - 1, pageblock_order);
-
- align = max(align, (phys_addr_t)PAGE_SIZE << order);
- }
+ && !nomap)
+ align = max_t(phys_addr_t, align, PAGE_SIZE * MAX_ORDER_NR_PAGES);
prop = of_get_flat_dt_prop(node, "alloc-ranges", &len);
if (prop) {
diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h
index 973fd731a520..83c7248053a1 100644
--- a/include/linux/pageblock-flags.h
+++ b/include/linux/pageblock-flags.h
@@ -37,8 +37,11 @@ extern unsigned int pageblock_order;
#else /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
-/* Huge pages are a constant size */
-#define pageblock_order HUGETLB_PAGE_ORDER
+/*
+ * Huge pages are a constant size, but don't exceed the maximum allocation
+ * granularity.
+ */
+#define pageblock_order min_t(unsigned int, HUGETLB_PAGE_ORDER, MAX_ORDER - 1)
#endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index 3d63d91cba5c..4333c05c14fc 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_ORDER_NR_PAGES;
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);
diff --git a/mm/Kconfig b/mm/Kconfig
index 3326ee3903f3..4c91b92e7537 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -262,6 +262,9 @@ config HUGETLB_PAGE_SIZE_VARIABLE
HUGETLB_PAGE_ORDER when there are multiple HugeTLB page sizes available
on a platform.
+ Note that the pageblock_order cannot exceed MAX_ORDER - 1 and will be
+ clamped down to MAX_ORDER - 1.
+
config CONTIG_ALLOC
def_bool (MEMORY_ISOLATION && COMPACTION) || CMA
diff --git a/mm/cma.c b/mm/cma.c
index bc9ca8f3c487..418e214685da 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -180,8 +180,7 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
return -EINVAL;
/* ensure minimal alignment required by mm core */
- alignment = PAGE_SIZE <<
- max_t(unsigned long, MAX_ORDER - 1, pageblock_order);
+ alignment = PAGE_SIZE * MAX_ORDER_NR_PAGES;
/* alignment should be aligned with order_per_bit */
if (!IS_ALIGNED(alignment >> PAGE_SHIFT, 1 << order_per_bit))
@@ -268,8 +267,7 @@ int __init cma_declare_contiguous_nid(phys_addr_t base,
* migratetype page by page allocator's buddy algorithm. In the case,
* you couldn't get a contiguous memory, which is not what we want.
*/
- alignment = max(alignment, (phys_addr_t)PAGE_SIZE <<
- max_t(unsigned long, MAX_ORDER - 1, pageblock_order));
+ alignment = max_t(phys_addr_t, alignment, PAGE_SIZE * MAX_ORDER_NR_PAGES);
if (fixed && base & (alignment - 1)) {
ret = -EINVAL;
pr_err("Region at %pa must be aligned to %pa bytes\n",
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3589febc6d31..36d9fc308a26 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1072,14 +1072,12 @@ static inline void __free_one_page(struct page *page,
int migratetype, fpi_t fpi_flags)
{
struct capture_control *capc = task_capc(zone);
+ unsigned int max_order = pageblock_order;
unsigned long buddy_pfn;
unsigned long combined_pfn;
- unsigned int max_order;
struct page *buddy;
bool to_tail;
- max_order = min_t(unsigned int, MAX_ORDER - 1, pageblock_order);
-
VM_BUG_ON(!zone_is_initialized(zone));
VM_BUG_ON_PAGE(page->flags & PAGE_FLAGS_CHECK_AT_PREP, page);
@@ -2260,19 +2258,8 @@ void __init init_cma_reserved_pageblock(struct page *page)
} while (++p, --i);
set_pageblock_migratetype(page, MIGRATE_CMA);
-
- if (pageblock_order >= MAX_ORDER) {
- i = pageblock_nr_pages;
- p = page;
- do {
- set_page_refcounted(p);
- __free_pages(p, MAX_ORDER - 1);
- p += MAX_ORDER_NR_PAGES;
- } while (i -= MAX_ORDER_NR_PAGES);
- } else {
- set_page_refcounted(page);
- __free_pages(page, pageblock_order);
- }
+ set_page_refcounted(page);
+ __free_pages(page, pageblock_order);
adjust_managed_page_count(page, pageblock_nr_pages);
page_zone(page)->cma_pages += pageblock_nr_pages;
@@ -7389,16 +7376,15 @@ static inline void setup_usemap(struct zone *zone) {}
/* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */
void __init set_pageblock_order(void)
{
- unsigned int order;
+ unsigned int order = MAX_ORDER - 1;
/* Check that pageblock_nr_pages has not already been setup */
if (pageblock_order)
return;
- if (HPAGE_SHIFT > PAGE_SHIFT)
+ /* Don't let pageblocks exceed the maximum allocation granularity. */
+ if (HPAGE_SHIFT > PAGE_SHIFT && HUGETLB_PAGE_ORDER < order)
order = HUGETLB_PAGE_ORDER;
- else
- order = MAX_ORDER - 1;
/*
* Assume the largest contiguous order of interest is a huge page.
@@ -7593,7 +7579,7 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat)
if (!pgdat->node_spanned_pages)
return;
- start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1);
+ start = ALIGN_DOWN(pgdat->node_start_pfn, MAX_ORDER_NR_PAGES);
offset = pgdat->node_start_pfn - start;
/* ia64 gets its own node_mem_map, before this, without bootmem */
if (!pgdat->node_mem_map) {
@@ -8986,14 +8972,12 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
#ifdef CONFIG_CONTIG_ALLOC
static unsigned long pfn_max_align_down(unsigned long pfn)
{
- return pfn & ~(max_t(unsigned long, MAX_ORDER_NR_PAGES,
- pageblock_nr_pages) - 1);
+ return ALIGN_DOWN(pfn, MAX_ORDER_NR_PAGES);
}
static unsigned long pfn_max_align_up(unsigned long pfn)
{
- return ALIGN(pfn, max_t(unsigned long, MAX_ORDER_NR_PAGES,
- pageblock_nr_pages));
+ return ALIGN(pfn, MAX_ORDER_NR_PAGES);
}
#if defined(CONFIG_DYNAMIC_DEBUG) || \
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index f67c4c70f17f..e679af6121e3 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -276,9 +276,9 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
int ret;
/*
- * Note: pageblock_nr_pages != MAX_ORDER. Then, chunks of free pages
- * are not aligned to pageblock_nr_pages.
- * Then we just check migratetype first.
+ * Note: if pageblock_nr_pages < MAX_ORDER_NR_PAGES, then chunks of free
+ * pages are not necessarily aligned to pageblock_nr_pages. Check the
+ * migratetype first.
*/
for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
page = __first_valid_page(pfn, pageblock_nr_pages);
--
2.34.1
--
Thanks,
David / dhildenb
^ permalink raw reply related
* Re: [PATCH v2] powerpc/mm: Update default hugetlb size early
From: Aneesh Kumar K.V @ 2022-02-11 12:23 UTC (permalink / raw)
To: David Hildenbrand, linuxppc-dev, mpe, Christophe Leroy; +Cc: linux-mm
In-Reply-To: <b77816ef-80fd-40b7-cf6e-6de2a3125eb1@redhat.com>
David Hildenbrand <david@redhat.com> writes:
> On 11.02.22 10:16, Aneesh Kumar K V wrote:
>> On 2/11/22 14:00, David Hildenbrand wrote:
>>> On 11.02.22 07:52, Aneesh Kumar K.V wrote:
>>>> commit: d9c234005227 ("Do not depend on MAX_ORDER when grouping pages by mobility")
>>>> introduced pageblock_order which will be used to group pages better.
>>>> The kernel now groups pages based on the value of HPAGE_SHIFT. Hence HPAGE_SHIFT
>>>> should be set before we call set_pageblock_order.
>>>>
>>>> set_pageblock_order happens early in the boot and default hugetlb page size
>>>> should be initialized before that to compute the right pageblock_order value.
>>>>
>>>> Currently, default hugetlbe page size is set via arch_initcalls which happens
>>>> late in the boot as shown via the below callstack:
>>>>
>>>> [c000000007383b10] [c000000001289328] hugetlbpage_init+0x2b8/0x2f8
>>>> [c000000007383bc0] [c0000000012749e4] do_one_initcall+0x14c/0x320
>>>> [c000000007383c90] [c00000000127505c] kernel_init_freeable+0x410/0x4e8
>>>> [c000000007383da0] [c000000000012664] kernel_init+0x30/0x15c
>>>> [c000000007383e10] [c00000000000cf14] ret_from_kernel_thread+0x5c/0x64
>>>>
>>>> and the pageblock_order initialization is done early during the boot.
>>>>
>>>> [c0000000018bfc80] [c0000000012ae120] set_pageblock_order+0x50/0x64
>>>> [c0000000018bfca0] [c0000000012b3d94] sparse_init+0x188/0x268
>>>> [c0000000018bfd60] [c000000001288bfc] initmem_init+0x28c/0x328
>>>> [c0000000018bfe50] [c00000000127b370] setup_arch+0x410/0x480
>>>> [c0000000018bfed0] [c00000000127401c] start_kernel+0xb8/0x934
>>>> [c0000000018bff90] [c00000000000d984] start_here_common+0x1c/0x98
>>>>
>>>> delaying default hugetlb page size initialization implies the kernel will
>>>> initialize pageblock_order to (MAX_ORDER - 1) which is not an optimal
>>>> value for mobility grouping. IIUC we always had this issue. But it was not
>>>> a problem for hash translation mode because (MAX_ORDER - 1) is the same as
>>>> HUGETLB_PAGE_ORDER (8) in the case of hash (16MB). With radix,
>>>> HUGETLB_PAGE_ORDER will be 5 (2M size) and hence pageblock_order should be
>>>> 5 instead of 8.
>>>
>>>
>>> A related question: Can we on ppc still have pageblock_order > MAX_ORDER
>>> - 1? We have some code for that and I am not so sure if we really need that.
>>>
>>
>> I also have been wondering about the same. On book3s64 I don't think we
>> need that support for both 64K and 4K page size because with hash
>> hugetlb size is MAX_ORDER -1. (16MB hugepage size)
>>
>> I am not sure about the 256K page support. Christophe may be able to
>> answer that.
>>
>> For the gigantic hugepage support we depend on cma based allocation or
>> firmware reservation. So I am not sure why we ever considered pageblock
>> > MAX_ORDER -1 scenario. If you have pointers w.r.t why that was ever
>> needed, I could double-check whether ppc64 is still dependent on that.
>
> commit dc78327c0ea7da5186d8cbc1647bd6088c5c9fa5
> Author: Michal Nazarewicz <mina86@mina86.com>
> Date: Wed Jul 2 15:22:35 2014 -0700
>
> mm: page_alloc: fix CMA area initialisation when pageblock > MAX_ORDER
>
> indicates that at least arm64 used to have cases for that as well.
>
> However, nowadays with ARM64_64K_PAGES we have FORCE_MAX_ZONEORDER=14 as
> default, corresponding to 512MiB.
>
> So I'm not sure if this is something worth supporting. If you want
> somewhat reliable gigantic pages, use CMA or preallocate them during boot.
>
> --
> Thanks,
>
> David / dhildenb
I could build a kernel with FORCE_MAX_ZONEORDER=8 and pageblock_order =
8. We need to disable THP for such a kernel to boot, because THP do
check for PMD_ORDER < MAX_ORDER. I was able to boot that kernel on a
virtualized platform, but then gigantic_page_runtime_supported is not
supported on such config with hash translation.
On non virtualized platform I am hitting crashes like below during boot.
[ 47.637865][ C42] =============================================================================
[ 47.637907][ C42] BUG pgtable-2^11 (Not tainted): Object already free
[ 47.637925][ C42] -----------------------------------------------------------------------------
[ 47.637925][ C42]
[ 47.637945][ C42] Allocated in __pud_alloc+0x84/0x2a0 age=278 cpu=40 pid=1409
[ 47.637974][ C42] __slab_alloc.isra.0+0x40/0x60
[ 47.637995][ C42] kmem_cache_alloc+0x1a8/0x510
[ 47.638010][ C42] __pud_alloc+0x84/0x2a0
[ 47.638024][ C42] copy_page_range+0x38c/0x1b90
[ 47.638040][ C42] dup_mm+0x548/0x880
[ 47.638058][ C42] copy_process+0xdc0/0x1e90
[ 47.638076][ C42] kernel_clone+0xd4/0x9d0
[ 47.638094][ C42] __do_sys_clone+0x88/0xe0
[ 47.638112][ C42] system_call_exception+0x368/0x3a0
[ 47.638128][ C42] system_call_common+0xec/0x250
[ 47.638147][ C42] Freed in __tlb_remove_table+0x1d4/0x200 age=263 cpu=57 pid=326
[ 47.638172][ C42] kmem_cache_free+0x44c/0x680
[ 47.638187][ C42] __tlb_remove_table+0x1d4/0x200
[ 47.638204][ C42] tlb_remove_table_rcu+0x54/0xa0
[ 47.638222][ C42] rcu_core+0xdd4/0x15d0
[ 47.638239][ C42] __do_softirq+0x360/0x69c
[ 47.638257][ C42] run_ksoftirqd+0x54/0xc0
[ 47.638273][ C42] smpboot_thread_fn+0x28c/0x2f0
[ 47.638290][ C42] kthread+0x1a4/0x1b0
[ 47.638305][ C42] ret_from_kernel_thread+0x5c/0x64
[ 47.638320][ C42] Slab 0xc00c00000000d600 objects=10 used=9 fp=0xc0000000035a8000 flags=0x7ffff000010201(locked|slab|head|node=0|zone=0|lastcpupid=0x7ffff)
[ 47.638352][ C42] Object 0xc0000000035a8000 @offset=163840 fp=0x0000000000000000
[ 47.638352][ C42]
[ 47.638373][ C42] Redzone c0000000035a4000: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
[ 47.638394][ C42] Redzone c0000000035a4010: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
[ 47.638414][ C42] Redzone c0000000035a4020: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
[ 47.638435][ C42] Redzone c0000000035a4030: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
[ 47.638455][ C42] Redzone c0000000035a4040: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
[ 47.638474][ C42] Redzone c0000000035a4050: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
[ 47.638494][ C42] Redzone c0000000035a4060: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
[ 47.638514][ C42] Redzone c0000000035a4070: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
[ 47.638534][ C42] Redzone c0000000035a4080: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
^ permalink raw reply
* Re: [PATCH v2 1/2] selftest/vm: Use correct PAGE_SHIFT value for ppc64
From: Aneesh Kumar K V @ 2022-02-11 11:52 UTC (permalink / raw)
To: Mike Rapoport; +Cc: Shuah Khan, linux-mm, linux-kselftest, akpm, linuxppc-dev
In-Reply-To: <YgY7lDToiQ0pM6U6@kernel.org>
On 2/11/22 16:03, Mike Rapoport wrote:
> On Fri, Feb 11, 2022 at 12:03:28PM +0530, Aneesh Kumar K.V wrote:
>> Keep it simple by using a #define and limiting hugepage size to 2M.
>> This keeps the test simpler instead of dynamically finding the page size
>> and huge page size.
>>
>> Without this tests are broken w.r.t reading /proc/self/pagemap
>>
>> if (pread(pagemap_fd, ent, sizeof(ent),
>> (uintptr_t)ptr >> (PAGE_SHIFT - 3)) != sizeof(ent))
>> err(2, "read pagemap");
>>
>> Cc: Shuah Khan <shuah@kernel.org>
>> Cc: linux-kselftest@vger.kernel.org
>> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
>> ---
>> tools/testing/selftests/vm/ksm_tests.c | 9 ++++++++-
>> tools/testing/selftests/vm/transhuge-stress.c | 9 ++++++++-
>> 2 files changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/testing/selftests/vm/ksm_tests.c b/tools/testing/selftests/vm/ksm_tests.c
>> index 1436e1a9a3d3..cae72872152b 100644
>> --- a/tools/testing/selftests/vm/ksm_tests.c
>> +++ b/tools/testing/selftests/vm/ksm_tests.c
>> @@ -22,7 +22,14 @@
>> #define KSM_MERGE_ACROSS_NODES_DEFAULT true
>> #define MB (1ul << 20)
>>
>> -#define PAGE_SHIFT 12
>> +#ifdef __powerpc64__
>> +#define PAGE_SHIFT 16
>> +#else
>> +#define PAGE_SHIFT 12
>> +#endif
>
> Page size can be other than 4096 for other configurations as well. And even
> on ppc64 it's not necessarily 64k.
>
But most common test config is with 64K page size.
> Ideally page size in selftests/vm should be sysconf(_SC_PAGESIZE)
yes. As explained in commit message, the idea was to keep it simpler.
"Keep it simple by using a #define and limiting hugepage size to 2M.
This keeps the test simpler instead of dynamically finding the page size
and huge page size.
Without this tests are broken w.r.t reading /proc/self/pagemap"
We can definitely look at updating multiple tests in selftest/vm to work
with dynamic value of pagesize and huagepage size. But that can be
outside this patch?
>
>> +/*
>> + * On ppc64 this will only work with radix 2M hugepage size
>> + */
>> #define HPAGE_SHIFT 21
>>
>> #define PAGE_SIZE (1 << PAGE_SHIFT)
>> diff --git a/tools/testing/selftests/vm/transhuge-stress.c b/tools/testing/selftests/vm/transhuge-stress.c
>> index 5e4c036f6ad3..b1f8d98355c5 100644
>> --- a/tools/testing/selftests/vm/transhuge-stress.c
>> +++ b/tools/testing/selftests/vm/transhuge-stress.c
>> @@ -16,7 +16,14 @@
>> #include <string.h>
>> #include <sys/mman.h>
>>
>> -#define PAGE_SHIFT 12
>> +#ifdef __powerpc64__
>> +#define PAGE_SHIFT 16
>> +#else
>> +#define PAGE_SHIFT 12
>> +#endif
>> +/*
>> + * On ppc64 this will only work with radix 2M hugepage size
>> + */
>> #define HPAGE_SHIFT 21
>>
>> #define PAGE_SIZE (1 << PAGE_SHIFT)
>> --
>> 2.34.1
>>
>>
>
^ permalink raw reply
* Re: [PATCH kernel 2/3] powerpc/llvm: Sample config for LLVM LTO
From: Naveen N. Rao @ 2022-02-11 11:44 UTC (permalink / raw)
To: Alexey Kardashevskiy, llvm
Cc: Nathan Lynch, Fabiano Rosas, Nick Desaulniers, Nicholas Piggin,
Nathan Chancellor, Sathvika Vasireddy, Joel Stanley, linuxppc-dev,
Daniel Axtens
In-Reply-To: <20220211023125.1790960-3-aik@ozlabs.ru>
Alexey Kardashevskiy wrote:
>
> Disables CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT as CONFIG_HAS_LTO_CLANG
> depends on it being disabled. In order to avoid disabling way too many
> options (like DYNAMIC_FTRACE/FUNCTION_TRACER), this converts
> FTRACE_MCOUNT_USE_RECORDMCOUNT from def_bool to bool.
<snip>
> +CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT=n
I don't think that will work since we have no other ways of generating
mcount locations on powerpc. And since we decided to only support
DYNAMIC_FTRACE, I guess we will need to disable FUNCTION_TRACER to get
this working, for now.
I am looking into ways to get ftrace working in this scenario.
- Naveen
^ permalink raw reply
* Re: [RFC PATCH 2/3] powerpc/ftrace: Override ftrace_location_lookup() for MPROFILE_KERNEL
From: Naveen N. Rao @ 2022-02-11 11:36 UTC (permalink / raw)
To: Steven Rostedt
Cc: Daniel Borkmann, Yauheni Kaliuta, Jordan Niethe, linuxppc-dev,
bpf, Jiri Olsa, Alexei Starovoitov, Hari Bathini
In-Reply-To: <20220210120152.00d24b64@gandalf.local.home>
Steven Rostedt wrote:
> On Thu, 10 Feb 2022 16:40:28 +0000
> "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> wrote:
>
>> The other option is to mark ftrace_cmp_recs() as a __weak function, but
>> I have a vague recollection of you suggesting #ifdef rather than a
>> __weak function in the past. I might be mis-remembering, so if you think
>> making this a __weak function is better, I can do that.
>
> No. If I wanted that I would have suggested it. I think this is the
> prettiest of the ugly solutions out there ;-)
Understood :)
>
> As I said, I can't think of a better solution, and we can go with this
> until something else comes along.
Thanks,
- Naveen
^ permalink raw reply
* Re: [RFC] Upstreaming Linux for Nintendo Wii U
From: Michael Ellerman @ 2022-02-11 11:29 UTC (permalink / raw)
To: Ash Logan, benh, paulus
Cc: linkmauve, linux-usb, linux-kernel, amd-gfx, linuxppc-dev, j.ne
In-Reply-To: <0020d47c-0e23-822c-33f5-ccb7ea4c1072@heyquark.com>
Ash Logan <ash@heyquark.com> writes:
> Hello,
Hi Ash,
I can't really answer all your questions, but I can chime in on one or
two things ...
> - Right now I've made a new platform (like ps3) rather than joining the
> GameCube and Wii in embedded6xx, since that is marked as BROKEN_ON_SMP.
> The Wii U is a 3-core system, though a CPU bug[8] prevents existing
> userspaces working with it. Bit of a "cross that bridge when we get
> there" situation, though I'm reluctant to prevent that possibility by
> using a BROKEN_ON_SMP platform.
I'm happy for it to be a new platform. I'd almost prefer it to be a
separate platform, that way you can make changes in your platform code
without worrying (as much) about breaking other platforms.
> - Like the Wii before it, the Wii U has a small amount of RAM at address
> zero, a gap, then a large amount of RAM at a higher address. Instead of
> the "map everything and reserve the gap" approach of the Wii, we loop
> over each memblock and map only true RAM[9]. This seems to work, but as
> far as I can tell is unique amongst powerpc32 platforms, so it's worth
> pointing out. (Note: I've been told this doesn't work anymore after some
> KUAP changes[10], so this point might be moot; haven't investigated)
We'd need more detail on that I guess. Currently all the 32-bit
platforms use the flat memory model, which assumes RAM is a single
contiguous block. Though that doesn't mean it all has to be used or
mapped, like the Wii does. To properly support your layout you should be
using sparsemem, but it's possible that's more trouble than it's worth,
I'm not sure. How far apart are the low and high blocks of RAM, and what
are their sizes?
> - Due to the aformentioned DMA restrictions and possibly a fatal
> bytemasking bug on uncached mappings[11], I have been wondering if it'd
> be better to just give up on the SRAM at address 0 altogether and use it
> as VRAM or something, loading the kernel at a higher address.
Don't you have exceptions entering down at low addresses? Even so you
could possibly trampoline them up to the kernel at a high address.
> In terms of platform bringup, the key issue is whether to be embedded6xx
> or not and what output device to use. Beyond that it's just things like
> IRQ controller drivers, should be pretty straightforward. I think on our
> end, we'll start rebasing to 5.15 (LTS) and start sending patches from
> there. I know getting closer to HEAD is preferable, this project has
> just moved very slowly in the past and being on LTS has been a lifesaver.
As I said I'm happy for it to be a new platform. If there ends up being
a lot of shared code we can always refactor, but embedded6xx is only
~1500 LOC anyway.
One thing that has come up with previous console port submissions is the
requirement for patches to be signed off. The docs are here if you
aren't familiar with them:
https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin
Otherwise your plan sounds good to me, 4.19 is pretty old so getting up
to 5.15 would be a good start. Then submit whatever bits you can and
chip away at it.
cheers
^ permalink raw reply
* Re: [PATCH v2 1/2] selftest/vm: Use correct PAGE_SHIFT value for ppc64
From: Mike Rapoport @ 2022-02-11 10:33 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: Shuah Khan, linux-mm, linux-kselftest, akpm, linuxppc-dev
In-Reply-To: <20220211063330.99648-1-aneesh.kumar@linux.ibm.com>
On Fri, Feb 11, 2022 at 12:03:28PM +0530, Aneesh Kumar K.V wrote:
> Keep it simple by using a #define and limiting hugepage size to 2M.
> This keeps the test simpler instead of dynamically finding the page size
> and huge page size.
>
> Without this tests are broken w.r.t reading /proc/self/pagemap
>
> if (pread(pagemap_fd, ent, sizeof(ent),
> (uintptr_t)ptr >> (PAGE_SHIFT - 3)) != sizeof(ent))
> err(2, "read pagemap");
>
> Cc: Shuah Khan <shuah@kernel.org>
> Cc: linux-kselftest@vger.kernel.org
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> ---
> tools/testing/selftests/vm/ksm_tests.c | 9 ++++++++-
> tools/testing/selftests/vm/transhuge-stress.c | 9 ++++++++-
> 2 files changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/vm/ksm_tests.c b/tools/testing/selftests/vm/ksm_tests.c
> index 1436e1a9a3d3..cae72872152b 100644
> --- a/tools/testing/selftests/vm/ksm_tests.c
> +++ b/tools/testing/selftests/vm/ksm_tests.c
> @@ -22,7 +22,14 @@
> #define KSM_MERGE_ACROSS_NODES_DEFAULT true
> #define MB (1ul << 20)
>
> -#define PAGE_SHIFT 12
> +#ifdef __powerpc64__
> +#define PAGE_SHIFT 16
> +#else
> +#define PAGE_SHIFT 12
> +#endif
Page size can be other than 4096 for other configurations as well. And even
on ppc64 it's not necessarily 64k.
Ideally page size in selftests/vm should be sysconf(_SC_PAGESIZE)
> +/*
> + * On ppc64 this will only work with radix 2M hugepage size
> + */
> #define HPAGE_SHIFT 21
>
> #define PAGE_SIZE (1 << PAGE_SHIFT)
> diff --git a/tools/testing/selftests/vm/transhuge-stress.c b/tools/testing/selftests/vm/transhuge-stress.c
> index 5e4c036f6ad3..b1f8d98355c5 100644
> --- a/tools/testing/selftests/vm/transhuge-stress.c
> +++ b/tools/testing/selftests/vm/transhuge-stress.c
> @@ -16,7 +16,14 @@
> #include <string.h>
> #include <sys/mman.h>
>
> -#define PAGE_SHIFT 12
> +#ifdef __powerpc64__
> +#define PAGE_SHIFT 16
> +#else
> +#define PAGE_SHIFT 12
> +#endif
> +/*
> + * On ppc64 this will only work with radix 2M hugepage size
> + */
> #define HPAGE_SHIFT 21
>
> #define PAGE_SIZE (1 << PAGE_SHIFT)
> --
> 2.34.1
>
>
--
Sincerely yours,
Mike.
^ permalink raw reply
* [PATCH 1/2] net: Allow csum_sub() to be provided in arch
From: Christophe Leroy @ 2022-02-11 10:24 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
David S. Miller, Jakub Kicinski
Cc: netdev, linuxppc-dev, linux-kernel
In the same spirit as commit 07064c6e022b ("net: Allow csum_add to be
provided in arch"), allow csum_sub() to be provided by arch.
The generic implementation of csum_sub() call csum_add() with the
complement of the addendum.
Some architectures can do it directly.
This will also avoid getting several copies of csum_sub() outlined
when building with -Os.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
include/net/checksum.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/net/checksum.h b/include/net/checksum.h
index 9badcd5532ef..735d98724145 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -62,10 +62,12 @@ static inline __wsum csum_add(__wsum csum, __wsum addend)
}
#endif
+#ifndef HAVE_ARCH_CSUM_SUB
static inline __wsum csum_sub(__wsum csum, __wsum addend)
{
return csum_add(csum, ~addend);
}
+#endif
static inline __sum16 csum16_add(__sum16 csum, __be16 addend)
{
--
2.34.1
^ permalink raw reply related
* [PATCH 2/2] powerpc/32: Implement csum_sub
From: Christophe Leroy @ 2022-02-11 10:24 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
David S. Miller, Jakub Kicinski
Cc: netdev, linuxppc-dev, linux-kernel
In-Reply-To: <0c8eaab8f0685d2a70d125cf876238c70afd4fb6.1644574987.git.christophe.leroy@csgroup.eu>
When building kernel with CONFIG_CC_OPTIMISE_FOR_SIZE, several
copies of csum_sub() are generated, with the following code:
00000170 <csum_sub>:
170: 7c 84 20 f8 not r4,r4
174: 7c 63 20 14 addc r3,r3,r4
178: 7c 63 01 94 addze r3,r3
17c: 4e 80 00 20 blr
Let's define a PPC32 version with subc/addme, and for it's inlining.
It will return 0 instead of 0xffffffff when subtracting 0x80000000 to itself,
this is not an issue as 0 and ~0 are equivalent, refer to RFC 1624.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/checksum.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h
index 350de8f90250..3288a1bf5e8d 100644
--- a/arch/powerpc/include/asm/checksum.h
+++ b/arch/powerpc/include/asm/checksum.h
@@ -112,6 +112,22 @@ static __always_inline __wsum csum_add(__wsum csum, __wsum addend)
#endif
}
+#ifdef CONFIG_PPC32
+#define HAVE_ARCH_CSUM_SUB
+static __always_inline __wsum csum_sub(__wsum csum, __wsum addend)
+{
+ if (__builtin_constant_p(csum) && (csum == 0 || csum == ~0))
+ return ~addend;
+ if (__builtin_constant_p(addend) && (addend == 0 || addend == ~0))
+ return csum;
+
+ asm("subc %0,%0,%1;"
+ "addme %0,%0;"
+ : "+r" (csum) : "r" (addend) : "xer");
+ return csum;
+}
+#endif
+
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries. ihl is the number
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v2] powerpc/mm: Update default hugetlb size early
From: David Hildenbrand @ 2022-02-11 10:05 UTC (permalink / raw)
To: Aneesh Kumar K V, linuxppc-dev, mpe, Christophe Leroy; +Cc: linux-mm
In-Reply-To: <05d6615a-50c7-1b23-1bab-0e0b64dd4e81@linux.ibm.com>
On 11.02.22 10:16, Aneesh Kumar K V wrote:
> On 2/11/22 14:00, David Hildenbrand wrote:
>> On 11.02.22 07:52, Aneesh Kumar K.V wrote:
>>> commit: d9c234005227 ("Do not depend on MAX_ORDER when grouping pages by mobility")
>>> introduced pageblock_order which will be used to group pages better.
>>> The kernel now groups pages based on the value of HPAGE_SHIFT. Hence HPAGE_SHIFT
>>> should be set before we call set_pageblock_order.
>>>
>>> set_pageblock_order happens early in the boot and default hugetlb page size
>>> should be initialized before that to compute the right pageblock_order value.
>>>
>>> Currently, default hugetlbe page size is set via arch_initcalls which happens
>>> late in the boot as shown via the below callstack:
>>>
>>> [c000000007383b10] [c000000001289328] hugetlbpage_init+0x2b8/0x2f8
>>> [c000000007383bc0] [c0000000012749e4] do_one_initcall+0x14c/0x320
>>> [c000000007383c90] [c00000000127505c] kernel_init_freeable+0x410/0x4e8
>>> [c000000007383da0] [c000000000012664] kernel_init+0x30/0x15c
>>> [c000000007383e10] [c00000000000cf14] ret_from_kernel_thread+0x5c/0x64
>>>
>>> and the pageblock_order initialization is done early during the boot.
>>>
>>> [c0000000018bfc80] [c0000000012ae120] set_pageblock_order+0x50/0x64
>>> [c0000000018bfca0] [c0000000012b3d94] sparse_init+0x188/0x268
>>> [c0000000018bfd60] [c000000001288bfc] initmem_init+0x28c/0x328
>>> [c0000000018bfe50] [c00000000127b370] setup_arch+0x410/0x480
>>> [c0000000018bfed0] [c00000000127401c] start_kernel+0xb8/0x934
>>> [c0000000018bff90] [c00000000000d984] start_here_common+0x1c/0x98
>>>
>>> delaying default hugetlb page size initialization implies the kernel will
>>> initialize pageblock_order to (MAX_ORDER - 1) which is not an optimal
>>> value for mobility grouping. IIUC we always had this issue. But it was not
>>> a problem for hash translation mode because (MAX_ORDER - 1) is the same as
>>> HUGETLB_PAGE_ORDER (8) in the case of hash (16MB). With radix,
>>> HUGETLB_PAGE_ORDER will be 5 (2M size) and hence pageblock_order should be
>>> 5 instead of 8.
>>
>>
>> A related question: Can we on ppc still have pageblock_order > MAX_ORDER
>> - 1? We have some code for that and I am not so sure if we really need that.
>>
>
> I also have been wondering about the same. On book3s64 I don't think we
> need that support for both 64K and 4K page size because with hash
> hugetlb size is MAX_ORDER -1. (16MB hugepage size)
>
> I am not sure about the 256K page support. Christophe may be able to
> answer that.
>
> For the gigantic hugepage support we depend on cma based allocation or
> firmware reservation. So I am not sure why we ever considered pageblock
> > MAX_ORDER -1 scenario. If you have pointers w.r.t why that was ever
> needed, I could double-check whether ppc64 is still dependent on that.
commit dc78327c0ea7da5186d8cbc1647bd6088c5c9fa5
Author: Michal Nazarewicz <mina86@mina86.com>
Date: Wed Jul 2 15:22:35 2014 -0700
mm: page_alloc: fix CMA area initialisation when pageblock > MAX_ORDER
indicates that at least arm64 used to have cases for that as well.
However, nowadays with ARM64_64K_PAGES we have FORCE_MAX_ZONEORDER=14 as
default, corresponding to 512MiB.
So I'm not sure if this is something worth supporting. If you want
somewhat reliable gigantic pages, use CMA or preallocate them during boot.
--
Thanks,
David / dhildenb
^ permalink raw reply
* Re: [PATCH v2] powerpc/mm: Update default hugetlb size early
From: Aneesh Kumar K V @ 2022-02-11 9:16 UTC (permalink / raw)
To: David Hildenbrand, linuxppc-dev, mpe, Christophe Leroy; +Cc: linux-mm
In-Reply-To: <831ee5f6-8605-02d2-b7e5-543aec4857c3@redhat.com>
On 2/11/22 14:00, David Hildenbrand wrote:
> On 11.02.22 07:52, Aneesh Kumar K.V wrote:
>> commit: d9c234005227 ("Do not depend on MAX_ORDER when grouping pages by mobility")
>> introduced pageblock_order which will be used to group pages better.
>> The kernel now groups pages based on the value of HPAGE_SHIFT. Hence HPAGE_SHIFT
>> should be set before we call set_pageblock_order.
>>
>> set_pageblock_order happens early in the boot and default hugetlb page size
>> should be initialized before that to compute the right pageblock_order value.
>>
>> Currently, default hugetlbe page size is set via arch_initcalls which happens
>> late in the boot as shown via the below callstack:
>>
>> [c000000007383b10] [c000000001289328] hugetlbpage_init+0x2b8/0x2f8
>> [c000000007383bc0] [c0000000012749e4] do_one_initcall+0x14c/0x320
>> [c000000007383c90] [c00000000127505c] kernel_init_freeable+0x410/0x4e8
>> [c000000007383da0] [c000000000012664] kernel_init+0x30/0x15c
>> [c000000007383e10] [c00000000000cf14] ret_from_kernel_thread+0x5c/0x64
>>
>> and the pageblock_order initialization is done early during the boot.
>>
>> [c0000000018bfc80] [c0000000012ae120] set_pageblock_order+0x50/0x64
>> [c0000000018bfca0] [c0000000012b3d94] sparse_init+0x188/0x268
>> [c0000000018bfd60] [c000000001288bfc] initmem_init+0x28c/0x328
>> [c0000000018bfe50] [c00000000127b370] setup_arch+0x410/0x480
>> [c0000000018bfed0] [c00000000127401c] start_kernel+0xb8/0x934
>> [c0000000018bff90] [c00000000000d984] start_here_common+0x1c/0x98
>>
>> delaying default hugetlb page size initialization implies the kernel will
>> initialize pageblock_order to (MAX_ORDER - 1) which is not an optimal
>> value for mobility grouping. IIUC we always had this issue. But it was not
>> a problem for hash translation mode because (MAX_ORDER - 1) is the same as
>> HUGETLB_PAGE_ORDER (8) in the case of hash (16MB). With radix,
>> HUGETLB_PAGE_ORDER will be 5 (2M size) and hence pageblock_order should be
>> 5 instead of 8.
>
>
> A related question: Can we on ppc still have pageblock_order > MAX_ORDER
> - 1? We have some code for that and I am not so sure if we really need that.
>
I also have been wondering about the same. On book3s64 I don't think we
need that support for both 64K and 4K page size because with hash
hugetlb size is MAX_ORDER -1. (16MB hugepage size)
I am not sure about the 256K page support. Christophe may be able to
answer that.
For the gigantic hugepage support we depend on cma based allocation or
firmware reservation. So I am not sure why we ever considered pageblock
> MAX_ORDER -1 scenario. If you have pointers w.r.t why that was ever
needed, I could double-check whether ppc64 is still dependent on that.
-aneesh
^ permalink raw reply
* [PATCH] powerpc/bitops: Force inlining of fls()
From: Christophe Leroy @ 2022-02-11 8:51 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
Building a kernel with CONFIG_CC_OPTIMISE_FOR_SIZE leads to
the following functions being copied several times in vmlinux:
31 times __ilog2_u32()
34 times fls()
Disassembly follows:
c00f476c <fls>:
c00f476c: 7c 63 00 34 cntlzw r3,r3
c00f4770: 20 63 00 20 subfic r3,r3,32
c00f4774: 4e 80 00 20 blr
c00f4778 <__ilog2_u32>:
c00f4778: 94 21 ff f0 stwu r1,-16(r1)
c00f477c: 7c 08 02 a6 mflr r0
c00f4780: 90 01 00 14 stw r0,20(r1)
c00f4784: 4b ff ff e9 bl c00f476c <fls>
c00f4788: 80 01 00 14 lwz r0,20(r1)
c00f478c: 38 63 ff ff addi r3,r3,-1
c00f4790: 7c 08 03 a6 mtlr r0
c00f4794: 38 21 00 10 addi r1,r1,16
c00f4798: 4e 80 00 20 blr
When forcing inlining of fls(), we get
c0008b80 <__ilog2_u32>:
c0008b80: 7c 63 00 34 cntlzw r3,r3
c0008b84: 20 63 00 1f subfic r3,r3,31
c0008b88: 4e 80 00 20 blr
vmlinux size gets reduced by 1 kbyte with that change.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/bitops.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index f18b1eac6b54..7df7fee774e5 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -288,7 +288,7 @@ static __always_inline void arch___clear_bit_unlock(int nr, volatile unsigned lo
* fls: find last (most-significant) bit set.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
-static inline int fls(unsigned int x)
+static __always_inline int fls(unsigned int x)
{
int lz;
@@ -306,7 +306,7 @@ static inline int fls(unsigned int x)
* 32-bit fls calls.
*/
#ifdef CONFIG_PPC64
-static inline int fls64(__u64 x)
+static __always_inline int fls64(__u64 x)
{
int lz;
--
2.34.1
^ permalink raw reply related
* [PATCH] net: Remove branch in csum_shift()
From: Christophe Leroy @ 2022-02-11 8:48 UTC (permalink / raw)
To: David S. Miller, Jakub Kicinski; +Cc: netdev, linuxppc-dev, linux-kernel
Today's implementation of csum_shift() leads to branching based on
parity of 'offset'
000002f8 <csum_block_add>:
2f8: 70 a5 00 01 andi. r5,r5,1
2fc: 41 a2 00 08 beq 304 <csum_block_add+0xc>
300: 54 84 c0 3e rotlwi r4,r4,24
304: 7c 63 20 14 addc r3,r3,r4
308: 7c 63 01 94 addze r3,r3
30c: 4e 80 00 20 blr
Use first bit of 'offset' directly as input of the rotation instead of
branching.
000002f8 <csum_block_add>:
2f8: 54 a5 1f 38 rlwinm r5,r5,3,28,28
2fc: 20 a5 00 20 subfic r5,r5,32
300: 5c 84 28 3e rotlw r4,r4,r5
304: 7c 63 20 14 addc r3,r3,r4
308: 7c 63 01 94 addze r3,r3
30c: 4e 80 00 20 blr
And change to left shift instead of right shift to skip one more
instruction. This has no impact on the final sum.
000002f8 <csum_block_add>:
2f8: 54 a5 1f 38 rlwinm r5,r5,3,28,28
2fc: 5c 84 28 3e rotlw r4,r4,r5
300: 7c 63 20 14 addc r3,r3,r4
304: 7c 63 01 94 addze r3,r3
308: 4e 80 00 20 blr
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
include/net/checksum.h | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/include/net/checksum.h b/include/net/checksum.h
index 5218041e5c8f..9badcd5532ef 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -83,9 +83,7 @@ static inline __sum16 csum16_sub(__sum16 csum, __be16 addend)
static inline __wsum csum_shift(__wsum sum, int offset)
{
/* rotate sum to align it with a 16b boundary */
- if (offset & 1)
- return (__force __wsum)ror32((__force u32)sum, 8);
- return sum;
+ return (__force __wsum)rol32((__force u32)sum, (offset & 1) << 3);
}
static inline __wsum
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v2] powerpc/mm: Update default hugetlb size early
From: David Hildenbrand @ 2022-02-11 8:30 UTC (permalink / raw)
To: Aneesh Kumar K.V, linuxppc-dev, mpe; +Cc: linux-mm
In-Reply-To: <20220211065215.101767-1-aneesh.kumar@linux.ibm.com>
On 11.02.22 07:52, Aneesh Kumar K.V wrote:
> commit: d9c234005227 ("Do not depend on MAX_ORDER when grouping pages by mobility")
> introduced pageblock_order which will be used to group pages better.
> The kernel now groups pages based on the value of HPAGE_SHIFT. Hence HPAGE_SHIFT
> should be set before we call set_pageblock_order.
>
> set_pageblock_order happens early in the boot and default hugetlb page size
> should be initialized before that to compute the right pageblock_order value.
>
> Currently, default hugetlbe page size is set via arch_initcalls which happens
> late in the boot as shown via the below callstack:
>
> [c000000007383b10] [c000000001289328] hugetlbpage_init+0x2b8/0x2f8
> [c000000007383bc0] [c0000000012749e4] do_one_initcall+0x14c/0x320
> [c000000007383c90] [c00000000127505c] kernel_init_freeable+0x410/0x4e8
> [c000000007383da0] [c000000000012664] kernel_init+0x30/0x15c
> [c000000007383e10] [c00000000000cf14] ret_from_kernel_thread+0x5c/0x64
>
> and the pageblock_order initialization is done early during the boot.
>
> [c0000000018bfc80] [c0000000012ae120] set_pageblock_order+0x50/0x64
> [c0000000018bfca0] [c0000000012b3d94] sparse_init+0x188/0x268
> [c0000000018bfd60] [c000000001288bfc] initmem_init+0x28c/0x328
> [c0000000018bfe50] [c00000000127b370] setup_arch+0x410/0x480
> [c0000000018bfed0] [c00000000127401c] start_kernel+0xb8/0x934
> [c0000000018bff90] [c00000000000d984] start_here_common+0x1c/0x98
>
> delaying default hugetlb page size initialization implies the kernel will
> initialize pageblock_order to (MAX_ORDER - 1) which is not an optimal
> value for mobility grouping. IIUC we always had this issue. But it was not
> a problem for hash translation mode because (MAX_ORDER - 1) is the same as
> HUGETLB_PAGE_ORDER (8) in the case of hash (16MB). With radix,
> HUGETLB_PAGE_ORDER will be 5 (2M size) and hence pageblock_order should be
> 5 instead of 8.
A related question: Can we on ppc still have pageblock_order > MAX_ORDER
- 1? We have some code for that and I am not so sure if we really need that.
--
Thanks,
David / dhildenb
^ permalink raw reply
* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
From: Segher Boessenkool @ 2022-02-11 7:39 UTC (permalink / raw)
To: Kees Cook
Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
Greg Kroah-Hartman, Helge Deller, linux-kernel,
James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
linuxppc-dev
In-Reply-To: <202202101653.9128E58B84@keescook>
On Thu, Feb 10, 2022 at 04:54:52PM -0800, Kees Cook wrote:
> On Sun, Oct 17, 2021 at 02:38:17PM +0200, Christophe Leroy wrote:
(edited:)
> > +typedef struct {
> > + unsigned long addr;
> > +} func_desc_t;
> >
> > static func_desc_t func_desc(unsigned long addr)
> > {
> > + return (func_desc_t){addr};
> There's only 1 element in the struct, so okay, but it hurt my eyes a
> little. I would have been happier with:
>
> return (func_desc_t){ .addr = addr; };
>
> But of course that also looks bonkers because it starts with "return".
> So no matter what I do my eyes bug out. ;)
The usual way to avoid convoluted constructs is to name more factors.
So:
static func_desc_t func_desc(unsigned long addr)
{
func_desc_t desc = {};
desc.addr = addr;
return desc;
}
Segher
^ permalink raw reply
* [PATCH] Fixup for next-test 3a1a8f078670 ("powerpc/ftrace: Remove ftrace_32.S")
From: Christophe Leroy @ 2022-02-11 7:41 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <5e837fc190504c4ef834272e70d60ae33f175d49.1640017960.git.christophe.leroy@csgroup.eu>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/trace/Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/trace/Makefile b/arch/powerpc/kernel/trace/Makefile
index ac7d42a4e8d0..542aa7a8b2b4 100644
--- a/arch/powerpc/kernel/trace/Makefile
+++ b/arch/powerpc/kernel/trace/Makefile
@@ -14,8 +14,9 @@ obj64-$(CONFIG_FUNCTION_TRACER) += ftrace_mprofile.o
else
obj64-$(CONFIG_FUNCTION_TRACER) += ftrace_64_pg.o
endif
+obj-$(CONFIG_FUNCTION_TRACER) += ftrace_low.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o ftrace_low.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
obj-$(CONFIG_TRACING) += trace_clock.o
--
2.34.1
^ permalink raw reply related
* [PATCH v2] powerpc/mm: Update default hugetlb size early
From: Aneesh Kumar K.V @ 2022-02-11 6:52 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: linux-mm, Aneesh Kumar K.V
commit: d9c234005227 ("Do not depend on MAX_ORDER when grouping pages by mobility")
introduced pageblock_order which will be used to group pages better.
The kernel now groups pages based on the value of HPAGE_SHIFT. Hence HPAGE_SHIFT
should be set before we call set_pageblock_order.
set_pageblock_order happens early in the boot and default hugetlb page size
should be initialized before that to compute the right pageblock_order value.
Currently, default hugetlbe page size is set via arch_initcalls which happens
late in the boot as shown via the below callstack:
[c000000007383b10] [c000000001289328] hugetlbpage_init+0x2b8/0x2f8
[c000000007383bc0] [c0000000012749e4] do_one_initcall+0x14c/0x320
[c000000007383c90] [c00000000127505c] kernel_init_freeable+0x410/0x4e8
[c000000007383da0] [c000000000012664] kernel_init+0x30/0x15c
[c000000007383e10] [c00000000000cf14] ret_from_kernel_thread+0x5c/0x64
and the pageblock_order initialization is done early during the boot.
[c0000000018bfc80] [c0000000012ae120] set_pageblock_order+0x50/0x64
[c0000000018bfca0] [c0000000012b3d94] sparse_init+0x188/0x268
[c0000000018bfd60] [c000000001288bfc] initmem_init+0x28c/0x328
[c0000000018bfe50] [c00000000127b370] setup_arch+0x410/0x480
[c0000000018bfed0] [c00000000127401c] start_kernel+0xb8/0x934
[c0000000018bff90] [c00000000000d984] start_here_common+0x1c/0x98
delaying default hugetlb page size initialization implies the kernel will
initialize pageblock_order to (MAX_ORDER - 1) which is not an optimal
value for mobility grouping. IIUC we always had this issue. But it was not
a problem for hash translation mode because (MAX_ORDER - 1) is the same as
HUGETLB_PAGE_ORDER (8) in the case of hash (16MB). With radix,
HUGETLB_PAGE_ORDER will be 5 (2M size) and hence pageblock_order should be
5 instead of 8.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/include/asm/hugetlb.h | 5 ++++-
arch/powerpc/mm/book3s64/hugetlbpage.c | 2 +-
arch/powerpc/mm/hugetlbpage.c | 5 +----
arch/powerpc/mm/init_64.c | 4 ++++
4 files changed, 10 insertions(+), 6 deletions(-)
Changes from v1:
* update commit message
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 962708fa1017..6a1a1ac5743b 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -15,7 +15,7 @@
extern bool hugetlb_disabled;
-void __init hugetlbpage_init_default(void);
+void __init hugetlbpage_init_defaultsize(void);
int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
unsigned long len);
@@ -76,6 +76,9 @@ static inline void __init gigantic_hugetlb_cma_reserve(void)
{
}
+static inline void __init hugetlbpage_init_defaultsize(void)
+{
+}
#endif /* CONFIG_HUGETLB_PAGE */
#endif /* _ASM_POWERPC_HUGETLB_H */
diff --git a/arch/powerpc/mm/book3s64/hugetlbpage.c b/arch/powerpc/mm/book3s64/hugetlbpage.c
index ea8f83afb0ae..3bc0eb21b2a0 100644
--- a/arch/powerpc/mm/book3s64/hugetlbpage.c
+++ b/arch/powerpc/mm/book3s64/hugetlbpage.c
@@ -150,7 +150,7 @@ void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr
set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
}
-void __init hugetlbpage_init_default(void)
+void __init hugetlbpage_init_defaultsize(void)
{
/* Set default large page size. Currently, we pick 16M or 1M
* depending on what is available
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index ddead41e2194..b642a5a8668f 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -664,10 +664,7 @@ static int __init hugetlbpage_init(void)
configured = true;
}
- if (configured) {
- if (IS_ENABLED(CONFIG_HUGETLB_PAGE_SIZE_VARIABLE))
- hugetlbpage_init_default();
- } else
+ if (!configured)
pr_info("Failed to initialize. Disabling HugeTLB");
return 0;
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 35f46bf54281..83c0ee9fbf05 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -59,6 +59,7 @@
#include <asm/sections.h>
#include <asm/iommu.h>
#include <asm/vdso.h>
+#include <asm/hugetlb.h>
#include <mm/mmu_decl.h>
@@ -513,6 +514,9 @@ void __init mmu_early_init_devtree(void)
} else
hash__early_init_devtree();
+ if (IS_ENABLED(CONFIG_HUGETLB_PAGE_SIZE_VARIABLE))
+ hugetlbpage_init_defaultsize();
+
if (!(cur_cpu_spec->mmu_features & MMU_FTR_HPTE_TABLE) &&
!(cur_cpu_spec->mmu_features & MMU_FTR_TYPE_RADIX))
panic("kernel does not support any MMU type offered by platform");
--
2.34.1
^ permalink raw reply related
* Re: [PATCH kernel 3/3] powerpc/llvm/lto: Workaround conditional branches in FTR_SECTION_ELSE
From: Russell Currey @ 2022-02-11 6:44 UTC (permalink / raw)
To: Alexey Kardashevskiy, llvm
Cc: Nathan Lynch, Fabiano Rosas, Nick Desaulniers, Nicholas Piggin,
Nathan Chancellor, Joel Stanley, Naveen N. Rao, linuxppc-dev,
Daniel Axtens
In-Reply-To: <20220211023125.1790960-4-aik@ozlabs.ru>
On Fri, 2022-02-11 at 13:31 +1100, Alexey Kardashevskiy wrote:
> diff --git a/arch/powerpc/lib/memcpy_64.S
> b/arch/powerpc/lib/memcpy_64.S
> index 016c91e958d8..286c7e2d0883 100644
> --- a/arch/powerpc/lib/memcpy_64.S
> +++ b/arch/powerpc/lib/memcpy_64.S
> @@ -50,10 +50,11 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
> At the time of writing the only CPU that has this combination of
> bits
> set is Power6. */
> test_feature = (SELFTEST_CASE == 1)
> + beq .ldst_aligned
Hey Alexey, typo here (should be .Ldst_aligned) that breaks the build
for BE.
> BEGIN_FTR_SECTION
> nop
^ permalink raw reply
* [PATCH v2 2/2] selftest/vm: Add util.h and and move helper functions there
From: Aneesh Kumar K.V @ 2022-02-11 6:33 UTC (permalink / raw)
To: linux-mm, akpm
Cc: Shuah Khan, linuxppc-dev, linux-kselftest, Aneesh Kumar K.V
In-Reply-To: <20220211063330.99648-1-aneesh.kumar@linux.ibm.com>
Avoid code duplication by adding util.h
Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-kselftest@vger.kernel.org
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
tools/testing/selftests/vm/ksm_tests.c | 45 +---------------
tools/testing/selftests/vm/transhuge-stress.c | 49 ++---------------
tools/testing/selftests/vm/util.h | 54 +++++++++++++++++++
3 files changed, 58 insertions(+), 90 deletions(-)
create mode 100644 tools/testing/selftests/vm/util.h
diff --git a/tools/testing/selftests/vm/ksm_tests.c b/tools/testing/selftests/vm/ksm_tests.c
index cae72872152b..fd85f15869d1 100644
--- a/tools/testing/selftests/vm/ksm_tests.c
+++ b/tools/testing/selftests/vm/ksm_tests.c
@@ -12,6 +12,7 @@
#include "../kselftest.h"
#include "../../../../include/vdso/time64.h"
+#include "util.h"
#define KSM_SYSFS_PATH "/sys/kernel/mm/ksm/"
#define KSM_FP(s) (KSM_SYSFS_PATH s)
@@ -22,22 +23,6 @@
#define KSM_MERGE_ACROSS_NODES_DEFAULT true
#define MB (1ul << 20)
-#ifdef __powerpc64__
-#define PAGE_SHIFT 16
-#else
-#define PAGE_SHIFT 12
-#endif
-/*
- * On ppc64 this will only work with radix 2M hugepage size
- */
-#define HPAGE_SHIFT 21
-
-#define PAGE_SIZE (1 << PAGE_SHIFT)
-#define HPAGE_SIZE (1 << HPAGE_SHIFT)
-
-#define PAGEMAP_PRESENT(ent) (((ent) & (1ull << 63)) != 0)
-#define PAGEMAP_PFN(ent) ((ent) & ((1ull << 55) - 1))
-
struct ksm_sysfs {
unsigned long max_page_sharing;
unsigned long merge_across_nodes;
@@ -463,34 +448,6 @@ static int check_ksm_numa_merge(int mapping, int prot, int timeout, bool merge_a
return KSFT_FAIL;
}
-int64_t allocate_transhuge(void *ptr, int pagemap_fd)
-{
- uint64_t ent[2];
-
- /* drop pmd */
- if (mmap(ptr, HPAGE_SIZE, PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_ANONYMOUS |
- MAP_NORESERVE | MAP_PRIVATE, -1, 0) != ptr)
- errx(2, "mmap transhuge");
-
- if (madvise(ptr, HPAGE_SIZE, MADV_HUGEPAGE))
- err(2, "MADV_HUGEPAGE");
-
- /* allocate transparent huge page */
- *(volatile void **)ptr = ptr;
-
- if (pread(pagemap_fd, ent, sizeof(ent),
- (uintptr_t)ptr >> (PAGE_SHIFT - 3)) != sizeof(ent))
- err(2, "read pagemap");
-
- if (PAGEMAP_PRESENT(ent[0]) && PAGEMAP_PRESENT(ent[1]) &&
- PAGEMAP_PFN(ent[0]) + 1 == PAGEMAP_PFN(ent[1]) &&
- !(PAGEMAP_PFN(ent[0]) & ((1 << (HPAGE_SHIFT - PAGE_SHIFT)) - 1)))
- return PAGEMAP_PFN(ent[0]);
-
- return -1;
-}
-
static int ksm_merge_hugepages_time(int mapping, int prot, int timeout, size_t map_size)
{
void *map_ptr, *map_ptr_orig;
diff --git a/tools/testing/selftests/vm/transhuge-stress.c b/tools/testing/selftests/vm/transhuge-stress.c
index b1f8d98355c5..0da4aa10746a 100644
--- a/tools/testing/selftests/vm/transhuge-stress.c
+++ b/tools/testing/selftests/vm/transhuge-stress.c
@@ -16,51 +16,7 @@
#include <string.h>
#include <sys/mman.h>
-#ifdef __powerpc64__
-#define PAGE_SHIFT 16
-#else
-#define PAGE_SHIFT 12
-#endif
-/*
- * On ppc64 this will only work with radix 2M hugepage size
- */
-#define HPAGE_SHIFT 21
-
-#define PAGE_SIZE (1 << PAGE_SHIFT)
-#define HPAGE_SIZE (1 << HPAGE_SHIFT)
-
-#define PAGEMAP_PRESENT(ent) (((ent) & (1ull << 63)) != 0)
-#define PAGEMAP_PFN(ent) ((ent) & ((1ull << 55) - 1))
-
-int pagemap_fd;
-
-int64_t allocate_transhuge(void *ptr)
-{
- uint64_t ent[2];
-
- /* drop pmd */
- if (mmap(ptr, HPAGE_SIZE, PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_ANONYMOUS |
- MAP_NORESERVE | MAP_PRIVATE, -1, 0) != ptr)
- errx(2, "mmap transhuge");
-
- if (madvise(ptr, HPAGE_SIZE, MADV_HUGEPAGE))
- err(2, "MADV_HUGEPAGE");
-
- /* allocate transparent huge page */
- *(volatile void **)ptr = ptr;
-
- if (pread(pagemap_fd, ent, sizeof(ent),
- (uintptr_t)ptr >> (PAGE_SHIFT - 3)) != sizeof(ent))
- err(2, "read pagemap");
-
- if (PAGEMAP_PRESENT(ent[0]) && PAGEMAP_PRESENT(ent[1]) &&
- PAGEMAP_PFN(ent[0]) + 1 == PAGEMAP_PFN(ent[1]) &&
- !(PAGEMAP_PFN(ent[0]) & ((1 << (HPAGE_SHIFT - PAGE_SHIFT)) - 1)))
- return PAGEMAP_PFN(ent[0]);
-
- return -1;
-}
+#include "util.h"
int main(int argc, char **argv)
{
@@ -70,6 +26,7 @@ int main(int argc, char **argv)
double s;
uint8_t *map;
size_t map_len;
+ int pagemap_fd;
ram = sysconf(_SC_PHYS_PAGES);
if (ram > SIZE_MAX / sysconf(_SC_PAGESIZE) / 4)
@@ -116,7 +73,7 @@ int main(int argc, char **argv)
for (p = ptr; p < ptr + len; p += HPAGE_SIZE) {
int64_t pfn;
- pfn = allocate_transhuge(p);
+ pfn = allocate_transhuge(p, pagemap_fd);
if (pfn < 0) {
nr_failed++;
diff --git a/tools/testing/selftests/vm/util.h b/tools/testing/selftests/vm/util.h
new file mode 100644
index 000000000000..8ec94940371f
--- /dev/null
+++ b/tools/testing/selftests/vm/util.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __KSELFTEST_VM_UTIL_H
+#define __KSELFTEST_VM_UTIL_H
+
+#include <sys/mman.h>
+#include <err.h>
+
+#ifdef __powerpc64__
+#define PAGE_SHIFT 16
+#else
+#define PAGE_SHIFT 12
+#endif
+/*
+ * On ppc64 this will only work with radix 2M hugepage size
+ */
+#define HPAGE_SHIFT 21
+
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#define HPAGE_SIZE (1 << HPAGE_SHIFT)
+
+#define PAGEMAP_PRESENT(ent) (((ent) & (1ull << 63)) != 0)
+#define PAGEMAP_PFN(ent) ((ent) & ((1ull << 55) - 1))
+
+
+static inline int64_t allocate_transhuge(void *ptr, int pagemap_fd)
+{
+ uint64_t ent[2];
+
+ /* drop pmd */
+ if (mmap(ptr, HPAGE_SIZE, PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_ANONYMOUS |
+ MAP_NORESERVE | MAP_PRIVATE, -1, 0) != ptr)
+ errx(2, "mmap transhuge");
+
+ if (madvise(ptr, HPAGE_SIZE, MADV_HUGEPAGE))
+ err(2, "MADV_HUGEPAGE");
+
+ /* allocate transparent huge page */
+ *(volatile void **)ptr = ptr;
+
+ if (pread(pagemap_fd, ent, sizeof(ent),
+ (uintptr_t)ptr >> (PAGE_SHIFT - 3)) != sizeof(ent))
+ err(2, "read pagemap");
+
+ if (PAGEMAP_PRESENT(ent[0]) && PAGEMAP_PRESENT(ent[1]) &&
+ PAGEMAP_PFN(ent[0]) + 1 == PAGEMAP_PFN(ent[1]) &&
+ !(PAGEMAP_PFN(ent[0]) & ((1 << (HPAGE_SHIFT - PAGE_SHIFT)) - 1)))
+ return PAGEMAP_PFN(ent[0]);
+
+ return -1;
+}
+
+#endif
--
2.34.1
^ permalink raw reply related
* [PATCH v2 1/2] selftest/vm: Use correct PAGE_SHIFT value for ppc64
From: Aneesh Kumar K.V @ 2022-02-11 6:33 UTC (permalink / raw)
To: linux-mm, akpm
Cc: Shuah Khan, linuxppc-dev, linux-kselftest, Aneesh Kumar K.V
Keep it simple by using a #define and limiting hugepage size to 2M.
This keeps the test simpler instead of dynamically finding the page size
and huge page size.
Without this tests are broken w.r.t reading /proc/self/pagemap
if (pread(pagemap_fd, ent, sizeof(ent),
(uintptr_t)ptr >> (PAGE_SHIFT - 3)) != sizeof(ent))
err(2, "read pagemap");
Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-kselftest@vger.kernel.org
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
tools/testing/selftests/vm/ksm_tests.c | 9 ++++++++-
tools/testing/selftests/vm/transhuge-stress.c | 9 ++++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/vm/ksm_tests.c b/tools/testing/selftests/vm/ksm_tests.c
index 1436e1a9a3d3..cae72872152b 100644
--- a/tools/testing/selftests/vm/ksm_tests.c
+++ b/tools/testing/selftests/vm/ksm_tests.c
@@ -22,7 +22,14 @@
#define KSM_MERGE_ACROSS_NODES_DEFAULT true
#define MB (1ul << 20)
-#define PAGE_SHIFT 12
+#ifdef __powerpc64__
+#define PAGE_SHIFT 16
+#else
+#define PAGE_SHIFT 12
+#endif
+/*
+ * On ppc64 this will only work with radix 2M hugepage size
+ */
#define HPAGE_SHIFT 21
#define PAGE_SIZE (1 << PAGE_SHIFT)
diff --git a/tools/testing/selftests/vm/transhuge-stress.c b/tools/testing/selftests/vm/transhuge-stress.c
index 5e4c036f6ad3..b1f8d98355c5 100644
--- a/tools/testing/selftests/vm/transhuge-stress.c
+++ b/tools/testing/selftests/vm/transhuge-stress.c
@@ -16,7 +16,14 @@
#include <string.h>
#include <sys/mman.h>
-#define PAGE_SHIFT 12
+#ifdef __powerpc64__
+#define PAGE_SHIFT 16
+#else
+#define PAGE_SHIFT 12
+#endif
+/*
+ * On ppc64 this will only work with radix 2M hugepage size
+ */
#define HPAGE_SHIFT 21
#define PAGE_SIZE (1 << PAGE_SHIFT)
--
2.34.1
^ permalink raw reply related
* [PATCH v2] mm/hugetlb: Fix kernel crash with hugetlb mremap
From: Aneesh Kumar K.V @ 2022-02-11 6:32 UTC (permalink / raw)
To: linux-mm, akpm
Cc: Mina Almasry, stable, Aneesh Kumar K.V, linuxppc-dev,
Mike Kravetz
This fixes the below crash:
kernel BUG at include/linux/mm.h:2373!
cpu 0x5d: Vector: 700 (Program Check) at [c00000003c6e76e0]
pc: c000000000581a54: pmd_to_page+0x54/0x80
lr: c00000000058d184: move_hugetlb_page_tables+0x4e4/0x5b0
sp: c00000003c6e7980
msr: 9000000000029033
current = 0xc00000003bd8d980
paca = 0xc000200fff610100 irqmask: 0x03 irq_happened: 0x01
pid = 9349, comm = hugepage-mremap
kernel BUG at include/linux/mm.h:2373!
[link register ] c00000000058d184 move_hugetlb_page_tables+0x4e4/0x5b0
[c00000003c6e7980] c00000000058cecc move_hugetlb_page_tables+0x22c/0x5b0 (unreliable)
[c00000003c6e7a90] c00000000053b78c move_page_tables+0xdbc/0x1010
[c00000003c6e7bd0] c00000000053bc34 move_vma+0x254/0x5f0
[c00000003c6e7c90] c00000000053c790 sys_mremap+0x7c0/0x900
[c00000003c6e7db0] c00000000002c450 system_call_exception+0x160/0x2c0
the kernel can't use huge_pte_offset before it set the pte entry because a page table
lookup check for huge PTE bit in the page table to differentiate between a
huge pte entry and a pointer to pte page. A huge_pte_alloc won't mark the
page table entry huge and hence kernel should not use huge_pte_offset after
a huge_pte_alloc.
Fixes: 550a7d60bd5e ("mm, hugepages: add mremap() support for hugepage backed vma")
Cc: stable@vger.kernel.org
Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
Reviewed-by: Mina Almasry <almasrymina@google.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
mm/hugetlb.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
Changes from v1:
* Add Fixes: tag
* Add Reviewed-by:
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 61895cc01d09..e57650a9404f 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -4851,14 +4851,13 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
}
static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
- unsigned long new_addr, pte_t *src_pte)
+ unsigned long new_addr, pte_t *src_pte, pte_t *dst_pte)
{
struct hstate *h = hstate_vma(vma);
struct mm_struct *mm = vma->vm_mm;
- pte_t *dst_pte, pte;
spinlock_t *src_ptl, *dst_ptl;
+ pte_t pte;
- dst_pte = huge_pte_offset(mm, new_addr, huge_page_size(h));
dst_ptl = huge_pte_lock(h, mm, dst_pte);
src_ptl = huge_pte_lockptr(h, mm, src_pte);
@@ -4917,7 +4916,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma,
if (!dst_pte)
break;
- move_huge_pte(vma, old_addr, new_addr, src_pte);
+ move_huge_pte(vma, old_addr, new_addr, src_pte, dst_pte);
}
flush_tlb_range(vma, old_end - len, old_end);
mmu_notifier_invalidate_range_end(&range);
--
2.34.1
^ permalink raw reply related
* Re: [PATCH 3/3] crypto/nx: Constify static attribute_group structs
From: Daniel Axtens @ 2022-02-11 6:27 UTC (permalink / raw)
To: Rikard Falkeborn, Herbert Xu, David S. Miller, Michael Ellerman,
Benjamin Herrenschmidt, Paul Mackerras
Cc: linuxppc-dev, linux-crypto, Rikard Falkeborn, linux-kernel
In-Reply-To: <20220210202805.7750-4-rikard.falkeborn@gmail.com>
Hi Rikard,
> The only usage of these is to pass their address to
> sysfs_{create,remove}_group(), which takes pointers to const struct
> attribute_group. Make them const to allow the compiler to put them in
> read-only memory.
I checked the file. Indeed, those structs are only used in
sysfs_{create,remove}_group. So I agree that they can be constified.
They also pass all the automated tests:
https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20220210202805.7750-4-rikard.falkeborn@gmail.com/
Reviewed-by: Daniel Axtens <dja@axtens.net>
Kind regards,
Daniel
>
> Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com>
> ---
> drivers/crypto/nx/nx-common-pseries.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/crypto/nx/nx-common-pseries.c b/drivers/crypto/nx/nx-common-pseries.c
> index 4e304f6081e4..7584a34ba88c 100644
> --- a/drivers/crypto/nx/nx-common-pseries.c
> +++ b/drivers/crypto/nx/nx-common-pseries.c
> @@ -962,7 +962,7 @@ static struct attribute *nx842_sysfs_entries[] = {
> NULL,
> };
>
> -static struct attribute_group nx842_attribute_group = {
> +static const struct attribute_group nx842_attribute_group = {
> .name = NULL, /* put in device directory */
> .attrs = nx842_sysfs_entries,
> };
> @@ -992,7 +992,7 @@ static struct attribute *nxcop_caps_sysfs_entries[] = {
> NULL,
> };
>
> -static struct attribute_group nxcop_caps_attr_group = {
> +static const struct attribute_group nxcop_caps_attr_group = {
> .name = "nx_gzip_caps",
> .attrs = nxcop_caps_sysfs_entries,
> };
> --
> 2.35.1
^ permalink raw reply
* Re: [PATCH 38/49] arch/powerpc: replace cpumask_weight with cpumask_weight_{eq, ...} where appropriate
From: Michael Ellerman @ 2022-02-11 4:10 UTC (permalink / raw)
To: Yury Norov, Yury Norov, Andy Shevchenko, Rasmus Villemoes,
Andrew Morton, Michał Mirosław, Greg Kroah-Hartman,
Peter Zijlstra, David Laight, Joe Perches, Dennis Zhou,
Emil Renner Berthing, Nicholas Piggin, Matti Vaittinen,
Alexey Klimov, linux-kernel, Benjamin Herrenschmidt,
Paul Mackerras, Srikar Dronamraju, Gautham R. Shenoy,
Valentin Schneider, Parth Shah, Cédric Le Goater,
Hari Bathini, Rob Herring, Laurent Dufour, Petr Mladek,
John Ogness, Sudeep Holla, Christophe Leroy, Naveen N. Rao,
Xiongwei Song, Arnd Bergmann, linuxppc-dev
In-Reply-To: <20220210224933.379149-39-yury.norov@gmail.com>
Yury Norov <yury.norov@gmail.com> writes:
> PowerPC code uses cpumask_weight() to compare the weight of cpumask with
> a given number. We can do it more efficiently with cpumask_weight_{eq, ...}
> because conditional cpumask_weight may stop traversing the cpumask earlier,
> as soon as condition is (or can't be) met.
>
> Signed-off-by: Yury Norov <yury.norov@gmail.com>
> ---
> arch/powerpc/kernel/smp.c | 2 +-
> arch/powerpc/kernel/watchdog.c | 2 +-
> arch/powerpc/xmon/xmon.c | 4 ++--
> 3 files changed, 4 insertions(+), 4 deletions(-)
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
cheers
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox