2019-10-16 01:47:59

by Vineet Gupta

[permalink] [raw]
Subject: [PATCH v2 1/5] ARC: mm: remove __ARCH_USE_5LEVEL_HACK

Add the intermedivmlinux-A-baseline vmlinux-B-elide-ARCH_USE_5LEVEL_HACK

This is a non-functional change anyways since ARC has software page walker
with 2 lookup levels (pgd -> pte)

There is slight code bloat due to pulling in needless p*d_free_tlb()
macros which needs to be addressed seperately.

| bloat-o-meter2 vmlinux-with-5LEVEL_HACK vmlinux-patched
| add/remove: 0/0 grow/shrink: 2/0 up/down: 128/0 (128)
| function old new delta
| free_pgd_range 546 656 +110
| p4d_clear_bad 2 20 +18
| Total: Before=4137148, After=4137276, chg 0.000000%

Cc: Kirill A. Shutemov <[email protected]>
Signed-off-by: Vineet Gupta <[email protected]>
---
arch/arc/include/asm/pgtable.h | 1 -
arch/arc/mm/fault.c | 10 ++++++++--
arch/arc/mm/highmem.c | 4 +++-
3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 7addd0301c51..b917b596f7fb 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -33,7 +33,6 @@
#define _ASM_ARC_PGTABLE_H

#include <linux/bits.h>
-#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>
#include <asm/page.h>
#include <asm/mmu.h> /* to propagate CONFIG_ARC_MMU_VER <n> */
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index 3861543b66a0..fb86bc3e9b35 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -30,6 +30,7 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
* with the 'reference' page table.
*/
pgd_t *pgd, *pgd_k;
+ p4d_t *p4d, *p4d_k;
pud_t *pud, *pud_k;
pmd_t *pmd, *pmd_k;

@@ -39,8 +40,13 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
if (!pgd_present(*pgd_k))
goto bad_area;

- pud = pud_offset(pgd, address);
- pud_k = pud_offset(pgd_k, address);
+ p4d = p4d_offset(pgd, address);
+ p4d_k = p4d_offset(pgd_k, address);
+ if (!p4d_present(*p4d_k))
+ goto bad_area;
+
+ pud = pud_offset(p4d, address);
+ pud_k = pud_offset(p4d_k, address);
if (!pud_present(*pud_k))
goto bad_area;

diff --git a/arch/arc/mm/highmem.c b/arch/arc/mm/highmem.c
index a4856bfaedf3..fc8849e4f72e 100644
--- a/arch/arc/mm/highmem.c
+++ b/arch/arc/mm/highmem.c
@@ -111,12 +111,14 @@ EXPORT_SYMBOL(__kunmap_atomic);
static noinline pte_t * __init alloc_kmap_pgtable(unsigned long kvaddr)
{
pgd_t *pgd_k;
+ p4d_t *p4d_k;
pud_t *pud_k;
pmd_t *pmd_k;
pte_t *pte_k;

pgd_k = pgd_offset_k(kvaddr);
- pud_k = pud_offset(pgd_k, kvaddr);
+ p4d_k = p4d_offset(pgd_k, kvaddr);
+ pud_k = pud_offset(p4d_k, kvaddr);
pmd_k = pmd_offset(pud_k, kvaddr);

pte_k = (pte_t *)memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
--
2.20.1


2019-10-16 07:21:19

by Linus Torvalds

[permalink] [raw]
Subject: Re: [PATCH v2 1/5] ARC: mm: remove __ARCH_USE_5LEVEL_HACK

On Tue, Oct 15, 2019 at 12:19 PM Vineet Gupta
<[email protected]> wrote:
>
> This is a non-functional change anyways since ARC has software page walker
> with 2 lookup levels (pgd -> pte)

Could we encourage other architectures to do the same, and get rid of
all uses of __ARCH_USE_5LEVEL_HACK?

Linus

2019-10-16 07:24:38

by Vineet Gupta

[permalink] [raw]
Subject: Re: [PATCH v2 1/5] ARC: mm: remove __ARCH_USE_5LEVEL_HACK

On 10/15/19 2:48 PM, Linus Torvalds wrote:
> On Tue, Oct 15, 2019 at 12:19 PM Vineet Gupta
> <[email protected]> wrote:
>> This is a non-functional change anyways since ARC has software page walker
>> with 2 lookup levels (pgd -> pte)
>
> Could we encourage other architectures to do the same, and get rid of
> all uses of __ARCH_USE_5LEVEL_HACK?

IMHO this should have been done at the onset. The actual changes don't seem that
difficult, just need to add the missing p4d calls although I can sympathize with
hassles of coordinating/building/testing/yadi yada cross arch.

OTOH, the [45]LEVEL_HACK seem like a nice way to "fold" the levels: the
skipped/folded level vanishes completely. Among others it does things like

#define p4d_t pgd_t

On ARC 2-level code:

free_pte_range
pmd_pgtable(*pmd);

((((((*pmd).pud).pgd))) & PAGE_MASK)); <-- 5LEVEL_HACK
vs.
((((((((*pmd).pud).p4d).pgd)))) & PAGE_MASK )); <-- w/o 5LEVEL_HACK

pmd_clear(pmd);

*(pmd)).pud).pgd)))) = 0
vs.
*(pmd)).pud).p4d).pgd)))) = 0


So we may not be able to fix all he historical misgivigs, but this might alleviate
the pain a bit. I'll try to dabble a bit.

Thx for taking a look and te ACKs.
-Vineet