powerpc/book3s64/mm: Fix DirectMap stats in /proc/meminfo
authorAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Fri, 16 Jun 2023 11:08:13 +0000 (16:38 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 21 Jun 2023 04:08:53 +0000 (14:08 +1000)
On memory unplug reduce DirectMap page count correctly.
root@ubuntu-guest:# grep Direct /proc/meminfo
DirectMap4k:           0 kB
DirectMap64k:           0 kB
DirectMap2M:    115343360 kB
DirectMap1G:           0 kB

Before fix:
root@ubuntu-guest:# ndctl disable-namespace all
disabled 1 namespace
root@ubuntu-guest:# grep Direct /proc/meminfo
DirectMap4k:           0 kB
DirectMap64k:           0 kB
DirectMap2M:    115343360 kB
DirectMap1G:           0 kB

After fix:
root@ubuntu-guest:# ndctl disable-namespace all
disabled 1 namespace
root@ubuntu-guest:# grep Direct /proc/meminfo
DirectMap4k:           0 kB
DirectMap64k:           0 kB
DirectMap2M:    104857600 kB
DirectMap1G:           0 kB

Fixes: a2dc009afa9a ("powerpc/mm/book3s/radix: Add mapping statistics")
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Tested-by: Sachin Sant <sachinp@linux.ibm.com <mailto:sachinp@linux.ibm.com>>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20230616110826.344417-4-aneesh.kumar@linux.ibm.com
arch/powerpc/mm/book3s64/radix_pgtable.c

index 5f8c6fb..cb11eda 100644 (file)
@@ -745,9 +745,9 @@ static void free_pud_table(pud_t *pud_start, p4d_t *p4d)
 }
 
 static void remove_pte_table(pte_t *pte_start, unsigned long addr,
-                            unsigned long end)
+                            unsigned long end, bool direct)
 {
-       unsigned long next;
+       unsigned long next, pages = 0;
        pte_t *pte;
 
        pte = pte_start + pte_index(addr);
@@ -769,13 +769,16 @@ static void remove_pte_table(pte_t *pte_start, unsigned long addr,
                }
 
                pte_clear(&init_mm, addr, pte);
+               pages++;
        }
+       if (direct)
+               update_page_count(mmu_virtual_psize, -pages);
 }
 
 static void __meminit remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
-                            unsigned long end)
+                                      unsigned long end, bool direct)
 {
-       unsigned long next;
+       unsigned long next, pages = 0;
        pte_t *pte_base;
        pmd_t *pmd;
 
@@ -793,19 +796,22 @@ static void __meminit remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
                                continue;
                        }
                        pte_clear(&init_mm, addr, (pte_t *)pmd);
+                       pages++;
                        continue;
                }
 
                pte_base = (pte_t *)pmd_page_vaddr(*pmd);
-               remove_pte_table(pte_base, addr, next);
+               remove_pte_table(pte_base, addr, next, direct);
                free_pte_table(pte_base, pmd);
        }
+       if (direct)
+               update_page_count(MMU_PAGE_2M, -pages);
 }
 
 static void __meminit remove_pud_table(pud_t *pud_start, unsigned long addr,
-                            unsigned long end)
+                                      unsigned long end, bool direct)
 {
-       unsigned long next;
+       unsigned long next, pages = 0;
        pmd_t *pmd_base;
        pud_t *pud;
 
@@ -823,16 +829,20 @@ static void __meminit remove_pud_table(pud_t *pud_start, unsigned long addr,
                                continue;
                        }
                        pte_clear(&init_mm, addr, (pte_t *)pud);
+                       pages++;
                        continue;
                }
 
                pmd_base = pud_pgtable(*pud);
-               remove_pmd_table(pmd_base, addr, next);
+               remove_pmd_table(pmd_base, addr, next, direct);
                free_pmd_table(pmd_base, pud);
        }
+       if (direct)
+               update_page_count(MMU_PAGE_1G, -pages);
 }
 
-static void __meminit remove_pagetable(unsigned long start, unsigned long end)
+static void __meminit remove_pagetable(unsigned long start, unsigned long end,
+                                      bool direct)
 {
        unsigned long addr, next;
        pud_t *pud_base;
@@ -861,7 +871,7 @@ static void __meminit remove_pagetable(unsigned long start, unsigned long end)
                }
 
                pud_base = p4d_pgtable(*p4d);
-               remove_pud_table(pud_base, addr, next);
+               remove_pud_table(pud_base, addr, next, direct);
                free_pud_table(pud_base, p4d);
        }
 
@@ -884,7 +894,7 @@ int __meminit radix__create_section_mapping(unsigned long start,
 
 int __meminit radix__remove_section_mapping(unsigned long start, unsigned long end)
 {
-       remove_pagetable(start, end);
+       remove_pagetable(start, end, true);
        return 0;
 }
 #endif /* CONFIG_MEMORY_HOTPLUG */
@@ -920,7 +930,7 @@ int __meminit radix__vmemmap_create_mapping(unsigned long start,
 #ifdef CONFIG_MEMORY_HOTPLUG
 void __meminit radix__vmemmap_remove_mapping(unsigned long start, unsigned long page_size)
 {
-       remove_pagetable(start, start + page_size);
+       remove_pagetable(start, start + page_size, false);
 }
 #endif
 #endif