* [PATCH v3 1/3] arm64: mm: use appropriate ctors for page tables
@ 2019-03-10 1:19 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-10 1:19 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: linux-arch, Yu Zhao, Ard Biesheuvel, Peter Zijlstra,
linux-kernel, Nick Piggin, Jun Yao, linux-mm, Aneesh Kumar K . V,
Chintan Pandya, Joel Fernandes, Kirill A . Shutemov,
Andrew Morton, Laura Abbott, linux-arm-kernel
For pte page, use pgtable_page_ctor(); for pmd page, use
pgtable_pmd_page_ctor(); and for the rest (pud, p4d and pgd),
don't use any.
For now, we don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK and
pgtable_pmd_page_ctor() is a nop. When we do in patch 3, we
make sure pmd is not folded so we won't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index b6f5aa52ac67..f704b291f2c5 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -98,7 +98,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
}
EXPORT_SYMBOL(phys_mem_access_prot);
-static phys_addr_t __init early_pgtable_alloc(void)
+static phys_addr_t __init early_pgtable_alloc(int shift)
{
phys_addr_t phys;
void *ptr;
@@ -173,7 +173,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -183,7 +183,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
if (pmd_none(pmd)) {
phys_addr_t pte_phys;
BUG_ON(!pgtable_alloc);
- pte_phys = pgtable_alloc();
+ pte_phys = pgtable_alloc(PAGE_SHIFT);
__pmd_populate(pmdp, pte_phys, PMD_TYPE_TABLE);
pmd = READ_ONCE(*pmdp);
}
@@ -207,7 +207,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pmd_t *pmdp;
@@ -245,7 +245,7 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pud_t pud = READ_ONCE(*pudp);
@@ -257,7 +257,7 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
if (pud_none(pud)) {
phys_addr_t pmd_phys;
BUG_ON(!pgtable_alloc);
- pmd_phys = pgtable_alloc();
+ pmd_phys = pgtable_alloc(PMD_SHIFT);
__pud_populate(pudp, pmd_phys, PUD_TYPE_TABLE);
pud = READ_ONCE(*pudp);
}
@@ -293,7 +293,7 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -303,7 +303,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
if (pgd_none(pgd)) {
phys_addr_t pud_phys;
BUG_ON(!pgtable_alloc);
- pud_phys = pgtable_alloc();
+ pud_phys = pgtable_alloc(PUD_SHIFT);
__pgd_populate(pgdp, pud_phys, PUD_TYPE_TABLE);
pgd = READ_ONCE(*pgdp);
}
@@ -344,7 +344,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long addr, length, end, next;
@@ -370,11 +370,23 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
-static phys_addr_t pgd_pgtable_alloc(void)
+static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
- if (!ptr || !pgtable_page_ctor(virt_to_page(ptr)))
- BUG();
+ BUG_ON(!ptr);
+
+ /*
+ * Call proper page table ctor in case later we need to
+ * call core mm functions like apply_to_page_range() on
+ * this pre-allocated page table.
+ *
+ * We don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK if pmd is
+ * folded, and if so pgtable_pmd_page_ctor() becomes nop.
+ */
+ if (shift == PAGE_SHIFT)
+ BUG_ON(!pgtable_page_ctor(virt_to_page(ptr)));
+ else if (shift == PMD_SHIFT)
+ BUG_ON(!pgtable_pmd_page_ctor(virt_to_page(ptr)));
/* Ensure the zeroed page is visible to the page table walker */
dsb(ishst);
--
2.21.0.360.g471c308f928-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v3 1/3] arm64: mm: use appropriate ctors for page tables
@ 2019-03-10 1:19 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-10 1:19 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
For pte page, use pgtable_page_ctor(); for pmd page, use
pgtable_pmd_page_ctor(); and for the rest (pud, p4d and pgd),
don't use any.
For now, we don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK and
pgtable_pmd_page_ctor() is a nop. When we do in patch 3, we
make sure pmd is not folded so we won't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index b6f5aa52ac67..f704b291f2c5 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -98,7 +98,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
}
EXPORT_SYMBOL(phys_mem_access_prot);
-static phys_addr_t __init early_pgtable_alloc(void)
+static phys_addr_t __init early_pgtable_alloc(int shift)
{
phys_addr_t phys;
void *ptr;
@@ -173,7 +173,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -183,7 +183,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
if (pmd_none(pmd)) {
phys_addr_t pte_phys;
BUG_ON(!pgtable_alloc);
- pte_phys = pgtable_alloc();
+ pte_phys = pgtable_alloc(PAGE_SHIFT);
__pmd_populate(pmdp, pte_phys, PMD_TYPE_TABLE);
pmd = READ_ONCE(*pmdp);
}
@@ -207,7 +207,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pmd_t *pmdp;
@@ -245,7 +245,7 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pud_t pud = READ_ONCE(*pudp);
@@ -257,7 +257,7 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
if (pud_none(pud)) {
phys_addr_t pmd_phys;
BUG_ON(!pgtable_alloc);
- pmd_phys = pgtable_alloc();
+ pmd_phys = pgtable_alloc(PMD_SHIFT);
__pud_populate(pudp, pmd_phys, PUD_TYPE_TABLE);
pud = READ_ONCE(*pudp);
}
@@ -293,7 +293,7 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -303,7 +303,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
if (pgd_none(pgd)) {
phys_addr_t pud_phys;
BUG_ON(!pgtable_alloc);
- pud_phys = pgtable_alloc();
+ pud_phys = pgtable_alloc(PUD_SHIFT);
__pgd_populate(pgdp, pud_phys, PUD_TYPE_TABLE);
pgd = READ_ONCE(*pgdp);
}
@@ -344,7 +344,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long addr, length, end, next;
@@ -370,11 +370,23 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
-static phys_addr_t pgd_pgtable_alloc(void)
+static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
- if (!ptr || !pgtable_page_ctor(virt_to_page(ptr)))
- BUG();
+ BUG_ON(!ptr);
+
+ /*
+ * Call proper page table ctor in case later we need to
+ * call core mm functions like apply_to_page_range() on
+ * this pre-allocated page table.
+ *
+ * We don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK if pmd is
+ * folded, and if so pgtable_pmd_page_ctor() becomes nop.
+ */
+ if (shift == PAGE_SHIFT)
+ BUG_ON(!pgtable_page_ctor(virt_to_page(ptr)));
+ else if (shift == PMD_SHIFT)
+ BUG_ON(!pgtable_pmd_page_ctor(virt_to_page(ptr)));
/* Ensure the zeroed page is visible to the page table walker */
dsb(ishst);
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v3 2/3] arm64: mm: don't call page table ctors for init_mm
2019-03-10 1:19 ` Yu Zhao
(?)
@ 2019-03-10 1:19 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-10 1:19 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
init_mm doesn't require page table lock to be initialized at
any level. Add a separate page table allocator for it, and the
new one skips page table ctors.
The ctors allocate memory when ALLOC_SPLIT_PTLOCKS is set. Not
calling them avoids memory leak in case we call pte_free_kernel()
on init_mm.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f704b291f2c5..d1dc2a2777aa 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -370,6 +370,16 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
+static phys_addr_t pgd_kernel_pgtable_alloc(int shift)
+{
+ void *ptr = (void *)__get_free_page(PGALLOC_GFP);
+ BUG_ON(!ptr);
+
+ /* Ensure the zeroed page is visible to the page table walker */
+ dsb(ishst);
+ return __pa(ptr);
+}
+
static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
@@ -594,7 +604,7 @@ static int __init map_entry_trampoline(void)
/* Map only the text into the trampoline page table */
memset(tramp_pg_dir, 0, PGD_SIZE);
__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
- prot, pgd_pgtable_alloc, 0);
+ prot, pgd_kernel_pgtable_alloc, 0);
/* Map both the text and data into the kernel page table */
__set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
@@ -1070,7 +1080,8 @@ int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
- size, PAGE_KERNEL, pgd_pgtable_alloc, flags);
+ size, PAGE_KERNEL, pgd_kernel_pgtable_alloc,
+ flags);
return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT,
altmap, want_memblock);
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v3 2/3] arm64: mm: don't call page table ctors for init_mm
@ 2019-03-10 1:19 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-10 1:19 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: linux-arch, Yu Zhao, Ard Biesheuvel, Peter Zijlstra,
linux-kernel, Nick Piggin, Jun Yao, linux-mm, Aneesh Kumar K . V,
Chintan Pandya, Joel Fernandes, Kirill A . Shutemov,
Andrew Morton, Laura Abbott, linux-arm-kernel
init_mm doesn't require page table lock to be initialized at
any level. Add a separate page table allocator for it, and the
new one skips page table ctors.
The ctors allocate memory when ALLOC_SPLIT_PTLOCKS is set. Not
calling them avoids memory leak in case we call pte_free_kernel()
on init_mm.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f704b291f2c5..d1dc2a2777aa 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -370,6 +370,16 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
+static phys_addr_t pgd_kernel_pgtable_alloc(int shift)
+{
+ void *ptr = (void *)__get_free_page(PGALLOC_GFP);
+ BUG_ON(!ptr);
+
+ /* Ensure the zeroed page is visible to the page table walker */
+ dsb(ishst);
+ return __pa(ptr);
+}
+
static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
@@ -594,7 +604,7 @@ static int __init map_entry_trampoline(void)
/* Map only the text into the trampoline page table */
memset(tramp_pg_dir, 0, PGD_SIZE);
__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
- prot, pgd_pgtable_alloc, 0);
+ prot, pgd_kernel_pgtable_alloc, 0);
/* Map both the text and data into the kernel page table */
__set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
@@ -1070,7 +1080,8 @@ int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
- size, PAGE_KERNEL, pgd_pgtable_alloc, flags);
+ size, PAGE_KERNEL, pgd_kernel_pgtable_alloc,
+ flags);
return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT,
altmap, want_memblock);
--
2.21.0.360.g471c308f928-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v3 2/3] arm64: mm: don't call page table ctors for init_mm
@ 2019-03-10 1:19 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-10 1:19 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
init_mm doesn't require page table lock to be initialized at
any level. Add a separate page table allocator for it, and the
new one skips page table ctors.
The ctors allocate memory when ALLOC_SPLIT_PTLOCKS is set. Not
calling them avoids memory leak in case we call pte_free_kernel()
on init_mm.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f704b291f2c5..d1dc2a2777aa 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -370,6 +370,16 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
+static phys_addr_t pgd_kernel_pgtable_alloc(int shift)
+{
+ void *ptr = (void *)__get_free_page(PGALLOC_GFP);
+ BUG_ON(!ptr);
+
+ /* Ensure the zeroed page is visible to the page table walker */
+ dsb(ishst);
+ return __pa(ptr);
+}
+
static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
@@ -594,7 +604,7 @@ static int __init map_entry_trampoline(void)
/* Map only the text into the trampoline page table */
memset(tramp_pg_dir, 0, PGD_SIZE);
__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
- prot, pgd_pgtable_alloc, 0);
+ prot, pgd_kernel_pgtable_alloc, 0);
/* Map both the text and data into the kernel page table */
__set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
@@ -1070,7 +1080,8 @@ int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
- size, PAGE_KERNEL, pgd_pgtable_alloc, flags);
+ size, PAGE_KERNEL, pgd_kernel_pgtable_alloc,
+ flags);
return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT,
altmap, want_memblock);
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
2019-03-10 1:19 ` Yu Zhao
(?)
@ 2019-03-10 1:19 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-10 1:19 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
Switch from per mm_struct to per pmd page table lock by enabling
ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
large system.
I'm not sure if there is contention on mm->page_table_lock. Given
the option comes at no cost (apart from initializing more spin
locks), why not enable it now.
We only do so when pmd is not folded, so we don't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
is folded).
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/Kconfig | 3 +++
arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
arch/arm64/include/asm/tlb.h | 5 ++++-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cfbf307d6dc4..a3b1b789f766 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
+config ARCH_ENABLE_SPLIT_PMD_PTLOCK
+ def_bool y if PGTABLE_LEVELS > 2
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
---help---
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 52fa47c73bf0..dabba4b2c61f 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -33,12 +33,22 @@
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- return (pmd_t *)__get_free_page(PGALLOC_GFP);
+ struct page *page;
+
+ page = alloc_page(PGALLOC_GFP);
+ if (!page)
+ return NULL;
+ if (!pgtable_pmd_page_ctor(page)) {
+ __free_page(page);
+ return NULL;
+ }
+ return page_address(page);
}
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
{
BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
+ pgtable_pmd_page_dtor(virt_to_page(pmdp));
free_page((unsigned long)pmdp);
}
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 106fdc951b6e..4e3becfed387 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
unsigned long addr)
{
- tlb_remove_table(tlb, virt_to_page(pmdp));
+ struct page *page = virt_to_page(pmdp);
+
+ pgtable_pmd_page_dtor(page);
+ tlb_remove_table(tlb, page);
}
#endif
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
@ 2019-03-10 1:19 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-10 1:19 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: linux-arch, Yu Zhao, Ard Biesheuvel, Peter Zijlstra,
linux-kernel, Nick Piggin, Jun Yao, linux-mm, Aneesh Kumar K . V,
Chintan Pandya, Joel Fernandes, Kirill A . Shutemov,
Andrew Morton, Laura Abbott, linux-arm-kernel
Switch from per mm_struct to per pmd page table lock by enabling
ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
large system.
I'm not sure if there is contention on mm->page_table_lock. Given
the option comes at no cost (apart from initializing more spin
locks), why not enable it now.
We only do so when pmd is not folded, so we don't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
is folded).
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/Kconfig | 3 +++
arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
arch/arm64/include/asm/tlb.h | 5 ++++-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cfbf307d6dc4..a3b1b789f766 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
+config ARCH_ENABLE_SPLIT_PMD_PTLOCK
+ def_bool y if PGTABLE_LEVELS > 2
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
---help---
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 52fa47c73bf0..dabba4b2c61f 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -33,12 +33,22 @@
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- return (pmd_t *)__get_free_page(PGALLOC_GFP);
+ struct page *page;
+
+ page = alloc_page(PGALLOC_GFP);
+ if (!page)
+ return NULL;
+ if (!pgtable_pmd_page_ctor(page)) {
+ __free_page(page);
+ return NULL;
+ }
+ return page_address(page);
}
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
{
BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
+ pgtable_pmd_page_dtor(virt_to_page(pmdp));
free_page((unsigned long)pmdp);
}
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 106fdc951b6e..4e3becfed387 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
unsigned long addr)
{
- tlb_remove_table(tlb, virt_to_page(pmdp));
+ struct page *page = virt_to_page(pmdp);
+
+ pgtable_pmd_page_dtor(page);
+ tlb_remove_table(tlb, page);
}
#endif
--
2.21.0.360.g471c308f928-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
@ 2019-03-10 1:19 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-10 1:19 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
Switch from per mm_struct to per pmd page table lock by enabling
ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
large system.
I'm not sure if there is contention on mm->page_table_lock. Given
the option comes at no cost (apart from initializing more spin
locks), why not enable it now.
We only do so when pmd is not folded, so we don't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
is folded).
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/Kconfig | 3 +++
arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
arch/arm64/include/asm/tlb.h | 5 ++++-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cfbf307d6dc4..a3b1b789f766 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
+config ARCH_ENABLE_SPLIT_PMD_PTLOCK
+ def_bool y if PGTABLE_LEVELS > 2
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
---help---
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 52fa47c73bf0..dabba4b2c61f 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -33,12 +33,22 @@
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- return (pmd_t *)__get_free_page(PGALLOC_GFP);
+ struct page *page;
+
+ page = alloc_page(PGALLOC_GFP);
+ if (!page)
+ return NULL;
+ if (!pgtable_pmd_page_ctor(page)) {
+ __free_page(page);
+ return NULL;
+ }
+ return page_address(page);
}
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
{
BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
+ pgtable_pmd_page_dtor(virt_to_page(pmdp));
free_page((unsigned long)pmdp);
}
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 106fdc951b6e..4e3becfed387 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
unsigned long addr)
{
- tlb_remove_table(tlb, virt_to_page(pmdp));
+ struct page *page = virt_to_page(pmdp);
+
+ pgtable_pmd_page_dtor(page);
+ tlb_remove_table(tlb, page);
}
#endif
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
2019-03-10 1:19 ` Yu Zhao
@ 2019-03-11 8:28 ` Anshuman Khandual
-1 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-11 8:28 UTC (permalink / raw)
To: Yu Zhao, Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm
On 03/10/2019 06:49 AM, Yu Zhao wrote:
> Switch from per mm_struct to per pmd page table lock by enabling
> ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
> large system.
>
> I'm not sure if there is contention on mm->page_table_lock. Given
> the option comes at no cost (apart from initializing more spin
> locks), why not enable it now.
>
> We only do so when pmd is not folded, so we don't mistakenly call
> pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
> check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
> is folded).
>
> Signed-off-by: Yu Zhao <yuzhao@google.com>
> ---
> arch/arm64/Kconfig | 3 +++
> arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
> arch/arm64/include/asm/tlb.h | 5 ++++-
> 3 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index cfbf307d6dc4..a3b1b789f766 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
> config ARCH_HAS_CACHE_LINE_SIZE
> def_bool y
>
> +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
> + def_bool y if PGTABLE_LEVELS > 2
> +
> config SECCOMP
> bool "Enable seccomp to safely compute untrusted bytecode"
> ---help---
> diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> index 52fa47c73bf0..dabba4b2c61f 100644
> --- a/arch/arm64/include/asm/pgalloc.h
> +++ b/arch/arm64/include/asm/pgalloc.h
> @@ -33,12 +33,22 @@
>
> static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
> {
> - return (pmd_t *)__get_free_page(PGALLOC_GFP);
> + struct page *page;
> +
> + page = alloc_page(PGALLOC_GFP);
> + if (!page)
> + return NULL;
> + if (!pgtable_pmd_page_ctor(page)) {
> + __free_page(page);
> + return NULL;
> + }
> + return page_address(page);
> }
>
> static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
> {
> BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
> + pgtable_pmd_page_dtor(virt_to_page(pmdp));
> free_page((unsigned long)pmdp);
> }
There is just one problem here. ARM KVM's stage2_pmd_free() calls into pmd_free() on a page
originally allocated with __get_free_page() and never went through pgtable_pmd_page_ctor().
So when ARCH_ENABLE_SPLIT_PMD_PTLOCK is enabled
stage2_pmd_free()
pgtable_pmd_page_dtor()
ptlock_free()
kmem_cache_free(page_ptl_cachep, page->ptl)
Though SLUB implementation for kmem_cache_free() seems to be handling NULL page->ptl (as the
page never got it's lock allocated or initialized) correctly I am not sure if it is a right
thing to do.
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
@ 2019-03-11 8:28 ` Anshuman Khandual
0 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-11 8:28 UTC (permalink / raw)
To: Yu Zhao, Catalin Marinas, Will Deacon, Mark Rutland
Cc: linux-arch, Ard Biesheuvel, Peter Zijlstra, linux-kernel,
Nick Piggin, Jun Yao, linux-mm, Aneesh Kumar K . V,
Chintan Pandya, Joel Fernandes, Kirill A . Shutemov,
Andrew Morton, Laura Abbott, linux-arm-kernel
On 03/10/2019 06:49 AM, Yu Zhao wrote:
> Switch from per mm_struct to per pmd page table lock by enabling
> ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
> large system.
>
> I'm not sure if there is contention on mm->page_table_lock. Given
> the option comes at no cost (apart from initializing more spin
> locks), why not enable it now.
>
> We only do so when pmd is not folded, so we don't mistakenly call
> pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
> check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
> is folded).
>
> Signed-off-by: Yu Zhao <yuzhao@google.com>
> ---
> arch/arm64/Kconfig | 3 +++
> arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
> arch/arm64/include/asm/tlb.h | 5 ++++-
> 3 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index cfbf307d6dc4..a3b1b789f766 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
> config ARCH_HAS_CACHE_LINE_SIZE
> def_bool y
>
> +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
> + def_bool y if PGTABLE_LEVELS > 2
> +
> config SECCOMP
> bool "Enable seccomp to safely compute untrusted bytecode"
> ---help---
> diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> index 52fa47c73bf0..dabba4b2c61f 100644
> --- a/arch/arm64/include/asm/pgalloc.h
> +++ b/arch/arm64/include/asm/pgalloc.h
> @@ -33,12 +33,22 @@
>
> static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
> {
> - return (pmd_t *)__get_free_page(PGALLOC_GFP);
> + struct page *page;
> +
> + page = alloc_page(PGALLOC_GFP);
> + if (!page)
> + return NULL;
> + if (!pgtable_pmd_page_ctor(page)) {
> + __free_page(page);
> + return NULL;
> + }
> + return page_address(page);
> }
>
> static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
> {
> BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
> + pgtable_pmd_page_dtor(virt_to_page(pmdp));
> free_page((unsigned long)pmdp);
> }
There is just one problem here. ARM KVM's stage2_pmd_free() calls into pmd_free() on a page
originally allocated with __get_free_page() and never went through pgtable_pmd_page_ctor().
So when ARCH_ENABLE_SPLIT_PMD_PTLOCK is enabled
stage2_pmd_free()
pgtable_pmd_page_dtor()
ptlock_free()
kmem_cache_free(page_ptl_cachep, page->ptl)
Though SLUB implementation for kmem_cache_free() seems to be handling NULL page->ptl (as the
page never got it's lock allocated or initialized) correctly I am not sure if it is a right
thing to do.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
2019-03-11 8:28 ` Anshuman Khandual
@ 2019-03-11 23:10 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-11 23:10 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Catalin Marinas, Will Deacon, Mark Rutland, Aneesh Kumar K . V,
Andrew Morton, Nick Piggin, Peter Zijlstra, Joel Fernandes,
Kirill A . Shutemov, Ard Biesheuvel, Chintan Pandya, Jun Yao,
Laura Abbott, linux-arm-kernel, linux-kernel, linux-arch,
linux-mm
On Mon, Mar 11, 2019 at 01:58:27PM +0530, Anshuman Khandual wrote:
> On 03/10/2019 06:49 AM, Yu Zhao wrote:
> > Switch from per mm_struct to per pmd page table lock by enabling
> > ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
> > large system.
> >
> > I'm not sure if there is contention on mm->page_table_lock. Given
> > the option comes at no cost (apart from initializing more spin
> > locks), why not enable it now.
> >
> > We only do so when pmd is not folded, so we don't mistakenly call
> > pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
> > check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
> > is folded).
> >
> > Signed-off-by: Yu Zhao <yuzhao@google.com>
> > ---
> > arch/arm64/Kconfig | 3 +++
> > arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
> > arch/arm64/include/asm/tlb.h | 5 ++++-
> > 3 files changed, 18 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index cfbf307d6dc4..a3b1b789f766 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
> > config ARCH_HAS_CACHE_LINE_SIZE
> > def_bool y
> >
> > +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
> > + def_bool y if PGTABLE_LEVELS > 2
> > +
> > config SECCOMP
> > bool "Enable seccomp to safely compute untrusted bytecode"
> > ---help---
> > diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> > index 52fa47c73bf0..dabba4b2c61f 100644
> > --- a/arch/arm64/include/asm/pgalloc.h
> > +++ b/arch/arm64/include/asm/pgalloc.h
> > @@ -33,12 +33,22 @@
> >
> > static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
> > {
> > - return (pmd_t *)__get_free_page(PGALLOC_GFP);
> > + struct page *page;
> > +
> > + page = alloc_page(PGALLOC_GFP);
> > + if (!page)
> > + return NULL;
> > + if (!pgtable_pmd_page_ctor(page)) {
> > + __free_page(page);
> > + return NULL;
> > + }
> > + return page_address(page);
> > }
> >
> > static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
> > {
> > BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
> > + pgtable_pmd_page_dtor(virt_to_page(pmdp));
> > free_page((unsigned long)pmdp);
> > }
>
> There is just one problem here. ARM KVM's stage2_pmd_free() calls into pmd_free() on a page
> originally allocated with __get_free_page() and never went through pgtable_pmd_page_ctor().
> So when ARCH_ENABLE_SPLIT_PMD_PTLOCK is enabled
>
> stage2_pmd_free()
> pgtable_pmd_page_dtor()
> ptlock_free()
> kmem_cache_free(page_ptl_cachep, page->ptl)
>
> Though SLUB implementation for kmem_cache_free() seems to be handling NULL page->ptl (as the
> page never got it's lock allocated or initialized) correctly I am not sure if it is a right
> thing to do.
Thanks for reminding me. This should be fixed as well. Will do it
in a separate patch.
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
@ 2019-03-11 23:10 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-11 23:10 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Mark Rutland, linux-arch, Ard Biesheuvel, Peter Zijlstra,
Catalin Marinas, Will Deacon, linux-kernel, Nick Piggin, Jun Yao,
linux-mm, Aneesh Kumar K . V, Chintan Pandya, Joel Fernandes,
Kirill A . Shutemov, Andrew Morton, Laura Abbott,
linux-arm-kernel
On Mon, Mar 11, 2019 at 01:58:27PM +0530, Anshuman Khandual wrote:
> On 03/10/2019 06:49 AM, Yu Zhao wrote:
> > Switch from per mm_struct to per pmd page table lock by enabling
> > ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
> > large system.
> >
> > I'm not sure if there is contention on mm->page_table_lock. Given
> > the option comes at no cost (apart from initializing more spin
> > locks), why not enable it now.
> >
> > We only do so when pmd is not folded, so we don't mistakenly call
> > pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
> > check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
> > is folded).
> >
> > Signed-off-by: Yu Zhao <yuzhao@google.com>
> > ---
> > arch/arm64/Kconfig | 3 +++
> > arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
> > arch/arm64/include/asm/tlb.h | 5 ++++-
> > 3 files changed, 18 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index cfbf307d6dc4..a3b1b789f766 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
> > config ARCH_HAS_CACHE_LINE_SIZE
> > def_bool y
> >
> > +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
> > + def_bool y if PGTABLE_LEVELS > 2
> > +
> > config SECCOMP
> > bool "Enable seccomp to safely compute untrusted bytecode"
> > ---help---
> > diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> > index 52fa47c73bf0..dabba4b2c61f 100644
> > --- a/arch/arm64/include/asm/pgalloc.h
> > +++ b/arch/arm64/include/asm/pgalloc.h
> > @@ -33,12 +33,22 @@
> >
> > static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
> > {
> > - return (pmd_t *)__get_free_page(PGALLOC_GFP);
> > + struct page *page;
> > +
> > + page = alloc_page(PGALLOC_GFP);
> > + if (!page)
> > + return NULL;
> > + if (!pgtable_pmd_page_ctor(page)) {
> > + __free_page(page);
> > + return NULL;
> > + }
> > + return page_address(page);
> > }
> >
> > static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
> > {
> > BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
> > + pgtable_pmd_page_dtor(virt_to_page(pmdp));
> > free_page((unsigned long)pmdp);
> > }
>
> There is just one problem here. ARM KVM's stage2_pmd_free() calls into pmd_free() on a page
> originally allocated with __get_free_page() and never went through pgtable_pmd_page_ctor().
> So when ARCH_ENABLE_SPLIT_PMD_PTLOCK is enabled
>
> stage2_pmd_free()
> pgtable_pmd_page_dtor()
> ptlock_free()
> kmem_cache_free(page_ptl_cachep, page->ptl)
>
> Though SLUB implementation for kmem_cache_free() seems to be handling NULL page->ptl (as the
> page never got it's lock allocated or initialized) correctly I am not sure if it is a right
> thing to do.
Thanks for reminding me. This should be fixed as well. Will do it
in a separate patch.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
2019-03-10 1:19 ` Yu Zhao
@ 2019-03-11 12:12 ` Mark Rutland
-1 siblings, 0 replies; 120+ messages in thread
From: Mark Rutland @ 2019-03-11 12:12 UTC (permalink / raw)
To: Yu Zhao, Anshuman Khandual
Cc: Catalin Marinas, Will Deacon, Aneesh Kumar K . V, Andrew Morton,
Nick Piggin, Peter Zijlstra, Joel Fernandes, Kirill A . Shutemov,
Ard Biesheuvel, Chintan Pandya, Jun Yao, Laura Abbott,
linux-arm-kernel, linux-kernel, linux-arch, linux-mm
Hi,
On Sat, Mar 09, 2019 at 06:19:06PM -0700, Yu Zhao wrote:
> Switch from per mm_struct to per pmd page table lock by enabling
> ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
> large system.
>
> I'm not sure if there is contention on mm->page_table_lock. Given
> the option comes at no cost (apart from initializing more spin
> locks), why not enable it now.
>
> We only do so when pmd is not folded, so we don't mistakenly call
> pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
> check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
> is folded).
Just to check, I take it pgtable_pmd_page_ctor() is now a NOP when the
PMD is folded, and this last paragraph is stale?
> Signed-off-by: Yu Zhao <yuzhao@google.com>
> ---
> arch/arm64/Kconfig | 3 +++
> arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
> arch/arm64/include/asm/tlb.h | 5 ++++-
> 3 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index cfbf307d6dc4..a3b1b789f766 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
> config ARCH_HAS_CACHE_LINE_SIZE
> def_bool y
>
> +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
> + def_bool y if PGTABLE_LEVELS > 2
> +
> config SECCOMP
> bool "Enable seccomp to safely compute untrusted bytecode"
> ---help---
> diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> index 52fa47c73bf0..dabba4b2c61f 100644
> --- a/arch/arm64/include/asm/pgalloc.h
> +++ b/arch/arm64/include/asm/pgalloc.h
> @@ -33,12 +33,22 @@
>
> static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
> {
> - return (pmd_t *)__get_free_page(PGALLOC_GFP);
> + struct page *page;
> +
> + page = alloc_page(PGALLOC_GFP);
> + if (!page)
> + return NULL;
> + if (!pgtable_pmd_page_ctor(page)) {
> + __free_page(page);
> + return NULL;
> + }
> + return page_address(page);
> }
>
> static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
> {
> BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
> + pgtable_pmd_page_dtor(virt_to_page(pmdp));
> free_page((unsigned long)pmdp);
> }
It looks like arm64's existing stage-2 code is inconsistent across
alloc/free, and IIUC this change might turn that into a real problem.
Currently we allocate all levels of stage-2 table with
__get_free_page(), but free them with p?d_free(). We always miss the
ctor and always use the dtor.
Other than that, this patch looks fine to me, but I'd feel more
comfortable if we could first fix the stage-2 code to free those stage-2
tables without invoking the dtor.
Anshuman, IIRC you had a patch to fix the stage-2 code to not invoke the
dtors. If so, could you please post that so that we could take it as a
preparatory patch for this series?
Thanks,
Mark.
> diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
> index 106fdc951b6e..4e3becfed387 100644
> --- a/arch/arm64/include/asm/tlb.h
> +++ b/arch/arm64/include/asm/tlb.h
> @@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
> static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
> unsigned long addr)
> {
> - tlb_remove_table(tlb, virt_to_page(pmdp));
> + struct page *page = virt_to_page(pmdp);
> +
> + pgtable_pmd_page_dtor(page);
> + tlb_remove_table(tlb, page);
> }
> #endif
>
> --
> 2.21.0.360.g471c308f928-goog
>
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
@ 2019-03-11 12:12 ` Mark Rutland
0 siblings, 0 replies; 120+ messages in thread
From: Mark Rutland @ 2019-03-11 12:12 UTC (permalink / raw)
To: Yu Zhao, Anshuman Khandual
Cc: linux-arch, Ard Biesheuvel, Peter Zijlstra, Catalin Marinas,
Will Deacon, linux-kernel, Nick Piggin, Jun Yao, linux-mm,
Aneesh Kumar K . V, Chintan Pandya, Joel Fernandes,
Kirill A . Shutemov, Andrew Morton, Laura Abbott,
linux-arm-kernel
Hi,
On Sat, Mar 09, 2019 at 06:19:06PM -0700, Yu Zhao wrote:
> Switch from per mm_struct to per pmd page table lock by enabling
> ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
> large system.
>
> I'm not sure if there is contention on mm->page_table_lock. Given
> the option comes at no cost (apart from initializing more spin
> locks), why not enable it now.
>
> We only do so when pmd is not folded, so we don't mistakenly call
> pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
> check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
> is folded).
Just to check, I take it pgtable_pmd_page_ctor() is now a NOP when the
PMD is folded, and this last paragraph is stale?
> Signed-off-by: Yu Zhao <yuzhao@google.com>
> ---
> arch/arm64/Kconfig | 3 +++
> arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
> arch/arm64/include/asm/tlb.h | 5 ++++-
> 3 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index cfbf307d6dc4..a3b1b789f766 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
> config ARCH_HAS_CACHE_LINE_SIZE
> def_bool y
>
> +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
> + def_bool y if PGTABLE_LEVELS > 2
> +
> config SECCOMP
> bool "Enable seccomp to safely compute untrusted bytecode"
> ---help---
> diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> index 52fa47c73bf0..dabba4b2c61f 100644
> --- a/arch/arm64/include/asm/pgalloc.h
> +++ b/arch/arm64/include/asm/pgalloc.h
> @@ -33,12 +33,22 @@
>
> static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
> {
> - return (pmd_t *)__get_free_page(PGALLOC_GFP);
> + struct page *page;
> +
> + page = alloc_page(PGALLOC_GFP);
> + if (!page)
> + return NULL;
> + if (!pgtable_pmd_page_ctor(page)) {
> + __free_page(page);
> + return NULL;
> + }
> + return page_address(page);
> }
>
> static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
> {
> BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
> + pgtable_pmd_page_dtor(virt_to_page(pmdp));
> free_page((unsigned long)pmdp);
> }
It looks like arm64's existing stage-2 code is inconsistent across
alloc/free, and IIUC this change might turn that into a real problem.
Currently we allocate all levels of stage-2 table with
__get_free_page(), but free them with p?d_free(). We always miss the
ctor and always use the dtor.
Other than that, this patch looks fine to me, but I'd feel more
comfortable if we could first fix the stage-2 code to free those stage-2
tables without invoking the dtor.
Anshuman, IIRC you had a patch to fix the stage-2 code to not invoke the
dtors. If so, could you please post that so that we could take it as a
preparatory patch for this series?
Thanks,
Mark.
> diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
> index 106fdc951b6e..4e3becfed387 100644
> --- a/arch/arm64/include/asm/tlb.h
> +++ b/arch/arm64/include/asm/tlb.h
> @@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
> static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
> unsigned long addr)
> {
> - tlb_remove_table(tlb, virt_to_page(pmdp));
> + struct page *page = virt_to_page(pmdp);
> +
> + pgtable_pmd_page_dtor(page);
> + tlb_remove_table(tlb, page);
> }
> #endif
>
> --
> 2.21.0.360.g471c308f928-goog
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
2019-03-11 12:12 ` Mark Rutland
@ 2019-03-11 12:57 ` Anshuman Khandual
-1 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-11 12:57 UTC (permalink / raw)
To: Mark Rutland, Yu Zhao
Cc: Catalin Marinas, Will Deacon, Aneesh Kumar K . V, Andrew Morton,
Nick Piggin, Peter Zijlstra, Joel Fernandes, Kirill A . Shutemov,
Ard Biesheuvel, Chintan Pandya, Jun Yao, Laura Abbott,
linux-arm-kernel, linux-kernel, linux-arch, linux-mm
On 03/11/2019 05:42 PM, Mark Rutland wrote:
> Hi,
>
> On Sat, Mar 09, 2019 at 06:19:06PM -0700, Yu Zhao wrote:
>> Switch from per mm_struct to per pmd page table lock by enabling
>> ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
>> large system.
>>
>> I'm not sure if there is contention on mm->page_table_lock. Given
>> the option comes at no cost (apart from initializing more spin
>> locks), why not enable it now.
>>
>> We only do so when pmd is not folded, so we don't mistakenly call
>> pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
>> check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
>> is folded).
>
> Just to check, I take it pgtable_pmd_page_ctor() is now a NOP when the
> PMD is folded, and this last paragraph is stale?
>
>> Signed-off-by: Yu Zhao <yuzhao@google.com>
>> ---
>> arch/arm64/Kconfig | 3 +++
>> arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
>> arch/arm64/include/asm/tlb.h | 5 ++++-
>> 3 files changed, 18 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index cfbf307d6dc4..a3b1b789f766 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
>> config ARCH_HAS_CACHE_LINE_SIZE
>> def_bool y
>>
>> +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
>> + def_bool y if PGTABLE_LEVELS > 2
>> +
>> config SECCOMP
>> bool "Enable seccomp to safely compute untrusted bytecode"
>> ---help---
>> diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
>> index 52fa47c73bf0..dabba4b2c61f 100644
>> --- a/arch/arm64/include/asm/pgalloc.h
>> +++ b/arch/arm64/include/asm/pgalloc.h
>> @@ -33,12 +33,22 @@
>>
>> static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
>> {
>> - return (pmd_t *)__get_free_page(PGALLOC_GFP);
>> + struct page *page;
>> +
>> + page = alloc_page(PGALLOC_GFP);
>> + if (!page)
>> + return NULL;
>> + if (!pgtable_pmd_page_ctor(page)) {
>> + __free_page(page);
>> + return NULL;
>> + }
>> + return page_address(page);
>> }
>>
>> static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
>> {
>> BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
>> + pgtable_pmd_page_dtor(virt_to_page(pmdp));
>> free_page((unsigned long)pmdp);
>> }
>
> It looks like arm64's existing stage-2 code is inconsistent across
> alloc/free, and IIUC this change might turn that into a real problem.
> Currently we allocate all levels of stage-2 table with
> __get_free_page(), but free them with p?d_free(). We always miss the
> ctor and always use the dtor.
>
> Other than that, this patch looks fine to me, but I'd feel more
> comfortable if we could first fix the stage-2 code to free those stage-2
> tables without invoking the dtor.
Thats right. I have already highlighted this problem.
>
> Anshuman, IIRC you had a patch to fix the stage-2 code to not invoke the
> dtors. If so, could you please post that so that we could take it as a
> preparatory patch for this series?
Sure I can after fixing PTE level pte_free_kernel/__free_page which I had
missed in V2.
https://www.spinics.net/lists/arm-kernel/msg710118.html
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
@ 2019-03-11 12:57 ` Anshuman Khandual
0 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-11 12:57 UTC (permalink / raw)
To: Mark Rutland, Yu Zhao
Cc: linux-arch, Ard Biesheuvel, Peter Zijlstra, Catalin Marinas,
Will Deacon, linux-kernel, Nick Piggin, Jun Yao, linux-mm,
Aneesh Kumar K . V, Chintan Pandya, Joel Fernandes,
Kirill A . Shutemov, Andrew Morton, Laura Abbott,
linux-arm-kernel
On 03/11/2019 05:42 PM, Mark Rutland wrote:
> Hi,
>
> On Sat, Mar 09, 2019 at 06:19:06PM -0700, Yu Zhao wrote:
>> Switch from per mm_struct to per pmd page table lock by enabling
>> ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
>> large system.
>>
>> I'm not sure if there is contention on mm->page_table_lock. Given
>> the option comes at no cost (apart from initializing more spin
>> locks), why not enable it now.
>>
>> We only do so when pmd is not folded, so we don't mistakenly call
>> pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
>> check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
>> is folded).
>
> Just to check, I take it pgtable_pmd_page_ctor() is now a NOP when the
> PMD is folded, and this last paragraph is stale?
>
>> Signed-off-by: Yu Zhao <yuzhao@google.com>
>> ---
>> arch/arm64/Kconfig | 3 +++
>> arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
>> arch/arm64/include/asm/tlb.h | 5 ++++-
>> 3 files changed, 18 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index cfbf307d6dc4..a3b1b789f766 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
>> config ARCH_HAS_CACHE_LINE_SIZE
>> def_bool y
>>
>> +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
>> + def_bool y if PGTABLE_LEVELS > 2
>> +
>> config SECCOMP
>> bool "Enable seccomp to safely compute untrusted bytecode"
>> ---help---
>> diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
>> index 52fa47c73bf0..dabba4b2c61f 100644
>> --- a/arch/arm64/include/asm/pgalloc.h
>> +++ b/arch/arm64/include/asm/pgalloc.h
>> @@ -33,12 +33,22 @@
>>
>> static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
>> {
>> - return (pmd_t *)__get_free_page(PGALLOC_GFP);
>> + struct page *page;
>> +
>> + page = alloc_page(PGALLOC_GFP);
>> + if (!page)
>> + return NULL;
>> + if (!pgtable_pmd_page_ctor(page)) {
>> + __free_page(page);
>> + return NULL;
>> + }
>> + return page_address(page);
>> }
>>
>> static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
>> {
>> BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
>> + pgtable_pmd_page_dtor(virt_to_page(pmdp));
>> free_page((unsigned long)pmdp);
>> }
>
> It looks like arm64's existing stage-2 code is inconsistent across
> alloc/free, and IIUC this change might turn that into a real problem.
> Currently we allocate all levels of stage-2 table with
> __get_free_page(), but free them with p?d_free(). We always miss the
> ctor and always use the dtor.
>
> Other than that, this patch looks fine to me, but I'd feel more
> comfortable if we could first fix the stage-2 code to free those stage-2
> tables without invoking the dtor.
Thats right. I have already highlighted this problem.
>
> Anshuman, IIRC you had a patch to fix the stage-2 code to not invoke the
> dtors. If so, could you please post that so that we could take it as a
> preparatory patch for this series?
Sure I can after fixing PTE level pte_free_kernel/__free_page which I had
missed in V2.
https://www.spinics.net/lists/arm-kernel/msg710118.html
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
2019-03-11 12:12 ` Mark Rutland
(?)
@ 2019-03-11 23:11 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-11 23:11 UTC (permalink / raw)
To: Mark Rutland
Cc: Anshuman Khandual, Catalin Marinas, Will Deacon,
Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm
On Mon, Mar 11, 2019 at 12:12:28PM +0000, Mark Rutland wrote:
> Hi,
>
> On Sat, Mar 09, 2019 at 06:19:06PM -0700, Yu Zhao wrote:
> > Switch from per mm_struct to per pmd page table lock by enabling
> > ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
> > large system.
> >
> > I'm not sure if there is contention on mm->page_table_lock. Given
> > the option comes at no cost (apart from initializing more spin
> > locks), why not enable it now.
> >
> > We only do so when pmd is not folded, so we don't mistakenly call
> > pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
> > check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
> > is folded).
>
> Just to check, I take it pgtable_pmd_page_ctor() is now a NOP when the
> PMD is folded, and this last paragraph is stale?
Yes, and will remove it.
> > Signed-off-by: Yu Zhao <yuzhao@google.com>
> > ---
> > arch/arm64/Kconfig | 3 +++
> > arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
> > arch/arm64/include/asm/tlb.h | 5 ++++-
> > 3 files changed, 18 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index cfbf307d6dc4..a3b1b789f766 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
> > config ARCH_HAS_CACHE_LINE_SIZE
> > def_bool y
> >
> > +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
> > + def_bool y if PGTABLE_LEVELS > 2
> > +
> > config SECCOMP
> > bool "Enable seccomp to safely compute untrusted bytecode"
> > ---help---
> > diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> > index 52fa47c73bf0..dabba4b2c61f 100644
> > --- a/arch/arm64/include/asm/pgalloc.h
> > +++ b/arch/arm64/include/asm/pgalloc.h
> > @@ -33,12 +33,22 @@
> >
> > static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
> > {
> > - return (pmd_t *)__get_free_page(PGALLOC_GFP);
> > + struct page *page;
> > +
> > + page = alloc_page(PGALLOC_GFP);
> > + if (!page)
> > + return NULL;
> > + if (!pgtable_pmd_page_ctor(page)) {
> > + __free_page(page);
> > + return NULL;
> > + }
> > + return page_address(page);
> > }
> >
> > static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
> > {
> > BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
> > + pgtable_pmd_page_dtor(virt_to_page(pmdp));
> > free_page((unsigned long)pmdp);
> > }
>
> It looks like arm64's existing stage-2 code is inconsistent across
> alloc/free, and IIUC this change might turn that into a real problem.
> Currently we allocate all levels of stage-2 table with
> __get_free_page(), but free them with p?d_free(). We always miss the
> ctor and always use the dtor.
>
> Other than that, this patch looks fine to me, but I'd feel more
> comfortable if we could first fix the stage-2 code to free those stage-2
> tables without invoking the dtor.
>
> Anshuman, IIRC you had a patch to fix the stage-2 code to not invoke the
> dtors. If so, could you please post that so that we could take it as a
> preparatory patch for this series?
Will do.
> Thanks,
> Mark.
>
> > diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
> > index 106fdc951b6e..4e3becfed387 100644
> > --- a/arch/arm64/include/asm/tlb.h
> > +++ b/arch/arm64/include/asm/tlb.h
> > @@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
> > static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
> > unsigned long addr)
> > {
> > - tlb_remove_table(tlb, virt_to_page(pmdp));
> > + struct page *page = virt_to_page(pmdp);
> > +
> > + pgtable_pmd_page_dtor(page);
> > + tlb_remove_table(tlb, page);
> > }
> > #endif
> >
> > --
> > 2.21.0.360.g471c308f928-goog
> >
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
@ 2019-03-11 23:11 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-11 23:11 UTC (permalink / raw)
To: Mark Rutland
Cc: linux-arch, Anshuman Khandual, Peter Zijlstra, Catalin Marinas,
Ard Biesheuvel, Will Deacon, linux-kernel, Nick Piggin, Jun Yao,
linux-mm, Aneesh Kumar K . V, Chintan Pandya, Joel Fernandes,
Kirill A . Shutemov, Andrew Morton, Laura Abbott,
linux-arm-kernel
On Mon, Mar 11, 2019 at 12:12:28PM +0000, Mark Rutland wrote:
> Hi,
>
> On Sat, Mar 09, 2019 at 06:19:06PM -0700, Yu Zhao wrote:
> > Switch from per mm_struct to per pmd page table lock by enabling
> > ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
> > large system.
> >
> > I'm not sure if there is contention on mm->page_table_lock. Given
> > the option comes at no cost (apart from initializing more spin
> > locks), why not enable it now.
> >
> > We only do so when pmd is not folded, so we don't mistakenly call
> > pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
> > check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
> > is folded).
>
> Just to check, I take it pgtable_pmd_page_ctor() is now a NOP when the
> PMD is folded, and this last paragraph is stale?
Yes, and will remove it.
> > Signed-off-by: Yu Zhao <yuzhao@google.com>
> > ---
> > arch/arm64/Kconfig | 3 +++
> > arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
> > arch/arm64/include/asm/tlb.h | 5 ++++-
> > 3 files changed, 18 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index cfbf307d6dc4..a3b1b789f766 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
> > config ARCH_HAS_CACHE_LINE_SIZE
> > def_bool y
> >
> > +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
> > + def_bool y if PGTABLE_LEVELS > 2
> > +
> > config SECCOMP
> > bool "Enable seccomp to safely compute untrusted bytecode"
> > ---help---
> > diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> > index 52fa47c73bf0..dabba4b2c61f 100644
> > --- a/arch/arm64/include/asm/pgalloc.h
> > +++ b/arch/arm64/include/asm/pgalloc.h
> > @@ -33,12 +33,22 @@
> >
> > static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
> > {
> > - return (pmd_t *)__get_free_page(PGALLOC_GFP);
> > + struct page *page;
> > +
> > + page = alloc_page(PGALLOC_GFP);
> > + if (!page)
> > + return NULL;
> > + if (!pgtable_pmd_page_ctor(page)) {
> > + __free_page(page);
> > + return NULL;
> > + }
> > + return page_address(page);
> > }
> >
> > static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
> > {
> > BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
> > + pgtable_pmd_page_dtor(virt_to_page(pmdp));
> > free_page((unsigned long)pmdp);
> > }
>
> It looks like arm64's existing stage-2 code is inconsistent across
> alloc/free, and IIUC this change might turn that into a real problem.
> Currently we allocate all levels of stage-2 table with
> __get_free_page(), but free them with p?d_free(). We always miss the
> ctor and always use the dtor.
>
> Other than that, this patch looks fine to me, but I'd feel more
> comfortable if we could first fix the stage-2 code to free those stage-2
> tables without invoking the dtor.
>
> Anshuman, IIRC you had a patch to fix the stage-2 code to not invoke the
> dtors. If so, could you please post that so that we could take it as a
> preparatory patch for this series?
Will do.
> Thanks,
> Mark.
>
> > diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
> > index 106fdc951b6e..4e3becfed387 100644
> > --- a/arch/arm64/include/asm/tlb.h
> > +++ b/arch/arm64/include/asm/tlb.h
> > @@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
> > static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
> > unsigned long addr)
> > {
> > - tlb_remove_table(tlb, virt_to_page(pmdp));
> > + struct page *page = virt_to_page(pmdp);
> > +
> > + pgtable_pmd_page_dtor(page);
> > + tlb_remove_table(tlb, page);
> > }
> > #endif
> >
> > --
> > 2.21.0.360.g471c308f928-goog
> >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 3/3] arm64: mm: enable per pmd page table lock
@ 2019-03-11 23:11 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-11 23:11 UTC (permalink / raw)
To: Mark Rutland
Cc: linux-arch, Anshuman Khandual, Peter Zijlstra, Catalin Marinas,
Ard Biesheuvel, Will Deacon, linux-kernel, Nick Piggin, Jun Yao,
linux-mm, Aneesh Kumar K . V, Chintan Pandya, Joel Fernandes,
Kirill A . Shutemov, Andrew Morton, Laura Abbott,
linux-arm-kernel
On Mon, Mar 11, 2019 at 12:12:28PM +0000, Mark Rutland wrote:
> Hi,
>
> On Sat, Mar 09, 2019 at 06:19:06PM -0700, Yu Zhao wrote:
> > Switch from per mm_struct to per pmd page table lock by enabling
> > ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
> > large system.
> >
> > I'm not sure if there is contention on mm->page_table_lock. Given
> > the option comes at no cost (apart from initializing more spin
> > locks), why not enable it now.
> >
> > We only do so when pmd is not folded, so we don't mistakenly call
> > pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc(). (We
> > check shift against PMD_SHIFT, which is same as PUD_SHIFT when pmd
> > is folded).
>
> Just to check, I take it pgtable_pmd_page_ctor() is now a NOP when the
> PMD is folded, and this last paragraph is stale?
Yes, and will remove it.
> > Signed-off-by: Yu Zhao <yuzhao@google.com>
> > ---
> > arch/arm64/Kconfig | 3 +++
> > arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
> > arch/arm64/include/asm/tlb.h | 5 ++++-
> > 3 files changed, 18 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index cfbf307d6dc4..a3b1b789f766 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
> > config ARCH_HAS_CACHE_LINE_SIZE
> > def_bool y
> >
> > +config ARCH_ENABLE_SPLIT_PMD_PTLOCK
> > + def_bool y if PGTABLE_LEVELS > 2
> > +
> > config SECCOMP
> > bool "Enable seccomp to safely compute untrusted bytecode"
> > ---help---
> > diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> > index 52fa47c73bf0..dabba4b2c61f 100644
> > --- a/arch/arm64/include/asm/pgalloc.h
> > +++ b/arch/arm64/include/asm/pgalloc.h
> > @@ -33,12 +33,22 @@
> >
> > static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
> > {
> > - return (pmd_t *)__get_free_page(PGALLOC_GFP);
> > + struct page *page;
> > +
> > + page = alloc_page(PGALLOC_GFP);
> > + if (!page)
> > + return NULL;
> > + if (!pgtable_pmd_page_ctor(page)) {
> > + __free_page(page);
> > + return NULL;
> > + }
> > + return page_address(page);
> > }
> >
> > static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
> > {
> > BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
> > + pgtable_pmd_page_dtor(virt_to_page(pmdp));
> > free_page((unsigned long)pmdp);
> > }
>
> It looks like arm64's existing stage-2 code is inconsistent across
> alloc/free, and IIUC this change might turn that into a real problem.
> Currently we allocate all levels of stage-2 table with
> __get_free_page(), but free them with p?d_free(). We always miss the
> ctor and always use the dtor.
>
> Other than that, this patch looks fine to me, but I'd feel more
> comfortable if we could first fix the stage-2 code to free those stage-2
> tables without invoking the dtor.
>
> Anshuman, IIRC you had a patch to fix the stage-2 code to not invoke the
> dtors. If so, could you please post that so that we could take it as a
> preparatory patch for this series?
Will do.
> Thanks,
> Mark.
>
> > diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
> > index 106fdc951b6e..4e3becfed387 100644
> > --- a/arch/arm64/include/asm/tlb.h
> > +++ b/arch/arm64/include/asm/tlb.h
> > @@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
> > static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
> > unsigned long addr)
> > {
> > - tlb_remove_table(tlb, virt_to_page(pmdp));
> > + struct page *page = virt_to_page(pmdp);
> > +
> > + pgtable_pmd_page_dtor(page);
> > + tlb_remove_table(tlb, page);
> > }
> > #endif
> >
> > --
> > 2.21.0.360.g471c308f928-goog
> >
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 1/3] arm64: mm: use appropriate ctors for page tables
2019-03-10 1:19 ` Yu Zhao
@ 2019-03-11 7:45 ` Anshuman Khandual
-1 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-11 7:45 UTC (permalink / raw)
To: Yu Zhao, Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm
Hello Yu,
We had some disagreements over this series last time around after which I had
posted the following series [1] which tried to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK
after doing some pgtable accounting changes. After some thoughts and deliberations
I figure that its better not to do pgtable alloc changes on arm64 creating a brand
new semantics which ideally should be first debated and agreed upon in generic MM.
Though I still see value in a changed generic pgtable page allocation semantics
for user and kernel space that should not stop us from enabling more granular
PMD level locks through ARCH_ENABLE_SPLIT_PMD_PTLOCK right now.
[1] https://www.spinics.net/lists/arm-kernel/msg709917.html
Having said that this series attempts to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK with
some minimal changes to existing kernel pgtable page allocation code. Hence just
trying to re-evaluate the series in that isolation.
On 03/10/2019 06:49 AM, Yu Zhao wrote:
> For pte page, use pgtable_page_ctor(); for pmd page, use
> pgtable_pmd_page_ctor(); and for the rest (pud, p4d and pgd),
> don't use any.
This is semantics change. Hence the question is why ? Should not we wait until a
generic MM agreement in place in this regard ? Can we avoid this ? Is the change
really required to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK for user space THP which
this series originally intended to achieve ?
>
> For now, we don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK and
> pgtable_pmd_page_ctor() is a nop. When we do in patch 3, we
> make sure pmd is not folded so we won't mistakenly call
> pgtable_pmd_page_ctor() on pud or p4d.
This makes sense from code perspective but I still dont understand the need to
change kernel pgtable page allocation semantics without any real benefit or fix at
the moment. Cant we keep kernel page table page allocation unchanged for now and
just enable ARCH_ENABLE_SPLIT_PMD_PTLOCK for user space THP benefits ? Do you see
any concern with that.
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 1/3] arm64: mm: use appropriate ctors for page tables
@ 2019-03-11 7:45 ` Anshuman Khandual
0 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-11 7:45 UTC (permalink / raw)
To: Yu Zhao, Catalin Marinas, Will Deacon, Mark Rutland
Cc: linux-arch, Ard Biesheuvel, Peter Zijlstra, linux-kernel,
Nick Piggin, Jun Yao, linux-mm, Aneesh Kumar K . V,
Chintan Pandya, Joel Fernandes, Kirill A . Shutemov,
Andrew Morton, Laura Abbott, linux-arm-kernel
Hello Yu,
We had some disagreements over this series last time around after which I had
posted the following series [1] which tried to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK
after doing some pgtable accounting changes. After some thoughts and deliberations
I figure that its better not to do pgtable alloc changes on arm64 creating a brand
new semantics which ideally should be first debated and agreed upon in generic MM.
Though I still see value in a changed generic pgtable page allocation semantics
for user and kernel space that should not stop us from enabling more granular
PMD level locks through ARCH_ENABLE_SPLIT_PMD_PTLOCK right now.
[1] https://www.spinics.net/lists/arm-kernel/msg709917.html
Having said that this series attempts to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK with
some minimal changes to existing kernel pgtable page allocation code. Hence just
trying to re-evaluate the series in that isolation.
On 03/10/2019 06:49 AM, Yu Zhao wrote:
> For pte page, use pgtable_page_ctor(); for pmd page, use
> pgtable_pmd_page_ctor(); and for the rest (pud, p4d and pgd),
> don't use any.
This is semantics change. Hence the question is why ? Should not we wait until a
generic MM agreement in place in this regard ? Can we avoid this ? Is the change
really required to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK for user space THP which
this series originally intended to achieve ?
>
> For now, we don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK and
> pgtable_pmd_page_ctor() is a nop. When we do in patch 3, we
> make sure pmd is not folded so we won't mistakenly call
> pgtable_pmd_page_ctor() on pud or p4d.
This makes sense from code perspective but I still dont understand the need to
change kernel pgtable page allocation semantics without any real benefit or fix at
the moment. Cant we keep kernel page table page allocation unchanged for now and
just enable ARCH_ENABLE_SPLIT_PMD_PTLOCK for user space THP benefits ? Do you see
any concern with that.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 1/3] arm64: mm: use appropriate ctors for page tables
2019-03-11 7:45 ` Anshuman Khandual
@ 2019-03-11 23:23 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-11 23:23 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Catalin Marinas, Will Deacon, Mark Rutland, Aneesh Kumar K . V,
Andrew Morton, Nick Piggin, Peter Zijlstra, Joel Fernandes,
Kirill A . Shutemov, Ard Biesheuvel, Chintan Pandya, Jun Yao,
Laura Abbott, linux-arm-kernel, linux-kernel, linux-arch,
linux-mm
On Mon, Mar 11, 2019 at 01:15:55PM +0530, Anshuman Khandual wrote:
> Hello Yu,
>
> We had some disagreements over this series last time around after which I had
> posted the following series [1] which tried to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK
> after doing some pgtable accounting changes. After some thoughts and deliberations
> I figure that its better not to do pgtable alloc changes on arm64 creating a brand
> new semantics which ideally should be first debated and agreed upon in generic MM.
>
> Though I still see value in a changed generic pgtable page allocation semantics
> for user and kernel space that should not stop us from enabling more granular
> PMD level locks through ARCH_ENABLE_SPLIT_PMD_PTLOCK right now.
>
> [1] https://www.spinics.net/lists/arm-kernel/msg709917.html
>
> Having said that this series attempts to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK with
> some minimal changes to existing kernel pgtable page allocation code. Hence just
> trying to re-evaluate the series in that isolation.
>
> On 03/10/2019 06:49 AM, Yu Zhao wrote:
>
> > For pte page, use pgtable_page_ctor(); for pmd page, use
> > pgtable_pmd_page_ctor(); and for the rest (pud, p4d and pgd),
> > don't use any.
>
> This is semantics change. Hence the question is why ? Should not we wait until a
> generic MM agreement in place in this regard ? Can we avoid this ? Is the change
> really required to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK for user space THP which
> this series originally intended to achieve ?
>
> >
> > For now, we don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK and
> > pgtable_pmd_page_ctor() is a nop. When we do in patch 3, we
> > make sure pmd is not folded so we won't mistakenly call
> > pgtable_pmd_page_ctor() on pud or p4d.
>
> This makes sense from code perspective but I still dont understand the need to
> change kernel pgtable page allocation semantics without any real benefit or fix at
> the moment. Cant we keep kernel page table page allocation unchanged for now and
> just enable ARCH_ENABLE_SPLIT_PMD_PTLOCK for user space THP benefits ? Do you see
> any concern with that.
This is not for kernel page tables (i.e. init_mm). This is to
accommodate pre-allocated efi_mm page tables because it uses
apply_to_page_range() which then calls pte_alloc_map_lock().
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH v3 1/3] arm64: mm: use appropriate ctors for page tables
@ 2019-03-11 23:23 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-11 23:23 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Mark Rutland, linux-arch, Ard Biesheuvel, Peter Zijlstra,
Catalin Marinas, Will Deacon, linux-kernel, Nick Piggin, Jun Yao,
linux-mm, Aneesh Kumar K . V, Chintan Pandya, Joel Fernandes,
Kirill A . Shutemov, Andrew Morton, Laura Abbott,
linux-arm-kernel
On Mon, Mar 11, 2019 at 01:15:55PM +0530, Anshuman Khandual wrote:
> Hello Yu,
>
> We had some disagreements over this series last time around after which I had
> posted the following series [1] which tried to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK
> after doing some pgtable accounting changes. After some thoughts and deliberations
> I figure that its better not to do pgtable alloc changes on arm64 creating a brand
> new semantics which ideally should be first debated and agreed upon in generic MM.
>
> Though I still see value in a changed generic pgtable page allocation semantics
> for user and kernel space that should not stop us from enabling more granular
> PMD level locks through ARCH_ENABLE_SPLIT_PMD_PTLOCK right now.
>
> [1] https://www.spinics.net/lists/arm-kernel/msg709917.html
>
> Having said that this series attempts to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK with
> some minimal changes to existing kernel pgtable page allocation code. Hence just
> trying to re-evaluate the series in that isolation.
>
> On 03/10/2019 06:49 AM, Yu Zhao wrote:
>
> > For pte page, use pgtable_page_ctor(); for pmd page, use
> > pgtable_pmd_page_ctor(); and for the rest (pud, p4d and pgd),
> > don't use any.
>
> This is semantics change. Hence the question is why ? Should not we wait until a
> generic MM agreement in place in this regard ? Can we avoid this ? Is the change
> really required to enable ARCH_ENABLE_SPLIT_PMD_PTLOCK for user space THP which
> this series originally intended to achieve ?
>
> >
> > For now, we don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK and
> > pgtable_pmd_page_ctor() is a nop. When we do in patch 3, we
> > make sure pmd is not folded so we won't mistakenly call
> > pgtable_pmd_page_ctor() on pud or p4d.
>
> This makes sense from code perspective but I still dont understand the need to
> change kernel pgtable page allocation semantics without any real benefit or fix at
> the moment. Cant we keep kernel page table page allocation unchanged for now and
> just enable ARCH_ENABLE_SPLIT_PMD_PTLOCK for user space THP benefits ? Do you see
> any concern with that.
This is not for kernel page tables (i.e. init_mm). This is to
accommodate pre-allocated efi_mm page tables because it uses
apply_to_page_range() which then calls pte_alloc_map_lock().
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* [PATCH v4 1/4] arm64: mm: use appropriate ctors for page tables
2019-03-10 1:19 ` Yu Zhao
(?)
@ 2019-03-12 0:57 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
For pte page, use pgtable_page_ctor(); for pmd page, use
pgtable_pmd_page_ctor(); and for the rest (pud, p4d and pgd),
don't use any.
For now, we don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK and
pgtable_pmd_page_ctor() is a nop. When we do in patch 3, we
make sure pmd is not folded so we won't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index b6f5aa52ac67..f704b291f2c5 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -98,7 +98,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
}
EXPORT_SYMBOL(phys_mem_access_prot);
-static phys_addr_t __init early_pgtable_alloc(void)
+static phys_addr_t __init early_pgtable_alloc(int shift)
{
phys_addr_t phys;
void *ptr;
@@ -173,7 +173,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -183,7 +183,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
if (pmd_none(pmd)) {
phys_addr_t pte_phys;
BUG_ON(!pgtable_alloc);
- pte_phys = pgtable_alloc();
+ pte_phys = pgtable_alloc(PAGE_SHIFT);
__pmd_populate(pmdp, pte_phys, PMD_TYPE_TABLE);
pmd = READ_ONCE(*pmdp);
}
@@ -207,7 +207,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pmd_t *pmdp;
@@ -245,7 +245,7 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pud_t pud = READ_ONCE(*pudp);
@@ -257,7 +257,7 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
if (pud_none(pud)) {
phys_addr_t pmd_phys;
BUG_ON(!pgtable_alloc);
- pmd_phys = pgtable_alloc();
+ pmd_phys = pgtable_alloc(PMD_SHIFT);
__pud_populate(pudp, pmd_phys, PUD_TYPE_TABLE);
pud = READ_ONCE(*pudp);
}
@@ -293,7 +293,7 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -303,7 +303,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
if (pgd_none(pgd)) {
phys_addr_t pud_phys;
BUG_ON(!pgtable_alloc);
- pud_phys = pgtable_alloc();
+ pud_phys = pgtable_alloc(PUD_SHIFT);
__pgd_populate(pgdp, pud_phys, PUD_TYPE_TABLE);
pgd = READ_ONCE(*pgdp);
}
@@ -344,7 +344,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long addr, length, end, next;
@@ -370,11 +370,23 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
-static phys_addr_t pgd_pgtable_alloc(void)
+static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
- if (!ptr || !pgtable_page_ctor(virt_to_page(ptr)))
- BUG();
+ BUG_ON(!ptr);
+
+ /*
+ * Call proper page table ctor in case later we need to
+ * call core mm functions like apply_to_page_range() on
+ * this pre-allocated page table.
+ *
+ * We don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK if pmd is
+ * folded, and if so pgtable_pmd_page_ctor() becomes nop.
+ */
+ if (shift == PAGE_SHIFT)
+ BUG_ON(!pgtable_page_ctor(virt_to_page(ptr)));
+ else if (shift == PMD_SHIFT)
+ BUG_ON(!pgtable_pmd_page_ctor(virt_to_page(ptr)));
/* Ensure the zeroed page is visible to the page table walker */
dsb(ishst);
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 1/4] arm64: mm: use appropriate ctors for page tables
@ 2019-03-12 0:57 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: linux-arch, Yu Zhao, Ard Biesheuvel, Peter Zijlstra,
linux-kernel, Nick Piggin, Jun Yao, linux-mm, Aneesh Kumar K . V,
Chintan Pandya, Joel Fernandes, Kirill A . Shutemov,
Andrew Morton, Laura Abbott, linux-arm-kernel
For pte page, use pgtable_page_ctor(); for pmd page, use
pgtable_pmd_page_ctor(); and for the rest (pud, p4d and pgd),
don't use any.
For now, we don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK and
pgtable_pmd_page_ctor() is a nop. When we do in patch 3, we
make sure pmd is not folded so we won't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index b6f5aa52ac67..f704b291f2c5 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -98,7 +98,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
}
EXPORT_SYMBOL(phys_mem_access_prot);
-static phys_addr_t __init early_pgtable_alloc(void)
+static phys_addr_t __init early_pgtable_alloc(int shift)
{
phys_addr_t phys;
void *ptr;
@@ -173,7 +173,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -183,7 +183,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
if (pmd_none(pmd)) {
phys_addr_t pte_phys;
BUG_ON(!pgtable_alloc);
- pte_phys = pgtable_alloc();
+ pte_phys = pgtable_alloc(PAGE_SHIFT);
__pmd_populate(pmdp, pte_phys, PMD_TYPE_TABLE);
pmd = READ_ONCE(*pmdp);
}
@@ -207,7 +207,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pmd_t *pmdp;
@@ -245,7 +245,7 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pud_t pud = READ_ONCE(*pudp);
@@ -257,7 +257,7 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
if (pud_none(pud)) {
phys_addr_t pmd_phys;
BUG_ON(!pgtable_alloc);
- pmd_phys = pgtable_alloc();
+ pmd_phys = pgtable_alloc(PMD_SHIFT);
__pud_populate(pudp, pmd_phys, PUD_TYPE_TABLE);
pud = READ_ONCE(*pudp);
}
@@ -293,7 +293,7 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -303,7 +303,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
if (pgd_none(pgd)) {
phys_addr_t pud_phys;
BUG_ON(!pgtable_alloc);
- pud_phys = pgtable_alloc();
+ pud_phys = pgtable_alloc(PUD_SHIFT);
__pgd_populate(pgdp, pud_phys, PUD_TYPE_TABLE);
pgd = READ_ONCE(*pgdp);
}
@@ -344,7 +344,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long addr, length, end, next;
@@ -370,11 +370,23 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
-static phys_addr_t pgd_pgtable_alloc(void)
+static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
- if (!ptr || !pgtable_page_ctor(virt_to_page(ptr)))
- BUG();
+ BUG_ON(!ptr);
+
+ /*
+ * Call proper page table ctor in case later we need to
+ * call core mm functions like apply_to_page_range() on
+ * this pre-allocated page table.
+ *
+ * We don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK if pmd is
+ * folded, and if so pgtable_pmd_page_ctor() becomes nop.
+ */
+ if (shift == PAGE_SHIFT)
+ BUG_ON(!pgtable_page_ctor(virt_to_page(ptr)));
+ else if (shift == PMD_SHIFT)
+ BUG_ON(!pgtable_pmd_page_ctor(virt_to_page(ptr)));
/* Ensure the zeroed page is visible to the page table walker */
dsb(ishst);
--
2.21.0.360.g471c308f928-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 1/4] arm64: mm: use appropriate ctors for page tables
@ 2019-03-12 0:57 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
For pte page, use pgtable_page_ctor(); for pmd page, use
pgtable_pmd_page_ctor(); and for the rest (pud, p4d and pgd),
don't use any.
For now, we don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK and
pgtable_pmd_page_ctor() is a nop. When we do in patch 3, we
make sure pmd is not folded so we won't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index b6f5aa52ac67..f704b291f2c5 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -98,7 +98,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
}
EXPORT_SYMBOL(phys_mem_access_prot);
-static phys_addr_t __init early_pgtable_alloc(void)
+static phys_addr_t __init early_pgtable_alloc(int shift)
{
phys_addr_t phys;
void *ptr;
@@ -173,7 +173,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -183,7 +183,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
if (pmd_none(pmd)) {
phys_addr_t pte_phys;
BUG_ON(!pgtable_alloc);
- pte_phys = pgtable_alloc();
+ pte_phys = pgtable_alloc(PAGE_SHIFT);
__pmd_populate(pmdp, pte_phys, PMD_TYPE_TABLE);
pmd = READ_ONCE(*pmdp);
}
@@ -207,7 +207,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pmd_t *pmdp;
@@ -245,7 +245,7 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void), int flags)
+ phys_addr_t (*pgtable_alloc)(int), int flags)
{
unsigned long next;
pud_t pud = READ_ONCE(*pudp);
@@ -257,7 +257,7 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
if (pud_none(pud)) {
phys_addr_t pmd_phys;
BUG_ON(!pgtable_alloc);
- pmd_phys = pgtable_alloc();
+ pmd_phys = pgtable_alloc(PMD_SHIFT);
__pud_populate(pudp, pmd_phys, PUD_TYPE_TABLE);
pud = READ_ONCE(*pudp);
}
@@ -293,7 +293,7 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
@@ -303,7 +303,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
if (pgd_none(pgd)) {
phys_addr_t pud_phys;
BUG_ON(!pgtable_alloc);
- pud_phys = pgtable_alloc();
+ pud_phys = pgtable_alloc(PUD_SHIFT);
__pgd_populate(pgdp, pud_phys, PUD_TYPE_TABLE);
pgd = READ_ONCE(*pgdp);
}
@@ -344,7 +344,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void),
+ phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long addr, length, end, next;
@@ -370,11 +370,23 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
-static phys_addr_t pgd_pgtable_alloc(void)
+static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
- if (!ptr || !pgtable_page_ctor(virt_to_page(ptr)))
- BUG();
+ BUG_ON(!ptr);
+
+ /*
+ * Call proper page table ctor in case later we need to
+ * call core mm functions like apply_to_page_range() on
+ * this pre-allocated page table.
+ *
+ * We don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK if pmd is
+ * folded, and if so pgtable_pmd_page_ctor() becomes nop.
+ */
+ if (shift == PAGE_SHIFT)
+ BUG_ON(!pgtable_page_ctor(virt_to_page(ptr)));
+ else if (shift == PMD_SHIFT)
+ BUG_ON(!pgtable_pmd_page_ctor(virt_to_page(ptr)));
/* Ensure the zeroed page is visible to the page table walker */
dsb(ishst);
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 2/4] arm64: mm: don't call page table ctors for init_mm
2019-03-12 0:57 ` Yu Zhao
(?)
@ 2019-03-12 0:57 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
init_mm doesn't require page table lock to be initialized at
any level. Add a separate page table allocator for it, and the
new one skips page table ctors.
The ctors allocate memory when ALLOC_SPLIT_PTLOCKS is set. Not
calling them avoids memory leak in case we call pte_free_kernel()
on init_mm.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f704b291f2c5..d1dc2a2777aa 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -370,6 +370,16 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
+static phys_addr_t pgd_kernel_pgtable_alloc(int shift)
+{
+ void *ptr = (void *)__get_free_page(PGALLOC_GFP);
+ BUG_ON(!ptr);
+
+ /* Ensure the zeroed page is visible to the page table walker */
+ dsb(ishst);
+ return __pa(ptr);
+}
+
static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
@@ -594,7 +604,7 @@ static int __init map_entry_trampoline(void)
/* Map only the text into the trampoline page table */
memset(tramp_pg_dir, 0, PGD_SIZE);
__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
- prot, pgd_pgtable_alloc, 0);
+ prot, pgd_kernel_pgtable_alloc, 0);
/* Map both the text and data into the kernel page table */
__set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
@@ -1070,7 +1080,8 @@ int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
- size, PAGE_KERNEL, pgd_pgtable_alloc, flags);
+ size, PAGE_KERNEL, pgd_kernel_pgtable_alloc,
+ flags);
return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT,
altmap, want_memblock);
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 2/4] arm64: mm: don't call page table ctors for init_mm
@ 2019-03-12 0:57 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: linux-arch, Yu Zhao, Ard Biesheuvel, Peter Zijlstra,
linux-kernel, Nick Piggin, Jun Yao, linux-mm, Aneesh Kumar K . V,
Chintan Pandya, Joel Fernandes, Kirill A . Shutemov,
Andrew Morton, Laura Abbott, linux-arm-kernel
init_mm doesn't require page table lock to be initialized at
any level. Add a separate page table allocator for it, and the
new one skips page table ctors.
The ctors allocate memory when ALLOC_SPLIT_PTLOCKS is set. Not
calling them avoids memory leak in case we call pte_free_kernel()
on init_mm.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f704b291f2c5..d1dc2a2777aa 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -370,6 +370,16 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
+static phys_addr_t pgd_kernel_pgtable_alloc(int shift)
+{
+ void *ptr = (void *)__get_free_page(PGALLOC_GFP);
+ BUG_ON(!ptr);
+
+ /* Ensure the zeroed page is visible to the page table walker */
+ dsb(ishst);
+ return __pa(ptr);
+}
+
static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
@@ -594,7 +604,7 @@ static int __init map_entry_trampoline(void)
/* Map only the text into the trampoline page table */
memset(tramp_pg_dir, 0, PGD_SIZE);
__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
- prot, pgd_pgtable_alloc, 0);
+ prot, pgd_kernel_pgtable_alloc, 0);
/* Map both the text and data into the kernel page table */
__set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
@@ -1070,7 +1080,8 @@ int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
- size, PAGE_KERNEL, pgd_pgtable_alloc, flags);
+ size, PAGE_KERNEL, pgd_kernel_pgtable_alloc,
+ flags);
return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT,
altmap, want_memblock);
--
2.21.0.360.g471c308f928-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 2/4] arm64: mm: don't call page table ctors for init_mm
@ 2019-03-12 0:57 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
init_mm doesn't require page table lock to be initialized at
any level. Add a separate page table allocator for it, and the
new one skips page table ctors.
The ctors allocate memory when ALLOC_SPLIT_PTLOCKS is set. Not
calling them avoids memory leak in case we call pte_free_kernel()
on init_mm.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/mm/mmu.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f704b291f2c5..d1dc2a2777aa 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -370,6 +370,16 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
} while (pgdp++, addr = next, addr != end);
}
+static phys_addr_t pgd_kernel_pgtable_alloc(int shift)
+{
+ void *ptr = (void *)__get_free_page(PGALLOC_GFP);
+ BUG_ON(!ptr);
+
+ /* Ensure the zeroed page is visible to the page table walker */
+ dsb(ishst);
+ return __pa(ptr);
+}
+
static phys_addr_t pgd_pgtable_alloc(int shift)
{
void *ptr = (void *)__get_free_page(PGALLOC_GFP);
@@ -594,7 +604,7 @@ static int __init map_entry_trampoline(void)
/* Map only the text into the trampoline page table */
memset(tramp_pg_dir, 0, PGD_SIZE);
__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
- prot, pgd_pgtable_alloc, 0);
+ prot, pgd_kernel_pgtable_alloc, 0);
/* Map both the text and data into the kernel page table */
__set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
@@ -1070,7 +1080,8 @@ int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
- size, PAGE_KERNEL, pgd_pgtable_alloc, flags);
+ size, PAGE_KERNEL, pgd_kernel_pgtable_alloc,
+ flags);
return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT,
altmap, want_memblock);
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 3/4] arm64: mm: call ctor for stage2 pmd page
2019-03-12 0:57 ` Yu Zhao
(?)
@ 2019-03-12 0:57 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
Call pgtable_pmd_page_dtor() for pmd page allocated by
mmu_memory_cache_alloc() so kernel won't crash when it's freed
through stage2_pmd_free()->pmd_free()->pgtable_pmd_page_dtor().
This is needed if we are going to enable split pmd pt lock.
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/include/asm/stage2_pgtable.h | 15 ++++++++++++---
virt/kvm/arm/mmu.c | 13 +++++++++++--
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
index 5412fa40825e..0d9207144257 100644
--- a/arch/arm64/include/asm/stage2_pgtable.h
+++ b/arch/arm64/include/asm/stage2_pgtable.h
@@ -174,10 +174,19 @@ static inline bool stage2_pud_present(struct kvm *kvm, pud_t pud)
return 1;
}
-static inline void stage2_pud_populate(struct kvm *kvm, pud_t *pud, pmd_t *pmd)
+static inline int stage2_pud_populate(struct kvm *kvm, pud_t *pud, pmd_t *pmd)
{
- if (kvm_stage2_has_pmd(kvm))
- pud_populate(NULL, pud, pmd);
+ if (!kvm_stage2_has_pmd(kvm))
+ return 0;
+
+ /* paired with pgtable_pmd_page_dtor() in pmd_free() below */
+ if (!pgtable_pmd_page_ctor(virt_to_page(pmd))) {
+ free_page((unsigned long)pmd);
+ return -ENOMEM;
+ }
+
+ pud_populate(NULL, pud, pmd);
+ return 0;
}
static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index e9d28a7ca673..11922d84be83 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1037,6 +1037,7 @@ static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
phys_addr_t addr)
{
+ int ret;
pud_t *pud;
pmd_t *pmd;
@@ -1048,7 +1049,9 @@ static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
if (!cache)
return NULL;
pmd = mmu_memory_cache_alloc(cache);
- stage2_pud_populate(kvm, pud, pmd);
+ ret = stage2_pud_populate(kvm, pud, pmd);
+ if (ret)
+ return ERR_PTR(ret);
get_page(virt_to_page(pud));
}
@@ -1061,6 +1064,9 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
pmd_t *pmd, old_pmd;
pmd = stage2_get_pmd(kvm, cache, addr);
+ if (IS_ERR(pmd))
+ return PTR_ERR(pmd);
+
VM_BUG_ON(!pmd);
old_pmd = *pmd;
@@ -1198,6 +1204,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
phys_addr_t addr, const pte_t *new_pte,
unsigned long flags)
{
+ int ret;
pud_t *pud;
pmd_t *pmd;
pte_t *pte, old_pte;
@@ -1227,7 +1234,9 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
if (!cache)
return 0; /* ignore calls from kvm_set_spte_hva */
pmd = mmu_memory_cache_alloc(cache);
- stage2_pud_populate(kvm, pud, pmd);
+ ret = stage2_pud_populate(kvm, pud, pmd);
+ if (ret)
+ return ret;
get_page(virt_to_page(pud));
}
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 3/4] arm64: mm: call ctor for stage2 pmd page
@ 2019-03-12 0:57 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: linux-arch, Yu Zhao, Ard Biesheuvel, Peter Zijlstra,
linux-kernel, Nick Piggin, Jun Yao, linux-mm, Aneesh Kumar K . V,
Chintan Pandya, Joel Fernandes, Kirill A . Shutemov,
Andrew Morton, Laura Abbott, linux-arm-kernel
Call pgtable_pmd_page_dtor() for pmd page allocated by
mmu_memory_cache_alloc() so kernel won't crash when it's freed
through stage2_pmd_free()->pmd_free()->pgtable_pmd_page_dtor().
This is needed if we are going to enable split pmd pt lock.
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/include/asm/stage2_pgtable.h | 15 ++++++++++++---
virt/kvm/arm/mmu.c | 13 +++++++++++--
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
index 5412fa40825e..0d9207144257 100644
--- a/arch/arm64/include/asm/stage2_pgtable.h
+++ b/arch/arm64/include/asm/stage2_pgtable.h
@@ -174,10 +174,19 @@ static inline bool stage2_pud_present(struct kvm *kvm, pud_t pud)
return 1;
}
-static inline void stage2_pud_populate(struct kvm *kvm, pud_t *pud, pmd_t *pmd)
+static inline int stage2_pud_populate(struct kvm *kvm, pud_t *pud, pmd_t *pmd)
{
- if (kvm_stage2_has_pmd(kvm))
- pud_populate(NULL, pud, pmd);
+ if (!kvm_stage2_has_pmd(kvm))
+ return 0;
+
+ /* paired with pgtable_pmd_page_dtor() in pmd_free() below */
+ if (!pgtable_pmd_page_ctor(virt_to_page(pmd))) {
+ free_page((unsigned long)pmd);
+ return -ENOMEM;
+ }
+
+ pud_populate(NULL, pud, pmd);
+ return 0;
}
static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index e9d28a7ca673..11922d84be83 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1037,6 +1037,7 @@ static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
phys_addr_t addr)
{
+ int ret;
pud_t *pud;
pmd_t *pmd;
@@ -1048,7 +1049,9 @@ static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
if (!cache)
return NULL;
pmd = mmu_memory_cache_alloc(cache);
- stage2_pud_populate(kvm, pud, pmd);
+ ret = stage2_pud_populate(kvm, pud, pmd);
+ if (ret)
+ return ERR_PTR(ret);
get_page(virt_to_page(pud));
}
@@ -1061,6 +1064,9 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
pmd_t *pmd, old_pmd;
pmd = stage2_get_pmd(kvm, cache, addr);
+ if (IS_ERR(pmd))
+ return PTR_ERR(pmd);
+
VM_BUG_ON(!pmd);
old_pmd = *pmd;
@@ -1198,6 +1204,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
phys_addr_t addr, const pte_t *new_pte,
unsigned long flags)
{
+ int ret;
pud_t *pud;
pmd_t *pmd;
pte_t *pte, old_pte;
@@ -1227,7 +1234,9 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
if (!cache)
return 0; /* ignore calls from kvm_set_spte_hva */
pmd = mmu_memory_cache_alloc(cache);
- stage2_pud_populate(kvm, pud, pmd);
+ ret = stage2_pud_populate(kvm, pud, pmd);
+ if (ret)
+ return ret;
get_page(virt_to_page(pud));
}
--
2.21.0.360.g471c308f928-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 3/4] arm64: mm: call ctor for stage2 pmd page
@ 2019-03-12 0:57 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
Call pgtable_pmd_page_dtor() for pmd page allocated by
mmu_memory_cache_alloc() so kernel won't crash when it's freed
through stage2_pmd_free()->pmd_free()->pgtable_pmd_page_dtor().
This is needed if we are going to enable split pmd pt lock.
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/include/asm/stage2_pgtable.h | 15 ++++++++++++---
virt/kvm/arm/mmu.c | 13 +++++++++++--
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
index 5412fa40825e..0d9207144257 100644
--- a/arch/arm64/include/asm/stage2_pgtable.h
+++ b/arch/arm64/include/asm/stage2_pgtable.h
@@ -174,10 +174,19 @@ static inline bool stage2_pud_present(struct kvm *kvm, pud_t pud)
return 1;
}
-static inline void stage2_pud_populate(struct kvm *kvm, pud_t *pud, pmd_t *pmd)
+static inline int stage2_pud_populate(struct kvm *kvm, pud_t *pud, pmd_t *pmd)
{
- if (kvm_stage2_has_pmd(kvm))
- pud_populate(NULL, pud, pmd);
+ if (!kvm_stage2_has_pmd(kvm))
+ return 0;
+
+ /* paired with pgtable_pmd_page_dtor() in pmd_free() below */
+ if (!pgtable_pmd_page_ctor(virt_to_page(pmd))) {
+ free_page((unsigned long)pmd);
+ return -ENOMEM;
+ }
+
+ pud_populate(NULL, pud, pmd);
+ return 0;
}
static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index e9d28a7ca673..11922d84be83 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1037,6 +1037,7 @@ static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
phys_addr_t addr)
{
+ int ret;
pud_t *pud;
pmd_t *pmd;
@@ -1048,7 +1049,9 @@ static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
if (!cache)
return NULL;
pmd = mmu_memory_cache_alloc(cache);
- stage2_pud_populate(kvm, pud, pmd);
+ ret = stage2_pud_populate(kvm, pud, pmd);
+ if (ret)
+ return ERR_PTR(ret);
get_page(virt_to_page(pud));
}
@@ -1061,6 +1064,9 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
pmd_t *pmd, old_pmd;
pmd = stage2_get_pmd(kvm, cache, addr);
+ if (IS_ERR(pmd))
+ return PTR_ERR(pmd);
+
VM_BUG_ON(!pmd);
old_pmd = *pmd;
@@ -1198,6 +1204,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
phys_addr_t addr, const pte_t *new_pte,
unsigned long flags)
{
+ int ret;
pud_t *pud;
pmd_t *pmd;
pte_t *pte, old_pte;
@@ -1227,7 +1234,9 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
if (!cache)
return 0; /* ignore calls from kvm_set_spte_hva */
pmd = mmu_memory_cache_alloc(cache);
- stage2_pud_populate(kvm, pud, pmd);
+ ret = stage2_pud_populate(kvm, pud, pmd);
+ if (ret)
+ return ret;
get_page(virt_to_page(pud));
}
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-03-12 0:57 ` Yu Zhao
@ 2019-03-12 2:19 ` Anshuman Khandual
-1 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-12 2:19 UTC (permalink / raw)
To: catalin.marinas, will.deacon, mark.rutland, yuzhao
Cc: linux-mm, linux-arm-kernel
ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
pte_free_kernel(). These will fail once they start calling into pgtable_
[pmd]_page_dtor() for pages which never originally went through respective
constructor functions. Hence convert all stage-2 page table page release
functions to call buddy directly while freeing pages.
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/arm/include/asm/stage2_pgtable.h | 4 ++--
arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
virt/kvm/arm/mmu.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
index de2089501b8b..417a3be00718 100644
--- a/arch/arm/include/asm/stage2_pgtable.h
+++ b/arch/arm/include/asm/stage2_pgtable.h
@@ -32,14 +32,14 @@
#define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
#define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
#define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
-#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
+#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
#define stage2_pud_none(kvm, pud) pud_none(pud)
#define stage2_pud_clear(kvm, pud) pud_clear(pud)
#define stage2_pud_present(kvm, pud) pud_present(pud)
#define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
#define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
-#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
+#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
#define stage2_pud_huge(kvm, pud) pud_huge(pud)
diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
index 5412fa40825e..915809e4ac32 100644
--- a/arch/arm64/include/asm/stage2_pgtable.h
+++ b/arch/arm64/include/asm/stage2_pgtable.h
@@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
{
if (kvm_stage2_has_pud(kvm))
- pud_free(NULL, pud);
+ free_page((unsigned long)pud);
}
static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
@@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
{
if (kvm_stage2_has_pmd(kvm))
- pmd_free(NULL, pmd);
+ free_page((unsigned long)pmd);
}
static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index e9d28a7ca673..00bd79a2f0b1 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
VM_BUG_ON(pmd_thp_or_huge(*pmd));
pmd_clear(pmd);
kvm_tlb_flush_vmid_ipa(kvm, addr);
- pte_free_kernel(NULL, pte_table);
+ __free_page(virt_to_page(pte_table));
put_page(virt_to_page(pmd));
}
--
2.20.1
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-03-12 2:19 ` Anshuman Khandual
0 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-12 2:19 UTC (permalink / raw)
To: catalin.marinas, will.deacon, mark.rutland, yuzhao
Cc: linux-mm, linux-arm-kernel
ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
pte_free_kernel(). These will fail once they start calling into pgtable_
[pmd]_page_dtor() for pages which never originally went through respective
constructor functions. Hence convert all stage-2 page table page release
functions to call buddy directly while freeing pages.
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/arm/include/asm/stage2_pgtable.h | 4 ++--
arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
virt/kvm/arm/mmu.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
index de2089501b8b..417a3be00718 100644
--- a/arch/arm/include/asm/stage2_pgtable.h
+++ b/arch/arm/include/asm/stage2_pgtable.h
@@ -32,14 +32,14 @@
#define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
#define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
#define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
-#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
+#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
#define stage2_pud_none(kvm, pud) pud_none(pud)
#define stage2_pud_clear(kvm, pud) pud_clear(pud)
#define stage2_pud_present(kvm, pud) pud_present(pud)
#define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
#define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
-#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
+#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
#define stage2_pud_huge(kvm, pud) pud_huge(pud)
diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
index 5412fa40825e..915809e4ac32 100644
--- a/arch/arm64/include/asm/stage2_pgtable.h
+++ b/arch/arm64/include/asm/stage2_pgtable.h
@@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
{
if (kvm_stage2_has_pud(kvm))
- pud_free(NULL, pud);
+ free_page((unsigned long)pud);
}
static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
@@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
{
if (kvm_stage2_has_pmd(kvm))
- pmd_free(NULL, pmd);
+ free_page((unsigned long)pmd);
}
static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index e9d28a7ca673..00bd79a2f0b1 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
VM_BUG_ON(pmd_thp_or_huge(*pmd));
pmd_clear(pmd);
kvm_tlb_flush_vmid_ipa(kvm, addr);
- pte_free_kernel(NULL, pte_table);
+ __free_page(virt_to_page(pte_table));
put_page(virt_to_page(pmd));
}
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 120+ messages in thread
* Re: [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-03-12 2:19 ` Anshuman Khandual
@ 2019-03-12 2:40 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 2:40 UTC (permalink / raw)
To: Anshuman Khandual
Cc: catalin.marinas, will.deacon, mark.rutland, linux-mm, linux-arm-kernel
On Tue, Mar 12, 2019 at 07:49:02AM +0530, Anshuman Khandual wrote:
> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> pte_free_kernel(). These will fail once they start calling into pgtable_
> [pmd]_page_dtor() for pages which never originally went through respective
> constructor functions. Hence convert all stage-2 page table page release
> functions to call buddy directly while freeing pages.
This is apparently cleaner than what I have done.
Acked-by: Yu Zhao <yuzhao@google.com>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> virt/kvm/arm/mmu.c | 2 +-
> 3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> index de2089501b8b..417a3be00718 100644
> --- a/arch/arm/include/asm/stage2_pgtable.h
> +++ b/arch/arm/include/asm/stage2_pgtable.h
> @@ -32,14 +32,14 @@
> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> +#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
>
> #define stage2_pud_none(kvm, pud) pud_none(pud)
> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> #define stage2_pud_present(kvm, pud) pud_present(pud)
> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>
> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>
> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> index 5412fa40825e..915809e4ac32 100644
> --- a/arch/arm64/include/asm/stage2_pgtable.h
> +++ b/arch/arm64/include/asm/stage2_pgtable.h
> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> {
> if (kvm_stage2_has_pud(kvm))
> - pud_free(NULL, pud);
> + free_page((unsigned long)pud);
> }
>
> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> {
> if (kvm_stage2_has_pmd(kvm))
> - pmd_free(NULL, pmd);
> + free_page((unsigned long)pmd);
> }
>
> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index e9d28a7ca673..00bd79a2f0b1 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> VM_BUG_ON(pmd_thp_or_huge(*pmd));
> pmd_clear(pmd);
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - pte_free_kernel(NULL, pte_table);
> + __free_page(virt_to_page(pte_table));
> put_page(virt_to_page(pmd));
> }
>
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-03-12 2:40 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 2:40 UTC (permalink / raw)
To: Anshuman Khandual
Cc: mark.rutland, catalin.marinas, will.deacon, linux-arm-kernel, linux-mm
On Tue, Mar 12, 2019 at 07:49:02AM +0530, Anshuman Khandual wrote:
> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> pte_free_kernel(). These will fail once they start calling into pgtable_
> [pmd]_page_dtor() for pages which never originally went through respective
> constructor functions. Hence convert all stage-2 page table page release
> functions to call buddy directly while freeing pages.
This is apparently cleaner than what I have done.
Acked-by: Yu Zhao <yuzhao@google.com>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> virt/kvm/arm/mmu.c | 2 +-
> 3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> index de2089501b8b..417a3be00718 100644
> --- a/arch/arm/include/asm/stage2_pgtable.h
> +++ b/arch/arm/include/asm/stage2_pgtable.h
> @@ -32,14 +32,14 @@
> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> +#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
>
> #define stage2_pud_none(kvm, pud) pud_none(pud)
> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> #define stage2_pud_present(kvm, pud) pud_present(pud)
> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>
> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>
> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> index 5412fa40825e..915809e4ac32 100644
> --- a/arch/arm64/include/asm/stage2_pgtable.h
> +++ b/arch/arm64/include/asm/stage2_pgtable.h
> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> {
> if (kvm_stage2_has_pud(kvm))
> - pud_free(NULL, pud);
> + free_page((unsigned long)pud);
> }
>
> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> {
> if (kvm_stage2_has_pmd(kvm))
> - pmd_free(NULL, pmd);
> + free_page((unsigned long)pmd);
> }
>
> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index e9d28a7ca673..00bd79a2f0b1 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> VM_BUG_ON(pmd_thp_or_huge(*pmd));
> pmd_clear(pmd);
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - pte_free_kernel(NULL, pte_table);
> + __free_page(virt_to_page(pte_table));
> put_page(virt_to_page(pmd));
> }
>
> --
> 2.20.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-03-12 2:19 ` Anshuman Khandual
@ 2019-03-12 10:37 ` Suzuki K Poulose
-1 siblings, 0 replies; 120+ messages in thread
From: Suzuki K Poulose @ 2019-03-12 10:37 UTC (permalink / raw)
To: anshuman.khandual, catalin.marinas, will.deacon, mark.rutland, yuzhao
Cc: linux-mm, linux-arm-kernel
Hi Anshuman,
On 12/03/2019 02:19, Anshuman Khandual wrote:
> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> pte_free_kernel(). These will fail once they start calling into pgtable_
> [pmd]_page_dtor() for pages which never originally went through respective
> constructor functions. Hence convert all stage-2 page table page release
> functions to call buddy directly while freeing pages.
>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> virt/kvm/arm/mmu.c | 2 +-
> 3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> index de2089501b8b..417a3be00718 100644
> --- a/arch/arm/include/asm/stage2_pgtable.h
> +++ b/arch/arm/include/asm/stage2_pgtable.h
> @@ -32,14 +32,14 @@
> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> +#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
That must be a NOP, as we don't have pud on arm32 (we have 3 level table).
The pud_* helpers here all fallback to the generic no-pud helpers.
>
> #define stage2_pud_none(kvm, pud) pud_none(pud)
> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> #define stage2_pud_present(kvm, pud) pud_present(pud)
> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>
> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>
> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> index 5412fa40825e..915809e4ac32 100644
> --- a/arch/arm64/include/asm/stage2_pgtable.h
> +++ b/arch/arm64/include/asm/stage2_pgtable.h
> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> {
> if (kvm_stage2_has_pud(kvm))
> - pud_free(NULL, pud);
> + free_page((unsigned long)pud);
> }
>
> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> {
> if (kvm_stage2_has_pmd(kvm))
> - pmd_free(NULL, pmd);
> + free_page((unsigned long)pmd);
> }
>
> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index e9d28a7ca673..00bd79a2f0b1 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> VM_BUG_ON(pmd_thp_or_huge(*pmd));
> pmd_clear(pmd);
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - pte_free_kernel(NULL, pte_table);
> + __free_page(virt_to_page(pte_table));
> put_page(virt_to_page(pmd));
> }
>
With that fixed,
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-03-12 10:37 ` Suzuki K Poulose
0 siblings, 0 replies; 120+ messages in thread
From: Suzuki K Poulose @ 2019-03-12 10:37 UTC (permalink / raw)
To: anshuman.khandual, catalin.marinas, will.deacon, mark.rutland, yuzhao
Cc: linux-mm, linux-arm-kernel
Hi Anshuman,
On 12/03/2019 02:19, Anshuman Khandual wrote:
> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> pte_free_kernel(). These will fail once they start calling into pgtable_
> [pmd]_page_dtor() for pages which never originally went through respective
> constructor functions. Hence convert all stage-2 page table page release
> functions to call buddy directly while freeing pages.
>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> virt/kvm/arm/mmu.c | 2 +-
> 3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> index de2089501b8b..417a3be00718 100644
> --- a/arch/arm/include/asm/stage2_pgtable.h
> +++ b/arch/arm/include/asm/stage2_pgtable.h
> @@ -32,14 +32,14 @@
> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> +#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
That must be a NOP, as we don't have pud on arm32 (we have 3 level table).
The pud_* helpers here all fallback to the generic no-pud helpers.
>
> #define stage2_pud_none(kvm, pud) pud_none(pud)
> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> #define stage2_pud_present(kvm, pud) pud_present(pud)
> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>
> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>
> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> index 5412fa40825e..915809e4ac32 100644
> --- a/arch/arm64/include/asm/stage2_pgtable.h
> +++ b/arch/arm64/include/asm/stage2_pgtable.h
> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> {
> if (kvm_stage2_has_pud(kvm))
> - pud_free(NULL, pud);
> + free_page((unsigned long)pud);
> }
>
> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> {
> if (kvm_stage2_has_pmd(kvm))
> - pmd_free(NULL, pmd);
> + free_page((unsigned long)pmd);
> }
>
> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index e9d28a7ca673..00bd79a2f0b1 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> VM_BUG_ON(pmd_thp_or_huge(*pmd));
> pmd_clear(pmd);
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - pte_free_kernel(NULL, pte_table);
> + __free_page(virt_to_page(pte_table));
> put_page(virt_to_page(pmd));
> }
>
With that fixed,
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-03-12 10:37 ` Suzuki K Poulose
@ 2019-03-12 11:31 ` Anshuman Khandual
-1 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-12 11:31 UTC (permalink / raw)
To: Suzuki K Poulose, catalin.marinas, will.deacon, mark.rutland, yuzhao
Cc: linux-mm, linux-arm-kernel
On 03/12/2019 04:07 PM, Suzuki K Poulose wrote:
> Hi Anshuman,
>
> On 12/03/2019 02:19, Anshuman Khandual wrote:
>> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
>> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
>> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
>> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
>> pte_free_kernel(). These will fail once they start calling into pgtable_
>> [pmd]_page_dtor() for pages which never originally went through respective
>> constructor functions. Hence convert all stage-2 page table page release
>> functions to call buddy directly while freeing pages.
>>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
>> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
>> virt/kvm/arm/mmu.c | 2 +-
>> 3 files changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
>> index de2089501b8b..417a3be00718 100644
>> --- a/arch/arm/include/asm/stage2_pgtable.h
>> +++ b/arch/arm/include/asm/stage2_pgtable.h
>> @@ -32,14 +32,14 @@
>> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
>> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
>> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
>> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
>> +#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
>
> That must be a NOP, as we don't have pud on arm32 (we have 3 level table).
> The pud_* helpers here all fallback to the generic no-pud helpers.
Which is the following here for pud_free()
#define pud_free(mm, x) do { } while (0)
On arm64 its protected by kvm_stage2_has_pud() helper before calling into pud_free().
In this case even though applicable pud_free() is NOP, it is still misleading. If we
are sure about page table level will always remain three it can directly have a NOP
(do/while) in there.
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-03-12 11:31 ` Anshuman Khandual
0 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-12 11:31 UTC (permalink / raw)
To: Suzuki K Poulose, catalin.marinas, will.deacon, mark.rutland, yuzhao
Cc: linux-mm, linux-arm-kernel
On 03/12/2019 04:07 PM, Suzuki K Poulose wrote:
> Hi Anshuman,
>
> On 12/03/2019 02:19, Anshuman Khandual wrote:
>> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
>> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
>> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
>> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
>> pte_free_kernel(). These will fail once they start calling into pgtable_
>> [pmd]_page_dtor() for pages which never originally went through respective
>> constructor functions. Hence convert all stage-2 page table page release
>> functions to call buddy directly while freeing pages.
>>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
>> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
>> virt/kvm/arm/mmu.c | 2 +-
>> 3 files changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
>> index de2089501b8b..417a3be00718 100644
>> --- a/arch/arm/include/asm/stage2_pgtable.h
>> +++ b/arch/arm/include/asm/stage2_pgtable.h
>> @@ -32,14 +32,14 @@
>> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
>> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
>> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
>> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
>> +#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
>
> That must be a NOP, as we don't have pud on arm32 (we have 3 level table).
> The pud_* helpers here all fallback to the generic no-pud helpers.
Which is the following here for pud_free()
#define pud_free(mm, x) do { } while (0)
On arm64 its protected by kvm_stage2_has_pud() helper before calling into pud_free().
In this case even though applicable pud_free() is NOP, it is still misleading. If we
are sure about page table level will always remain three it can directly have a NOP
(do/while) in there.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-03-12 11:31 ` Anshuman Khandual
@ 2019-03-12 11:43 ` Suzuki K Poulose
-1 siblings, 0 replies; 120+ messages in thread
From: Suzuki K Poulose @ 2019-03-12 11:43 UTC (permalink / raw)
To: anshuman.khandual, catalin.marinas, will.deacon, mark.rutland, yuzhao
Cc: linux-mm, linux-arm-kernel
On 12/03/2019 11:31, Anshuman Khandual wrote:
>
>
> On 03/12/2019 04:07 PM, Suzuki K Poulose wrote:
>> Hi Anshuman,
>>
>> On 12/03/2019 02:19, Anshuman Khandual wrote:
>>> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
>>> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
>>> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
>>> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
>>> pte_free_kernel(). These will fail once they start calling into pgtable_
>>> [pmd]_page_dtor() for pages which never originally went through respective
>>> constructor functions. Hence convert all stage-2 page table page release
>>> functions to call buddy directly while freeing pages.
>>>
>>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>>> ---
>>> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
>>> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
>>> virt/kvm/arm/mmu.c | 2 +-
>>> 3 files changed, 5 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
>>> index de2089501b8b..417a3be00718 100644
>>> --- a/arch/arm/include/asm/stage2_pgtable.h
>>> +++ b/arch/arm/include/asm/stage2_pgtable.h
>>> @@ -32,14 +32,14 @@
>>> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
>>> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
>>> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
>>> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
>>> +#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
>>
>> That must be a NOP, as we don't have pud on arm32 (we have 3 level table).
>> The pud_* helpers here all fallback to the generic no-pud helpers.
> Which is the following here for pud_free()
>
> #define pud_free(mm, x) do { } while (0)
>
> On arm64 its protected by kvm_stage2_has_pud() helper before calling into pud_free().
> In this case even though applicable pud_free() is NOP, it is still misleading. If we
> are sure about page table level will always remain three it can directly have a NOP
> (do/while) in there.
>
Yes, it is fixed for arm32 and you could have it as do {} while (0), which is
what I meant by NOP. On arm64, we had varied number of levels depending on the
PAGE_SIZE and now due to the dynamic IPA, hence the check.
Cheers
Suzuki
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-03-12 11:43 ` Suzuki K Poulose
0 siblings, 0 replies; 120+ messages in thread
From: Suzuki K Poulose @ 2019-03-12 11:43 UTC (permalink / raw)
To: anshuman.khandual, catalin.marinas, will.deacon, mark.rutland, yuzhao
Cc: linux-mm, linux-arm-kernel
On 12/03/2019 11:31, Anshuman Khandual wrote:
>
>
> On 03/12/2019 04:07 PM, Suzuki K Poulose wrote:
>> Hi Anshuman,
>>
>> On 12/03/2019 02:19, Anshuman Khandual wrote:
>>> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
>>> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
>>> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
>>> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
>>> pte_free_kernel(). These will fail once they start calling into pgtable_
>>> [pmd]_page_dtor() for pages which never originally went through respective
>>> constructor functions. Hence convert all stage-2 page table page release
>>> functions to call buddy directly while freeing pages.
>>>
>>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>>> ---
>>> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
>>> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
>>> virt/kvm/arm/mmu.c | 2 +-
>>> 3 files changed, 5 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
>>> index de2089501b8b..417a3be00718 100644
>>> --- a/arch/arm/include/asm/stage2_pgtable.h
>>> +++ b/arch/arm/include/asm/stage2_pgtable.h
>>> @@ -32,14 +32,14 @@
>>> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
>>> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
>>> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
>>> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
>>> +#define stage2_pud_free(kvm, pud) free_page((unsigned long)pud)
>>
>> That must be a NOP, as we don't have pud on arm32 (we have 3 level table).
>> The pud_* helpers here all fallback to the generic no-pud helpers.
> Which is the following here for pud_free()
>
> #define pud_free(mm, x) do { } while (0)
>
> On arm64 its protected by kvm_stage2_has_pud() helper before calling into pud_free().
> In this case even though applicable pud_free() is NOP, it is still misleading. If we
> are sure about page table level will always remain three it can directly have a NOP
> (do/while) in there.
>
Yes, it is fixed for arm32 and you could have it as do {} while (0), which is
what I meant by NOP. On arm64, we had varied number of levels depending on the
PAGE_SIZE and now due to the dynamic IPA, hence the check.
Cheers
Suzuki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-03-12 11:43 ` Suzuki K Poulose
@ 2019-03-12 13:25 ` Anshuman Khandual
-1 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-12 13:25 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel
Cc: catalin.marinas, will.deacon, mark.rutland, yuzhao, suzuki.poulose
ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
pte_free_kernel(). These will fail once they start calling into pgtable_
[pmd]_page_dtor() for pages which never originally went through respective
constructor functions. Hence convert all stage-2 page table page release
functions to call buddy directly while freeing pages.
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Acked-by: Yu Zhao <yuzhao@google.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
Changes in V2:
- Updated stage2_pud_free() with NOP as per Suzuki
- s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
arch/arm/include/asm/stage2_pgtable.h | 4 ++--
arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
virt/kvm/arm/mmu.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
index de2089501b8b..fed02c3b4600 100644
--- a/arch/arm/include/asm/stage2_pgtable.h
+++ b/arch/arm/include/asm/stage2_pgtable.h
@@ -32,14 +32,14 @@
#define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
#define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
#define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
-#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
+#define stage2_pud_free(kvm, pud) do { } while (0)
#define stage2_pud_none(kvm, pud) pud_none(pud)
#define stage2_pud_clear(kvm, pud) pud_clear(pud)
#define stage2_pud_present(kvm, pud) pud_present(pud)
#define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
#define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
-#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
+#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
#define stage2_pud_huge(kvm, pud) pud_huge(pud)
diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
index 5412fa40825e..915809e4ac32 100644
--- a/arch/arm64/include/asm/stage2_pgtable.h
+++ b/arch/arm64/include/asm/stage2_pgtable.h
@@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
{
if (kvm_stage2_has_pud(kvm))
- pud_free(NULL, pud);
+ free_page((unsigned long)pud);
}
static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
@@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
{
if (kvm_stage2_has_pmd(kvm))
- pmd_free(NULL, pmd);
+ free_page((unsigned long)pmd);
}
static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index e9d28a7ca673..cbfbdadca8a5 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
VM_BUG_ON(pmd_thp_or_huge(*pmd));
pmd_clear(pmd);
kvm_tlb_flush_vmid_ipa(kvm, addr);
- pte_free_kernel(NULL, pte_table);
+ free_page((unsigned long)pte_table);
put_page(virt_to_page(pmd));
}
--
2.20.1
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-03-12 13:25 ` Anshuman Khandual
0 siblings, 0 replies; 120+ messages in thread
From: Anshuman Khandual @ 2019-03-12 13:25 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel
Cc: mark.rutland, catalin.marinas, will.deacon, yuzhao, suzuki.poulose
ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
pte_free_kernel(). These will fail once they start calling into pgtable_
[pmd]_page_dtor() for pages which never originally went through respective
constructor functions. Hence convert all stage-2 page table page release
functions to call buddy directly while freeing pages.
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Acked-by: Yu Zhao <yuzhao@google.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
Changes in V2:
- Updated stage2_pud_free() with NOP as per Suzuki
- s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
arch/arm/include/asm/stage2_pgtable.h | 4 ++--
arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
virt/kvm/arm/mmu.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
index de2089501b8b..fed02c3b4600 100644
--- a/arch/arm/include/asm/stage2_pgtable.h
+++ b/arch/arm/include/asm/stage2_pgtable.h
@@ -32,14 +32,14 @@
#define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
#define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
#define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
-#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
+#define stage2_pud_free(kvm, pud) do { } while (0)
#define stage2_pud_none(kvm, pud) pud_none(pud)
#define stage2_pud_clear(kvm, pud) pud_clear(pud)
#define stage2_pud_present(kvm, pud) pud_present(pud)
#define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
#define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
-#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
+#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
#define stage2_pud_huge(kvm, pud) pud_huge(pud)
diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
index 5412fa40825e..915809e4ac32 100644
--- a/arch/arm64/include/asm/stage2_pgtable.h
+++ b/arch/arm64/include/asm/stage2_pgtable.h
@@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
{
if (kvm_stage2_has_pud(kvm))
- pud_free(NULL, pud);
+ free_page((unsigned long)pud);
}
static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
@@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
{
if (kvm_stage2_has_pmd(kvm))
- pmd_free(NULL, pmd);
+ free_page((unsigned long)pmd);
}
static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index e9d28a7ca673..cbfbdadca8a5 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
VM_BUG_ON(pmd_thp_or_huge(*pmd));
pmd_clear(pmd);
kvm_tlb_flush_vmid_ipa(kvm, addr);
- pte_free_kernel(NULL, pte_table);
+ free_page((unsigned long)pte_table);
put_page(virt_to_page(pmd));
}
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-03-12 13:25 ` Anshuman Khandual
(?)
@ 2019-04-01 16:16 ` Will Deacon
-1 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-01 16:16 UTC (permalink / raw)
To: Anshuman Khandual
Cc: linux-mm, linux-arm-kernel, catalin.marinas, mark.rutland,
yuzhao, suzuki.poulose, marc.zyngier, christoffer.dall,
james.morse, julien.thierry, kvmarm
[+KVM/ARM folks, since I can't take this without an Ack in place from them]
My understanding is that this patch is intended to replace patch 3/4 in
this series:
http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> pte_free_kernel(). These will fail once they start calling into pgtable_
> [pmd]_page_dtor() for pages which never originally went through respective
> constructor functions. Hence convert all stage-2 page table page release
> functions to call buddy directly while freeing pages.
>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Acked-by: Yu Zhao <yuzhao@google.com>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> Changes in V2:
>
> - Updated stage2_pud_free() with NOP as per Suzuki
> - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
>
> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> virt/kvm/arm/mmu.c | 2 +-
> 3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> index de2089501b8b..fed02c3b4600 100644
> --- a/arch/arm/include/asm/stage2_pgtable.h
> +++ b/arch/arm/include/asm/stage2_pgtable.h
> @@ -32,14 +32,14 @@
> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> +#define stage2_pud_free(kvm, pud) do { } while (0)
>
> #define stage2_pud_none(kvm, pud) pud_none(pud)
> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> #define stage2_pud_present(kvm, pud) pud_present(pud)
> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>
> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>
> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> index 5412fa40825e..915809e4ac32 100644
> --- a/arch/arm64/include/asm/stage2_pgtable.h
> +++ b/arch/arm64/include/asm/stage2_pgtable.h
> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> {
> if (kvm_stage2_has_pud(kvm))
> - pud_free(NULL, pud);
> + free_page((unsigned long)pud);
> }
>
> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> {
> if (kvm_stage2_has_pmd(kvm))
> - pmd_free(NULL, pmd);
> + free_page((unsigned long)pmd);
> }
>
> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index e9d28a7ca673..cbfbdadca8a5 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> VM_BUG_ON(pmd_thp_or_huge(*pmd));
> pmd_clear(pmd);
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - pte_free_kernel(NULL, pte_table);
> + free_page((unsigned long)pte_table);
> put_page(virt_to_page(pmd));
> }
>
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-01 16:16 ` Will Deacon
0 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-01 16:16 UTC (permalink / raw)
To: Anshuman Khandual
Cc: mark.rutland, yuzhao, suzuki.poulose, marc.zyngier,
catalin.marinas, julien.thierry, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
[+KVM/ARM folks, since I can't take this without an Ack in place from them]
My understanding is that this patch is intended to replace patch 3/4 in
this series:
http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> pte_free_kernel(). These will fail once they start calling into pgtable_
> [pmd]_page_dtor() for pages which never originally went through respective
> constructor functions. Hence convert all stage-2 page table page release
> functions to call buddy directly while freeing pages.
>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Acked-by: Yu Zhao <yuzhao@google.com>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> Changes in V2:
>
> - Updated stage2_pud_free() with NOP as per Suzuki
> - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
>
> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> virt/kvm/arm/mmu.c | 2 +-
> 3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> index de2089501b8b..fed02c3b4600 100644
> --- a/arch/arm/include/asm/stage2_pgtable.h
> +++ b/arch/arm/include/asm/stage2_pgtable.h
> @@ -32,14 +32,14 @@
> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> +#define stage2_pud_free(kvm, pud) do { } while (0)
>
> #define stage2_pud_none(kvm, pud) pud_none(pud)
> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> #define stage2_pud_present(kvm, pud) pud_present(pud)
> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>
> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>
> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> index 5412fa40825e..915809e4ac32 100644
> --- a/arch/arm64/include/asm/stage2_pgtable.h
> +++ b/arch/arm64/include/asm/stage2_pgtable.h
> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> {
> if (kvm_stage2_has_pud(kvm))
> - pud_free(NULL, pud);
> + free_page((unsigned long)pud);
> }
>
> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> {
> if (kvm_stage2_has_pmd(kvm))
> - pmd_free(NULL, pmd);
> + free_page((unsigned long)pmd);
> }
>
> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index e9d28a7ca673..cbfbdadca8a5 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> VM_BUG_ON(pmd_thp_or_huge(*pmd));
> pmd_clear(pmd);
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - pte_free_kernel(NULL, pte_table);
> + free_page((unsigned long)pte_table);
> put_page(virt_to_page(pmd));
> }
>
> --
> 2.20.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-01 16:16 ` Will Deacon
0 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-01 16:16 UTC (permalink / raw)
To: Anshuman Khandual
Cc: mark.rutland, yuzhao, suzuki.poulose, marc.zyngier,
catalin.marinas, julien.thierry, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
[+KVM/ARM folks, since I can't take this without an Ack in place from them]
My understanding is that this patch is intended to replace patch 3/4 in
this series:
http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> pte_free_kernel(). These will fail once they start calling into pgtable_
> [pmd]_page_dtor() for pages which never originally went through respective
> constructor functions. Hence convert all stage-2 page table page release
> functions to call buddy directly while freeing pages.
>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Acked-by: Yu Zhao <yuzhao@google.com>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> Changes in V2:
>
> - Updated stage2_pud_free() with NOP as per Suzuki
> - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
>
> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> virt/kvm/arm/mmu.c | 2 +-
> 3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> index de2089501b8b..fed02c3b4600 100644
> --- a/arch/arm/include/asm/stage2_pgtable.h
> +++ b/arch/arm/include/asm/stage2_pgtable.h
> @@ -32,14 +32,14 @@
> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> +#define stage2_pud_free(kvm, pud) do { } while (0)
>
> #define stage2_pud_none(kvm, pud) pud_none(pud)
> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> #define stage2_pud_present(kvm, pud) pud_present(pud)
> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>
> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>
> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> index 5412fa40825e..915809e4ac32 100644
> --- a/arch/arm64/include/asm/stage2_pgtable.h
> +++ b/arch/arm64/include/asm/stage2_pgtable.h
> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> {
> if (kvm_stage2_has_pud(kvm))
> - pud_free(NULL, pud);
> + free_page((unsigned long)pud);
> }
>
> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> {
> if (kvm_stage2_has_pmd(kvm))
> - pmd_free(NULL, pmd);
> + free_page((unsigned long)pmd);
> }
>
> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index e9d28a7ca673..cbfbdadca8a5 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> VM_BUG_ON(pmd_thp_or_huge(*pmd));
> pmd_clear(pmd);
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - pte_free_kernel(NULL, pte_table);
> + free_page((unsigned long)pte_table);
> put_page(virt_to_page(pmd));
> }
>
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-04-01 16:16 ` Will Deacon
(?)
@ 2019-04-01 18:34 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-04-01 18:34 UTC (permalink / raw)
To: Will Deacon
Cc: Anshuman Khandual, linux-mm, linux-arm-kernel, catalin.marinas,
mark.rutland, suzuki.poulose, marc.zyngier, christoffer.dall,
james.morse, julien.thierry, kvmarm
On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> [+KVM/ARM folks, since I can't take this without an Ack in place from them]
>
> My understanding is that this patch is intended to replace patch 3/4 in
> this series:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
Yes, and sorry for the confusion. I could send an updated series once
this patch is merged. Thanks.
> On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
> > ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> > or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> > PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> > via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> > pte_free_kernel(). These will fail once they start calling into pgtable_
> > [pmd]_page_dtor() for pages which never originally went through respective
> > constructor functions. Hence convert all stage-2 page table page release
> > functions to call buddy directly while freeing pages.
> >
> > Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > Acked-by: Yu Zhao <yuzhao@google.com>
> > Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> > ---
> > Changes in V2:
> >
> > - Updated stage2_pud_free() with NOP as per Suzuki
> > - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
> >
> > arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> > arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> > virt/kvm/arm/mmu.c | 2 +-
> > 3 files changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> > index de2089501b8b..fed02c3b4600 100644
> > --- a/arch/arm/include/asm/stage2_pgtable.h
> > +++ b/arch/arm/include/asm/stage2_pgtable.h
> > @@ -32,14 +32,14 @@
> > #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> > #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> > #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> > -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> > +#define stage2_pud_free(kvm, pud) do { } while (0)
> >
> > #define stage2_pud_none(kvm, pud) pud_none(pud)
> > #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> > #define stage2_pud_present(kvm, pud) pud_present(pud)
> > #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> > #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> > -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> > +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
> >
> > #define stage2_pud_huge(kvm, pud) pud_huge(pud)
> >
> > diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> > index 5412fa40825e..915809e4ac32 100644
> > --- a/arch/arm64/include/asm/stage2_pgtable.h
> > +++ b/arch/arm64/include/asm/stage2_pgtable.h
> > @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> > static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> > {
> > if (kvm_stage2_has_pud(kvm))
> > - pud_free(NULL, pud);
> > + free_page((unsigned long)pud);
> > }
> >
> > static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> > @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> > static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> > {
> > if (kvm_stage2_has_pmd(kvm))
> > - pmd_free(NULL, pmd);
> > + free_page((unsigned long)pmd);
> > }
> >
> > static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> > diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> > index e9d28a7ca673..cbfbdadca8a5 100644
> > --- a/virt/kvm/arm/mmu.c
> > +++ b/virt/kvm/arm/mmu.c
> > @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> > VM_BUG_ON(pmd_thp_or_huge(*pmd));
> > pmd_clear(pmd);
> > kvm_tlb_flush_vmid_ipa(kvm, addr);
> > - pte_free_kernel(NULL, pte_table);
> > + free_page((unsigned long)pte_table);
> > put_page(virt_to_page(pmd));
> > }
> >
> > --
> > 2.20.1
> >
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-01 18:34 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-04-01 18:34 UTC (permalink / raw)
To: Will Deacon
Cc: mark.rutland, julien.thierry, suzuki.poulose, marc.zyngier,
catalin.marinas, Anshuman Khandual, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> [+KVM/ARM folks, since I can't take this without an Ack in place from them]
>
> My understanding is that this patch is intended to replace patch 3/4 in
> this series:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
Yes, and sorry for the confusion. I could send an updated series once
this patch is merged. Thanks.
> On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
> > ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> > or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> > PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> > via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> > pte_free_kernel(). These will fail once they start calling into pgtable_
> > [pmd]_page_dtor() for pages which never originally went through respective
> > constructor functions. Hence convert all stage-2 page table page release
> > functions to call buddy directly while freeing pages.
> >
> > Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > Acked-by: Yu Zhao <yuzhao@google.com>
> > Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> > ---
> > Changes in V2:
> >
> > - Updated stage2_pud_free() with NOP as per Suzuki
> > - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
> >
> > arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> > arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> > virt/kvm/arm/mmu.c | 2 +-
> > 3 files changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> > index de2089501b8b..fed02c3b4600 100644
> > --- a/arch/arm/include/asm/stage2_pgtable.h
> > +++ b/arch/arm/include/asm/stage2_pgtable.h
> > @@ -32,14 +32,14 @@
> > #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> > #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> > #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> > -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> > +#define stage2_pud_free(kvm, pud) do { } while (0)
> >
> > #define stage2_pud_none(kvm, pud) pud_none(pud)
> > #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> > #define stage2_pud_present(kvm, pud) pud_present(pud)
> > #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> > #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> > -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> > +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
> >
> > #define stage2_pud_huge(kvm, pud) pud_huge(pud)
> >
> > diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> > index 5412fa40825e..915809e4ac32 100644
> > --- a/arch/arm64/include/asm/stage2_pgtable.h
> > +++ b/arch/arm64/include/asm/stage2_pgtable.h
> > @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> > static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> > {
> > if (kvm_stage2_has_pud(kvm))
> > - pud_free(NULL, pud);
> > + free_page((unsigned long)pud);
> > }
> >
> > static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> > @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> > static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> > {
> > if (kvm_stage2_has_pmd(kvm))
> > - pmd_free(NULL, pmd);
> > + free_page((unsigned long)pmd);
> > }
> >
> > static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> > diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> > index e9d28a7ca673..cbfbdadca8a5 100644
> > --- a/virt/kvm/arm/mmu.c
> > +++ b/virt/kvm/arm/mmu.c
> > @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> > VM_BUG_ON(pmd_thp_or_huge(*pmd));
> > pmd_clear(pmd);
> > kvm_tlb_flush_vmid_ipa(kvm, addr);
> > - pte_free_kernel(NULL, pte_table);
> > + free_page((unsigned long)pte_table);
> > put_page(virt_to_page(pmd));
> > }
> >
> > --
> > 2.20.1
> >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-01 18:34 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-04-01 18:34 UTC (permalink / raw)
To: Will Deacon
Cc: mark.rutland, julien.thierry, suzuki.poulose, marc.zyngier,
catalin.marinas, Anshuman Khandual, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> [+KVM/ARM folks, since I can't take this without an Ack in place from them]
>
> My understanding is that this patch is intended to replace patch 3/4 in
> this series:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
Yes, and sorry for the confusion. I could send an updated series once
this patch is merged. Thanks.
> On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
> > ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
> > or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
> > PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
> > via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
> > pte_free_kernel(). These will fail once they start calling into pgtable_
> > [pmd]_page_dtor() for pages which never originally went through respective
> > constructor functions. Hence convert all stage-2 page table page release
> > functions to call buddy directly while freeing pages.
> >
> > Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > Acked-by: Yu Zhao <yuzhao@google.com>
> > Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> > ---
> > Changes in V2:
> >
> > - Updated stage2_pud_free() with NOP as per Suzuki
> > - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
> >
> > arch/arm/include/asm/stage2_pgtable.h | 4 ++--
> > arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
> > virt/kvm/arm/mmu.c | 2 +-
> > 3 files changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
> > index de2089501b8b..fed02c3b4600 100644
> > --- a/arch/arm/include/asm/stage2_pgtable.h
> > +++ b/arch/arm/include/asm/stage2_pgtable.h
> > @@ -32,14 +32,14 @@
> > #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
> > #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
> > #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
> > -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
> > +#define stage2_pud_free(kvm, pud) do { } while (0)
> >
> > #define stage2_pud_none(kvm, pud) pud_none(pud)
> > #define stage2_pud_clear(kvm, pud) pud_clear(pud)
> > #define stage2_pud_present(kvm, pud) pud_present(pud)
> > #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
> > #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
> > -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
> > +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
> >
> > #define stage2_pud_huge(kvm, pud) pud_huge(pud)
> >
> > diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
> > index 5412fa40825e..915809e4ac32 100644
> > --- a/arch/arm64/include/asm/stage2_pgtable.h
> > +++ b/arch/arm64/include/asm/stage2_pgtable.h
> > @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
> > static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
> > {
> > if (kvm_stage2_has_pud(kvm))
> > - pud_free(NULL, pud);
> > + free_page((unsigned long)pud);
> > }
> >
> > static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
> > @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
> > static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
> > {
> > if (kvm_stage2_has_pmd(kvm))
> > - pmd_free(NULL, pmd);
> > + free_page((unsigned long)pmd);
> > }
> >
> > static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
> > diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> > index e9d28a7ca673..cbfbdadca8a5 100644
> > --- a/virt/kvm/arm/mmu.c
> > +++ b/virt/kvm/arm/mmu.c
> > @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
> > VM_BUG_ON(pmd_thp_or_huge(*pmd));
> > pmd_clear(pmd);
> > kvm_tlb_flush_vmid_ipa(kvm, addr);
> > - pte_free_kernel(NULL, pte_table);
> > + free_page((unsigned long)pte_table);
> > put_page(virt_to_page(pmd));
> > }
> >
> > --
> > 2.20.1
> >
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-04-01 18:34 ` Yu Zhao
(?)
@ 2019-04-02 9:03 ` Will Deacon
-1 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-02 9:03 UTC (permalink / raw)
To: Yu Zhao
Cc: mark.rutland, julien.thierry, suzuki.poulose, marc.zyngier,
catalin.marinas, Anshuman Khandual, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> >
> > My understanding is that this patch is intended to replace patch 3/4 in
> > this series:
> >
> > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
>
> Yes, and sorry for the confusion. I could send an updated series once
> this patch is merged. Thanks.
That's alright, I think I'm on top of it (but I'll ask you to check whatever
I end up merging). Just wanted to make it easy for the kvm folks to dive in
with no context!
Will
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-02 9:03 ` Will Deacon
0 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-02 9:03 UTC (permalink / raw)
To: Yu Zhao
Cc: mark.rutland, julien.thierry, suzuki.poulose, marc.zyngier,
catalin.marinas, Anshuman Khandual, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> >
> > My understanding is that this patch is intended to replace patch 3/4 in
> > this series:
> >
> > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
>
> Yes, and sorry for the confusion. I could send an updated series once
> this patch is merged. Thanks.
That's alright, I think I'm on top of it (but I'll ask you to check whatever
I end up merging). Just wanted to make it easy for the kvm folks to dive in
with no context!
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-02 9:03 ` Will Deacon
0 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-02 9:03 UTC (permalink / raw)
To: Yu Zhao
Cc: marc.zyngier, catalin.marinas, Anshuman Khandual, linux-mm,
kvmarm, linux-arm-kernel
On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> >
> > My understanding is that this patch is intended to replace patch 3/4 in
> > this series:
> >
> > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
>
> Yes, and sorry for the confusion. I could send an updated series once
> this patch is merged. Thanks.
That's alright, I think I'm on top of it (but I'll ask you to check whatever
I end up merging). Just wanted to make it easy for the kvm folks to dive in
with no context!
Will
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-04-02 9:03 ` Will Deacon
(?)
(?)
@ 2019-04-08 14:22 ` Will Deacon
-1 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-08 14:22 UTC (permalink / raw)
To: Yu Zhao
Cc: mark.rutland, julien.thierry, suzuki.poulose, marc.zyngier,
catalin.marinas, Anshuman Khandual, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
On Tue, Apr 02, 2019 at 10:04:30AM +0100, Will Deacon wrote:
> On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> > On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> > >
> > > My understanding is that this patch is intended to replace patch 3/4 in
> > > this series:
> > >
> > > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
> >
> > Yes, and sorry for the confusion. I could send an updated series once
> > this patch is merged. Thanks.
>
> That's alright, I think I'm on top of it (but I'll ask you to check whatever
> I end up merging). Just wanted to make it easy for the kvm folks to dive in
> with no context!
Ok, I've pushed this out onto a temporary branch before I merge it into
-next:
https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=pgtable-ctors
Please can you confirm that it looks ok?
Thanks,
Will
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-08 14:22 ` Will Deacon
0 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-08 14:22 UTC (permalink / raw)
To: Yu Zhao
Cc: mark.rutland, julien.thierry, suzuki.poulose, marc.zyngier,
catalin.marinas, Anshuman Khandual, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
On Tue, Apr 02, 2019 at 10:04:30AM +0100, Will Deacon wrote:
> On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> > On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> > >
> > > My understanding is that this patch is intended to replace patch 3/4 in
> > > this series:
> > >
> > > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
> >
> > Yes, and sorry for the confusion. I could send an updated series once
> > this patch is merged. Thanks.
>
> That's alright, I think I'm on top of it (but I'll ask you to check whatever
> I end up merging). Just wanted to make it easy for the kvm folks to dive in
> with no context!
Ok, I've pushed this out onto a temporary branch before I merge it into
-next:
https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=pgtable-ctors
Please can you confirm that it looks ok?
Thanks,
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-08 14:22 ` Will Deacon
0 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-08 14:22 UTC (permalink / raw)
To: Yu Zhao
Cc: marc.zyngier, catalin.marinas, Anshuman Khandual, linux-mm,
kvmarm, linux-arm-kernel
On Tue, Apr 02, 2019 at 10:04:30AM +0100, Will Deacon wrote:
> On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> > On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> > >
> > > My understanding is that this patch is intended to replace patch 3/4 in
> > > this series:
> > >
> > > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
> >
> > Yes, and sorry for the confusion. I could send an updated series once
> > this patch is merged. Thanks.
>
> That's alright, I think I'm on top of it (but I'll ask you to check whatever
> I end up merging). Just wanted to make it easy for the kvm folks to dive in
> with no context!
Ok, I've pushed this out onto a temporary branch before I merge it into
-next:
https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=pgtable-ctors
Please can you confirm that it looks ok?
Thanks,
Will
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-08 14:22 ` Will Deacon
0 siblings, 0 replies; 120+ messages in thread
From: Will Deacon @ 2019-04-08 14:22 UTC (permalink / raw)
To: Yu Zhao
Cc: marc.zyngier, catalin.marinas, Anshuman Khandual, linux-mm,
kvmarm, linux-arm-kernel
On Tue, Apr 02, 2019 at 10:04:30AM +0100, Will Deacon wrote:
> On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> > On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> > >
> > > My understanding is that this patch is intended to replace patch 3/4 in
> > > this series:
> > >
> > > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
> >
> > Yes, and sorry for the confusion. I could send an updated series once
> > this patch is merged. Thanks.
>
> That's alright, I think I'm on top of it (but I'll ask you to check whatever
> I end up merging). Just wanted to make it easy for the kvm folks to dive in
> with no context!
Ok, I've pushed this out onto a temporary branch before I merge it into
-next:
https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=pgtable-ctors
Please can you confirm that it looks ok?
Thanks,
Will
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-08 17:18 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-04-08 17:18 UTC (permalink / raw)
To: Will Deacon
Cc: mark.rutland, julien.thierry, suzuki.poulose, marc.zyngier,
catalin.marinas, Anshuman Khandual, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
On Mon, Apr 08, 2019 at 03:22:38PM +0100, Will Deacon wrote:
> On Tue, Apr 02, 2019 at 10:04:30AM +0100, Will Deacon wrote:
> > On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> > > On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > > > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> > > >
> > > > My understanding is that this patch is intended to replace patch 3/4 in
> > > > this series:
> > > >
> > > > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
> > >
> > > Yes, and sorry for the confusion. I could send an updated series once
> > > this patch is merged. Thanks.
> >
> > That's alright, I think I'm on top of it (but I'll ask you to check whatever
> > I end up merging). Just wanted to make it easy for the kvm folks to dive in
> > with no context!
>
> Ok, I've pushed this out onto a temporary branch before I merge it into
> -next:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=pgtable-ctors
>
> Please can you confirm that it looks ok?
LGTM, thanks.
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-08 17:18 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-04-08 17:18 UTC (permalink / raw)
To: Will Deacon
Cc: mark.rutland, julien.thierry, suzuki.poulose, marc.zyngier,
catalin.marinas, Anshuman Khandual, christoffer.dall, linux-mm,
james.morse, kvmarm, linux-arm-kernel
On Mon, Apr 08, 2019 at 03:22:38PM +0100, Will Deacon wrote:
> On Tue, Apr 02, 2019 at 10:04:30AM +0100, Will Deacon wrote:
> > On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> > > On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > > > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> > > >
> > > > My understanding is that this patch is intended to replace patch 3/4 in
> > > > this series:
> > > >
> > > > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
> > >
> > > Yes, and sorry for the confusion. I could send an updated series once
> > > this patch is merged. Thanks.
> >
> > That's alright, I think I'm on top of it (but I'll ask you to check whatever
> > I end up merging). Just wanted to make it easy for the kvm folks to dive in
> > with no context!
>
> Ok, I've pushed this out onto a temporary branch before I merge it into
> -next:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=pgtable-ctors
>
> Please can you confirm that it looks ok?
LGTM, thanks.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-08 17:18 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-04-08 17:18 UTC (permalink / raw)
To: Will Deacon
Cc: marc.zyngier, catalin.marinas, Anshuman Khandual, linux-mm,
kvmarm, linux-arm-kernel
On Mon, Apr 08, 2019 at 03:22:38PM +0100, Will Deacon wrote:
> On Tue, Apr 02, 2019 at 10:04:30AM +0100, Will Deacon wrote:
> > On Mon, Apr 01, 2019 at 12:34:25PM -0600, Yu Zhao wrote:
> > > On Mon, Apr 01, 2019 at 05:16:38PM +0100, Will Deacon wrote:
> > > > [+KVM/ARM folks, since I can't take this without an Ack in place from them]
> > > >
> > > > My understanding is that this patch is intended to replace patch 3/4 in
> > > > this series:
> > > >
> > > > http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
> > >
> > > Yes, and sorry for the confusion. I could send an updated series once
> > > this patch is merged. Thanks.
> >
> > That's alright, I think I'm on top of it (but I'll ask you to check whatever
> > I end up merging). Just wanted to make it easy for the kvm folks to dive in
> > with no context!
>
> Ok, I've pushed this out onto a temporary branch before I merge it into
> -next:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=pgtable-ctors
>
> Please can you confirm that it looks ok?
LGTM, thanks.
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
2019-04-01 16:16 ` Will Deacon
(?)
(?)
@ 2019-04-08 9:09 ` Marc Zyngier
-1 siblings, 0 replies; 120+ messages in thread
From: Marc Zyngier @ 2019-04-08 9:09 UTC (permalink / raw)
To: Will Deacon, Anshuman Khandual
Cc: linux-mm, linux-arm-kernel, catalin.marinas, mark.rutland,
yuzhao, suzuki.poulose, christoffer.dall, james.morse,
julien.thierry, kvmarm
On 01/04/2019 17:16, Will Deacon wrote:
> [+KVM/ARM folks, since I can't take this without an Ack in place from them]
>
> My understanding is that this patch is intended to replace patch 3/4 in
> this series:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
>
> On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
>> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
>> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
>> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
>> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
>> pte_free_kernel(). These will fail once they start calling into pgtable_
>> [pmd]_page_dtor() for pages which never originally went through respective
>> constructor functions. Hence convert all stage-2 page table page release
>> functions to call buddy directly while freeing pages.
>>
>> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> Acked-by: Yu Zhao <yuzhao@google.com>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>> Changes in V2:
>>
>> - Updated stage2_pud_free() with NOP as per Suzuki
>> - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
>>
>> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
>> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
>> virt/kvm/arm/mmu.c | 2 +-
>> 3 files changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
>> index de2089501b8b..fed02c3b4600 100644
>> --- a/arch/arm/include/asm/stage2_pgtable.h
>> +++ b/arch/arm/include/asm/stage2_pgtable.h
>> @@ -32,14 +32,14 @@
>> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
>> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
>> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
>> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
>> +#define stage2_pud_free(kvm, pud) do { } while (0)
>>
>> #define stage2_pud_none(kvm, pud) pud_none(pud)
>> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
>> #define stage2_pud_present(kvm, pud) pud_present(pud)
>> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
>> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
>> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
>> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>>
>> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>>
>> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
>> index 5412fa40825e..915809e4ac32 100644
>> --- a/arch/arm64/include/asm/stage2_pgtable.h
>> +++ b/arch/arm64/include/asm/stage2_pgtable.h
>> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
>> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
>> {
>> if (kvm_stage2_has_pud(kvm))
>> - pud_free(NULL, pud);
>> + free_page((unsigned long)pud);
>> }
>>
>> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
>> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
>> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
>> {
>> if (kvm_stage2_has_pmd(kvm))
>> - pmd_free(NULL, pmd);
>> + free_page((unsigned long)pmd);
>> }
>>
>> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
>> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
>> index e9d28a7ca673..cbfbdadca8a5 100644
>> --- a/virt/kvm/arm/mmu.c
>> +++ b/virt/kvm/arm/mmu.c
>> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
>> VM_BUG_ON(pmd_thp_or_huge(*pmd));
>> pmd_clear(pmd);
>> kvm_tlb_flush_vmid_ipa(kvm, addr);
>> - pte_free_kernel(NULL, pte_table);
>> + free_page((unsigned long)pte_table);
>> put_page(virt_to_page(pmd));
>> }
>>
>> --
>> 2.20.1
>>
Looks good to me, please take it via the arm64 tree with my
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-08 9:09 ` Marc Zyngier
0 siblings, 0 replies; 120+ messages in thread
From: Marc Zyngier @ 2019-04-08 9:09 UTC (permalink / raw)
To: Will Deacon, Anshuman Khandual
Cc: mark.rutland, yuzhao, suzuki.poulose, catalin.marinas,
julien.thierry, christoffer.dall, linux-mm, james.morse, kvmarm,
linux-arm-kernel
On 01/04/2019 17:16, Will Deacon wrote:
> [+KVM/ARM folks, since I can't take this without an Ack in place from them]
>
> My understanding is that this patch is intended to replace patch 3/4 in
> this series:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
>
> On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
>> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
>> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
>> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
>> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
>> pte_free_kernel(). These will fail once they start calling into pgtable_
>> [pmd]_page_dtor() for pages which never originally went through respective
>> constructor functions. Hence convert all stage-2 page table page release
>> functions to call buddy directly while freeing pages.
>>
>> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> Acked-by: Yu Zhao <yuzhao@google.com>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>> Changes in V2:
>>
>> - Updated stage2_pud_free() with NOP as per Suzuki
>> - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
>>
>> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
>> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
>> virt/kvm/arm/mmu.c | 2 +-
>> 3 files changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
>> index de2089501b8b..fed02c3b4600 100644
>> --- a/arch/arm/include/asm/stage2_pgtable.h
>> +++ b/arch/arm/include/asm/stage2_pgtable.h
>> @@ -32,14 +32,14 @@
>> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
>> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
>> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
>> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
>> +#define stage2_pud_free(kvm, pud) do { } while (0)
>>
>> #define stage2_pud_none(kvm, pud) pud_none(pud)
>> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
>> #define stage2_pud_present(kvm, pud) pud_present(pud)
>> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
>> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
>> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
>> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>>
>> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>>
>> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
>> index 5412fa40825e..915809e4ac32 100644
>> --- a/arch/arm64/include/asm/stage2_pgtable.h
>> +++ b/arch/arm64/include/asm/stage2_pgtable.h
>> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
>> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
>> {
>> if (kvm_stage2_has_pud(kvm))
>> - pud_free(NULL, pud);
>> + free_page((unsigned long)pud);
>> }
>>
>> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
>> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
>> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
>> {
>> if (kvm_stage2_has_pmd(kvm))
>> - pmd_free(NULL, pmd);
>> + free_page((unsigned long)pmd);
>> }
>>
>> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
>> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
>> index e9d28a7ca673..cbfbdadca8a5 100644
>> --- a/virt/kvm/arm/mmu.c
>> +++ b/virt/kvm/arm/mmu.c
>> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
>> VM_BUG_ON(pmd_thp_or_huge(*pmd));
>> pmd_clear(pmd);
>> kvm_tlb_flush_vmid_ipa(kvm, addr);
>> - pte_free_kernel(NULL, pte_table);
>> + free_page((unsigned long)pte_table);
>> put_page(virt_to_page(pmd));
>> }
>>
>> --
>> 2.20.1
>>
Looks good to me, please take it via the arm64 tree with my
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-08 9:09 ` Marc Zyngier
0 siblings, 0 replies; 120+ messages in thread
From: Marc Zyngier @ 2019-04-08 9:09 UTC (permalink / raw)
To: Will Deacon, Anshuman Khandual
Cc: yuzhao, catalin.marinas, linux-mm, kvmarm, linux-arm-kernel
On 01/04/2019 17:16, Will Deacon wrote:
> [+KVM/ARM folks, since I can't take this without an Ack in place from them]
>
> My understanding is that this patch is intended to replace patch 3/4 in
> this series:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
>
> On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
>> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
>> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
>> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
>> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
>> pte_free_kernel(). These will fail once they start calling into pgtable_
>> [pmd]_page_dtor() for pages which never originally went through respective
>> constructor functions. Hence convert all stage-2 page table page release
>> functions to call buddy directly while freeing pages.
>>
>> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> Acked-by: Yu Zhao <yuzhao@google.com>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>> Changes in V2:
>>
>> - Updated stage2_pud_free() with NOP as per Suzuki
>> - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
>>
>> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
>> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
>> virt/kvm/arm/mmu.c | 2 +-
>> 3 files changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
>> index de2089501b8b..fed02c3b4600 100644
>> --- a/arch/arm/include/asm/stage2_pgtable.h
>> +++ b/arch/arm/include/asm/stage2_pgtable.h
>> @@ -32,14 +32,14 @@
>> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
>> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
>> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
>> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
>> +#define stage2_pud_free(kvm, pud) do { } while (0)
>>
>> #define stage2_pud_none(kvm, pud) pud_none(pud)
>> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
>> #define stage2_pud_present(kvm, pud) pud_present(pud)
>> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
>> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
>> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
>> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>>
>> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>>
>> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
>> index 5412fa40825e..915809e4ac32 100644
>> --- a/arch/arm64/include/asm/stage2_pgtable.h
>> +++ b/arch/arm64/include/asm/stage2_pgtable.h
>> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
>> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
>> {
>> if (kvm_stage2_has_pud(kvm))
>> - pud_free(NULL, pud);
>> + free_page((unsigned long)pud);
>> }
>>
>> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
>> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
>> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
>> {
>> if (kvm_stage2_has_pmd(kvm))
>> - pmd_free(NULL, pmd);
>> + free_page((unsigned long)pmd);
>> }
>>
>> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
>> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
>> index e9d28a7ca673..cbfbdadca8a5 100644
>> --- a/virt/kvm/arm/mmu.c
>> +++ b/virt/kvm/arm/mmu.c
>> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
>> VM_BUG_ON(pmd_thp_or_huge(*pmd));
>> pmd_clear(pmd);
>> kvm_tlb_flush_vmid_ipa(kvm, addr);
>> - pte_free_kernel(NULL, pte_table);
>> + free_page((unsigned long)pte_table);
>> put_page(virt_to_page(pmd));
>> }
>>
>> --
>> 2.20.1
>>
Looks good to me, please take it via the arm64 tree with my
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply [flat|nested] 120+ messages in thread
* Re: [PATCH V2] KVM: ARM: Remove pgtable page standard functions from stage-2 page tables
@ 2019-04-08 9:09 ` Marc Zyngier
0 siblings, 0 replies; 120+ messages in thread
From: Marc Zyngier @ 2019-04-08 9:09 UTC (permalink / raw)
To: Will Deacon, Anshuman Khandual
Cc: yuzhao, catalin.marinas, linux-mm, kvmarm, linux-arm-kernel
On 01/04/2019 17:16, Will Deacon wrote:
> [+KVM/ARM folks, since I can't take this without an Ack in place from them]
>
> My understanding is that this patch is intended to replace patch 3/4 in
> this series:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/638083.html
>
> On Tue, Mar 12, 2019 at 06:55:45PM +0530, Anshuman Khandual wrote:
>> ARM64 standard pgtable functions are going to use pgtable_page_[ctor|dtor]
>> or pgtable_pmd_page_[ctor|dtor] constructs. At present KVM guest stage-2
>> PUD|PMD|PTE level page tabe pages are allocated with __get_free_page()
>> via mmu_memory_cache_alloc() but released with standard pud|pmd_free() or
>> pte_free_kernel(). These will fail once they start calling into pgtable_
>> [pmd]_page_dtor() for pages which never originally went through respective
>> constructor functions. Hence convert all stage-2 page table page release
>> functions to call buddy directly while freeing pages.
>>
>> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> Acked-by: Yu Zhao <yuzhao@google.com>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>> Changes in V2:
>>
>> - Updated stage2_pud_free() with NOP as per Suzuki
>> - s/__free_page/free_page/ in clear_stage2_pmd_entry() for uniformity
>>
>> arch/arm/include/asm/stage2_pgtable.h | 4 ++--
>> arch/arm64/include/asm/stage2_pgtable.h | 4 ++--
>> virt/kvm/arm/mmu.c | 2 +-
>> 3 files changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h
>> index de2089501b8b..fed02c3b4600 100644
>> --- a/arch/arm/include/asm/stage2_pgtable.h
>> +++ b/arch/arm/include/asm/stage2_pgtable.h
>> @@ -32,14 +32,14 @@
>> #define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
>> #define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
>> #define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
>> -#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
>> +#define stage2_pud_free(kvm, pud) do { } while (0)
>>
>> #define stage2_pud_none(kvm, pud) pud_none(pud)
>> #define stage2_pud_clear(kvm, pud) pud_clear(pud)
>> #define stage2_pud_present(kvm, pud) pud_present(pud)
>> #define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
>> #define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
>> -#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
>> +#define stage2_pmd_free(kvm, pmd) free_page((unsigned long)pmd)
>>
>> #define stage2_pud_huge(kvm, pud) pud_huge(pud)
>>
>> diff --git a/arch/arm64/include/asm/stage2_pgtable.h b/arch/arm64/include/asm/stage2_pgtable.h
>> index 5412fa40825e..915809e4ac32 100644
>> --- a/arch/arm64/include/asm/stage2_pgtable.h
>> +++ b/arch/arm64/include/asm/stage2_pgtable.h
>> @@ -119,7 +119,7 @@ static inline pud_t *stage2_pud_offset(struct kvm *kvm,
>> static inline void stage2_pud_free(struct kvm *kvm, pud_t *pud)
>> {
>> if (kvm_stage2_has_pud(kvm))
>> - pud_free(NULL, pud);
>> + free_page((unsigned long)pud);
>> }
>>
>> static inline bool stage2_pud_table_empty(struct kvm *kvm, pud_t *pudp)
>> @@ -192,7 +192,7 @@ static inline pmd_t *stage2_pmd_offset(struct kvm *kvm,
>> static inline void stage2_pmd_free(struct kvm *kvm, pmd_t *pmd)
>> {
>> if (kvm_stage2_has_pmd(kvm))
>> - pmd_free(NULL, pmd);
>> + free_page((unsigned long)pmd);
>> }
>>
>> static inline bool stage2_pud_huge(struct kvm *kvm, pud_t pud)
>> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
>> index e9d28a7ca673..cbfbdadca8a5 100644
>> --- a/virt/kvm/arm/mmu.c
>> +++ b/virt/kvm/arm/mmu.c
>> @@ -191,7 +191,7 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
>> VM_BUG_ON(pmd_thp_or_huge(*pmd));
>> pmd_clear(pmd);
>> kvm_tlb_flush_vmid_ipa(kvm, addr);
>> - pte_free_kernel(NULL, pte_table);
>> + free_page((unsigned long)pte_table);
>> put_page(virt_to_page(pmd));
>> }
>>
>> --
>> 2.20.1
>>
Looks good to me, please take it via the arm64 tree with my
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply [flat|nested] 120+ messages in thread
* [PATCH v4 4/4] arm64: mm: enable per pmd page table lock
2019-03-12 0:57 ` Yu Zhao
(?)
@ 2019-03-12 0:57 ` Yu Zhao
-1 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
Switch from per mm_struct to per pmd page table lock by enabling
ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
large system.
I'm not sure if there is contention on mm->page_table_lock. Given
the option comes at no cost (apart from initializing more spin
locks), why not enable it now.
We only do so when pmd is not folded, so we don't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc().
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/Kconfig | 3 +++
arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
arch/arm64/include/asm/tlb.h | 5 ++++-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cfbf307d6dc4..a3b1b789f766 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
+config ARCH_ENABLE_SPLIT_PMD_PTLOCK
+ def_bool y if PGTABLE_LEVELS > 2
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
---help---
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 52fa47c73bf0..dabba4b2c61f 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -33,12 +33,22 @@
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- return (pmd_t *)__get_free_page(PGALLOC_GFP);
+ struct page *page;
+
+ page = alloc_page(PGALLOC_GFP);
+ if (!page)
+ return NULL;
+ if (!pgtable_pmd_page_ctor(page)) {
+ __free_page(page);
+ return NULL;
+ }
+ return page_address(page);
}
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
{
BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
+ pgtable_pmd_page_dtor(virt_to_page(pmdp));
free_page((unsigned long)pmdp);
}
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 106fdc951b6e..4e3becfed387 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
unsigned long addr)
{
- tlb_remove_table(tlb, virt_to_page(pmdp));
+ struct page *page = virt_to_page(pmdp);
+
+ pgtable_pmd_page_dtor(page);
+ tlb_remove_table(tlb, page);
}
#endif
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 4/4] arm64: mm: enable per pmd page table lock
@ 2019-03-12 0:57 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: linux-arch, Yu Zhao, Ard Biesheuvel, Peter Zijlstra,
linux-kernel, Nick Piggin, Jun Yao, linux-mm, Aneesh Kumar K . V,
Chintan Pandya, Joel Fernandes, Kirill A . Shutemov,
Andrew Morton, Laura Abbott, linux-arm-kernel
Switch from per mm_struct to per pmd page table lock by enabling
ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
large system.
I'm not sure if there is contention on mm->page_table_lock. Given
the option comes at no cost (apart from initializing more spin
locks), why not enable it now.
We only do so when pmd is not folded, so we don't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc().
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/Kconfig | 3 +++
arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
arch/arm64/include/asm/tlb.h | 5 ++++-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cfbf307d6dc4..a3b1b789f766 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
+config ARCH_ENABLE_SPLIT_PMD_PTLOCK
+ def_bool y if PGTABLE_LEVELS > 2
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
---help---
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 52fa47c73bf0..dabba4b2c61f 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -33,12 +33,22 @@
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- return (pmd_t *)__get_free_page(PGALLOC_GFP);
+ struct page *page;
+
+ page = alloc_page(PGALLOC_GFP);
+ if (!page)
+ return NULL;
+ if (!pgtable_pmd_page_ctor(page)) {
+ __free_page(page);
+ return NULL;
+ }
+ return page_address(page);
}
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
{
BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
+ pgtable_pmd_page_dtor(virt_to_page(pmdp));
free_page((unsigned long)pmdp);
}
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 106fdc951b6e..4e3becfed387 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
unsigned long addr)
{
- tlb_remove_table(tlb, virt_to_page(pmdp));
+ struct page *page = virt_to_page(pmdp);
+
+ pgtable_pmd_page_dtor(page);
+ tlb_remove_table(tlb, page);
}
#endif
--
2.21.0.360.g471c308f928-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 120+ messages in thread
* [PATCH v4 4/4] arm64: mm: enable per pmd page table lock
@ 2019-03-12 0:57 ` Yu Zhao
0 siblings, 0 replies; 120+ messages in thread
From: Yu Zhao @ 2019-03-12 0:57 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland
Cc: Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
Joel Fernandes, Kirill A . Shutemov, Ard Biesheuvel,
Chintan Pandya, Jun Yao, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-arch, linux-mm, Yu Zhao
Switch from per mm_struct to per pmd page table lock by enabling
ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
large system.
I'm not sure if there is contention on mm->page_table_lock. Given
the option comes at no cost (apart from initializing more spin
locks), why not enable it now.
We only do so when pmd is not folded, so we don't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc().
Signed-off-by: Yu Zhao <yuzhao@google.com>
---
arch/arm64/Kconfig | 3 +++
arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
arch/arm64/include/asm/tlb.h | 5 ++++-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cfbf307d6dc4..a3b1b789f766 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -872,6 +872,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
+config ARCH_ENABLE_SPLIT_PMD_PTLOCK
+ def_bool y if PGTABLE_LEVELS > 2
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
---help---
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 52fa47c73bf0..dabba4b2c61f 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -33,12 +33,22 @@
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- return (pmd_t *)__get_free_page(PGALLOC_GFP);
+ struct page *page;
+
+ page = alloc_page(PGALLOC_GFP);
+ if (!page)
+ return NULL;
+ if (!pgtable_pmd_page_ctor(page)) {
+ __free_page(page);
+ return NULL;
+ }
+ return page_address(page);
}
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
{
BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
+ pgtable_pmd_page_dtor(virt_to_page(pmdp));
free_page((unsigned long)pmdp);
}
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 106fdc951b6e..4e3becfed387 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
unsigned long addr)
{
- tlb_remove_table(tlb, virt_to_page(pmdp));
+ struct page *page = virt_to_page(pmdp);
+
+ pgtable_pmd_page_dtor(page);
+ tlb_remove_table(tlb, page);
}
#endif
--
2.21.0.360.g471c308f928-goog
^ permalink raw reply related [flat|nested] 120+ messages in thread