diff options
author | Heiko Carstens <hca@linux.ibm.com> | 2023-04-06 13:31:29 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2023-04-13 17:36:28 +0200 |
commit | 81e8479649853ffafc714aca4a9c0262efd3160a (patch) | |
tree | e915ac65bdca546ed59942519196a967d361a93b /arch/s390/boot | |
parent | 07fdd6627f7f9c72ed68d531653b56df81da9996 (diff) | |
download | lwn-81e8479649853ffafc714aca4a9c0262efd3160a.tar.gz lwn-81e8479649853ffafc714aca4a9c0262efd3160a.zip |
s390/mm: fix direct map accounting
Commit bb1520d581a3 ("s390/mm: start kernel with DAT enabled") did not
implement direct map accounting in the early page table setup code. In
result the reported values are bogus now:
$cat /proc/meminfo
...
DirectMap4k: 5120 kB
DirectMap1M: 18446744073709546496 kB
DirectMap2G: 0 kB
Fix this by adding the missing accounting. The result looks sane again:
$cat /proc/meminfo
...
DirectMap4k: 6156 kB
DirectMap1M: 2091008 kB
DirectMap2G: 6291456 kB
Fixes: bb1520d581a3 ("s390/mm: start kernel with DAT enabled")
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390/boot')
-rw-r--r-- | arch/s390/boot/vmem.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/s390/boot/vmem.c b/arch/s390/boot/vmem.c index df91d9065f7e..acb1f8b53105 100644 --- a/arch/s390/boot/vmem.c +++ b/arch/s390/boot/vmem.c @@ -13,6 +13,10 @@ unsigned long __bootdata_preserved(s390_invalid_asce); +#ifdef CONFIG_PROC_FS +atomic_long_t __bootdata_preserved(direct_pages_count[PG_DIRECT_MAP_MAX]); +#endif + #define init_mm (*(struct mm_struct *)vmlinux.init_mm_off) #define swapper_pg_dir vmlinux.swapper_pg_dir_off #define invalid_pg_dir vmlinux.invalid_pg_dir_off @@ -267,6 +271,7 @@ static bool can_large_pmd(pmd_t *pm_dir, unsigned long addr, unsigned long end) static void pgtable_pte_populate(pmd_t *pmd, unsigned long addr, unsigned long end, enum populate_mode mode) { + unsigned long pages = 0; pte_t *pte, entry; pte = pte_offset_kernel(pmd, addr); @@ -277,14 +282,17 @@ static void pgtable_pte_populate(pmd_t *pmd, unsigned long addr, unsigned long e entry = __pte(_pa(addr, PAGE_SIZE, mode)); entry = set_pte_bit(entry, PAGE_KERNEL_EXEC); set_pte(pte, entry); + pages++; } } + if (mode == POPULATE_DIRECT) + update_page_count(PG_DIRECT_MAP_4K, pages); } static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long end, enum populate_mode mode) { - unsigned long next; + unsigned long next, pages = 0; pmd_t *pmd, entry; pte_t *pte; @@ -298,6 +306,7 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e entry = __pmd(_pa(addr, _SEGMENT_SIZE, mode)); entry = set_pmd_bit(entry, SEGMENT_KERNEL_EXEC); set_pmd(pmd, entry); + pages++; continue; } pte = boot_pte_alloc(); @@ -307,12 +316,14 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e } pgtable_pte_populate(pmd, addr, next, mode); } + if (mode == POPULATE_DIRECT) + update_page_count(PG_DIRECT_MAP_1M, pages); } static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long end, enum populate_mode mode) { - unsigned long next; + unsigned long next, pages = 0; pud_t *pud, entry; pmd_t *pmd; @@ -326,6 +337,7 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e entry = __pud(_pa(addr, _REGION3_SIZE, mode)); entry = set_pud_bit(entry, REGION3_KERNEL_EXEC); set_pud(pud, entry); + pages++; continue; } pmd = boot_crst_alloc(_SEGMENT_ENTRY_EMPTY); @@ -335,6 +347,8 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e } pgtable_pmd_populate(pud, addr, next, mode); } + if (mode == POPULATE_DIRECT) + update_page_count(PG_DIRECT_MAP_2G, pages); } static void pgtable_p4d_populate(pgd_t *pgd, unsigned long addr, unsigned long end, |