Re: [PATCH] ARM64: Implement arch_report_meminfo()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 14 Dec 2023, Robin Murphy wrote:

It seems somewhat suspect that these counts only ever increase. It's not often that we change or remove parts of the linear map, but it certainly can happen.

Well yes in the case of hotplug I guess ... Ok here is V2



From cl@xxxxxxxxxx Fri Dec  8 13:11:58 2023
From: "Christoph Lameter (Ampere)" <cl@xxxxxxxxxx>
To: Catalin Marinas <catalin.marinas@xxxxxxx>, Marc Zyngier <maz@xxxxxxxxxx>, Will Deacon <will@xxxxxxxxxx>, Ryan Roberts <ryan.roberts@xxxxxxx>, Mark Rutland <mark.rutland@xxxxxxx>, Vishal Moola <vishal.moola@xxxxxxxxx>
Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx, linux-mm@xxxxxxxxx
Subject: [PATCH] ARM64: Implement arch_report_meminfo()

V1->V2 hotplug and umapping support

X86 has information in /proc/meminfo showing the use of large mappings
for the kernel direct map. This has now also become important for
ARM since the kernel default CONFIG_RODATA_FULL_DEFAULT_ENABLED
forces 4K PTE use for the direct map and users may not be aware
of the performance impact of the increased TLB use etc.

The output of /proc/meminfo on ARM64 is then after this patch:

4K page size:

Hugepagesize:       2048 kB
Hugetlb:               0 kB
DirectMap4k:      155912 kB
CONT DMap4k:        1176 kB
DirectMap2M:      722944 kB
CONT DMap2M:       28672 kB
DirectMap1G:   534773760 kB

64K page size:

Hugepagesize:     524288 kB
Hugetlb:               0 kB
DirectMap64k:      882624 kB
CONT DMap64k:       19904 kB
DirectMap512M:    534773760 kB
CONT DMap512M:           0 kB
DirectMap4096G:           0 kB

Signed-off-by: Christoph Lameter (Ampere) <cl@xxxxxxxxx>

Index: linux/arch/arm64/mm/mmu.c
===================================================================
--- linux.orig/arch/arm64/mm/mmu.c
+++ linux/arch/arm64/mm/mmu.c
@@ -76,6 +76,13 @@ EXPORT_SYMBOL(empty_zero_page);
 static DEFINE_SPINLOCK(swapper_pgdir_lock);
 static DEFINE_MUTEX(fixmap_lock);

+static atomic_t nr_pte;
+static atomic_t nr_pmd;
+static atomic_t nr_pud;
+static atomic_t nr_pte_cont;
+static atomic_t nr_pmd_cont;
+
+
 void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
 {
 	pgd_t *fixmap_pgdp;
@@ -179,6 +186,7 @@ static void init_pte(pmd_t *pmdp, unsign
 		pte_t old_pte = READ_ONCE(*ptep);

 		set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
+		atomic_inc(&nr_pte);

 		/*
 		 * After the PTE entry has been populated once, we
@@ -223,8 +231,10 @@ static void alloc_init_cont_pte(pmd_t *p

 		/* use a contiguous mapping if the range is suitably aligned */
 		if ((((addr | next | phys) & ~CONT_PTE_MASK) == 0) &&
-		    (flags & NO_CONT_MAPPINGS) == 0)
+		    (flags & NO_CONT_MAPPINGS) == 0) {
 			__prot = __pgprot(pgprot_val(prot) | PTE_CONT);
+			atomic_inc(&nr_pte_cont);
+		}

 		init_pte(pmdp, addr, next, phys, __prot);

@@ -249,6 +259,7 @@ static void init_pmd(pud_t *pudp, unsign
 		if (((addr | next | phys) & ~PMD_MASK) == 0 &&
 		    (flags & NO_BLOCK_MAPPINGS) == 0) {
 			pmd_set_huge(pmdp, phys, prot);
+			atomic_inc(&nr_pmd);

 			/*
 			 * After the PMD entry has been populated once, we
@@ -301,8 +312,10 @@ static void alloc_init_cont_pmd(pud_t *p

 		/* use a contiguous mapping if the range is suitably aligned */
 		if ((((addr | next | phys) & ~CONT_PMD_MASK) == 0) &&
-		    (flags & NO_CONT_MAPPINGS) == 0)
+		    (flags & NO_CONT_MAPPINGS) == 0) {
 			__prot = __pgprot(pgprot_val(prot) | PTE_CONT);
+			atomic_inc(&nr_pmd_cont);
+		}

 		init_pmd(pudp, addr, next, phys, __prot, pgtable_alloc, flags);

@@ -346,7 +359,7 @@ static void alloc_init_pud(pgd_t *pgdp,
 		   ((addr | next | phys) & ~PUD_MASK) == 0 &&
 		    (flags & NO_BLOCK_MAPPINGS) == 0) {
 			pud_set_huge(pudp, phys, prot);
-
+			atomic_inc(&nr_pud);
 			/*
 			 * After the PUD entry has been populated once, we
 			 * only allow updates to the permission attributes.
@@ -859,6 +872,11 @@ static void unmap_hotplug_pte_range(pmd_
 			continue;

 		WARN_ON(!pte_present(pte));
+
+		if (pte_cont(pte))
+			atomic_dec(&nr_pte_cont);
+		atomic_dec(&nr_pte);
+
 		pte_clear(&init_mm, addr, ptep);
 		flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
 		if (free_mapped)
@@ -883,6 +901,11 @@ static void unmap_hotplug_pmd_range(pud_

 		WARN_ON(!pmd_present(pmd));
 		if (pmd_sect(pmd)) {
+
+			if (pmd_cont(pmd))
+				atomic_dec(&nr_pmd_cont);
+			atomic_dec(&nr_pmd);
+
 			pmd_clear(pmdp);

 			/*
@@ -916,6 +939,9 @@ static void unmap_hotplug_pud_range(p4d_

 		WARN_ON(!pud_present(pud));
 		if (pud_sect(pud)) {
+
+			atomic_dec(&nr_pud);
+
 			pud_clear(pudp);

 			/*
@@ -1010,6 +1036,7 @@ static void free_empty_pte_table(pmd_t *
 			return;
 	}

+	atomic_dec(&nr_pmd);
 	pmd_clear(pmdp);
 	__flush_tlb_kernel_pgtable(start);
 	free_hotplug_pgtable_page(virt_to_page(ptep));
@@ -1050,6 +1077,7 @@ static void free_empty_pmd_table(pud_t *
 			return;
 	}

+	atomic_dec(&nr_pud);
 	pud_clear(pudp);
 	__flush_tlb_kernel_pgtable(start);
 	free_hotplug_pgtable_page(virt_to_page(pmdp));
@@ -1225,6 +1253,7 @@ int pmd_free_pte_page(pmd_t *pmdp, unsig
 	}

 	table = pte_offset_kernel(pmdp, addr);
+	atomic_dec(&nr_pmd);
 	pmd_clear(pmdp);
 	__flush_tlb_kernel_pgtable(addr);
 	pte_free_kernel(NULL, table);
@@ -1253,6 +1282,7 @@ int pud_free_pmd_page(pud_t *pudp, unsig
 		pmd_free_pte_page(pmdp, next);
 	} while (pmdp++, next += PMD_SIZE, next != end);

+	atomic_dec(&nr_pud);
 	pud_clear(pudp);
 	__flush_tlb_kernel_pgtable(addr);
 	pmd_free(NULL, table);
@@ -1486,3 +1516,36 @@ void ptep_modify_prot_commit(struct vm_a
 {
 	set_pte_at(vma->vm_mm, addr, ptep, pte);
 }
+
+
+#ifdef CONFIG_PROC_FS
+void arch_report_meminfo(struct seq_file *m)
+{
+	unsigned long pagesize_in_kb = PAGE_SIZE / 1024;
+
+	seq_printf(m, "DirectMap%luk:    %8lu kB\n",
+			pagesize_in_kb,
+		  	(unsigned long)atomic_read(&nr_pte) * pagesize_in_kb);
+
+        seq_printf(m, "CONT DMap%luk:    %8lu kB\n",
+			pagesize_in_kb,
+			(unsigned long)atomic_read(&nr_pte_cont) * pagesize_in_kb);
+
+	pagesize_in_kb = PMD_SIZE / 1024;
+
+        seq_printf(m, "DirectMap%luM:    %8lu kB\n",
+			pagesize_in_kb / 1024,
+			(unsigned long)atomic_read(&nr_pmd) * pagesize_in_kb);
+
+	seq_printf(m, "CONT DMap%luM:    %8lu kB\n",
+			pagesize_in_kb / 1024,
+			(unsigned long)atomic_read(&nr_pmd_cont) * pagesize_in_kb);
+
+	pagesize_in_kb = PUD_SIZE / 1024;
+
+	seq_printf(m, "DirectMap%luG:  %10lu kB\n",
+			pagesize_in_kb >> 20,
+			(unsigned long)atomic_read(&nr_pud) * pagesize_in_kb);
+}
+#endif
+




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux