Commit 81e84796 authored by Heiko Carstens's avatar Heiko Carstens Committed by Vasily Gorbik

s390/mm: fix direct map accounting

Commit bb1520d5 ("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: bb1520d5 ("s390/mm: start kernel with DAT enabled")
Reviewed-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 07fdd662
...@@ -13,6 +13,10 @@ ...@@ -13,6 +13,10 @@
unsigned long __bootdata_preserved(s390_invalid_asce); 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 init_mm (*(struct mm_struct *)vmlinux.init_mm_off)
#define swapper_pg_dir vmlinux.swapper_pg_dir_off #define swapper_pg_dir vmlinux.swapper_pg_dir_off
#define invalid_pg_dir vmlinux.invalid_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) ...@@ -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, static void pgtable_pte_populate(pmd_t *pmd, unsigned long addr, unsigned long end,
enum populate_mode mode) enum populate_mode mode)
{ {
unsigned long pages = 0;
pte_t *pte, entry; pte_t *pte, entry;
pte = pte_offset_kernel(pmd, addr); pte = pte_offset_kernel(pmd, addr);
...@@ -277,14 +282,17 @@ static void pgtable_pte_populate(pmd_t *pmd, unsigned long addr, unsigned long e ...@@ -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 = __pte(_pa(addr, PAGE_SIZE, mode));
entry = set_pte_bit(entry, PAGE_KERNEL_EXEC); entry = set_pte_bit(entry, PAGE_KERNEL_EXEC);
set_pte(pte, entry); 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, static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long end,
enum populate_mode mode) enum populate_mode mode)
{ {
unsigned long next; unsigned long next, pages = 0;
pmd_t *pmd, entry; pmd_t *pmd, entry;
pte_t *pte; pte_t *pte;
...@@ -298,6 +306,7 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e ...@@ -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 = __pmd(_pa(addr, _SEGMENT_SIZE, mode));
entry = set_pmd_bit(entry, SEGMENT_KERNEL_EXEC); entry = set_pmd_bit(entry, SEGMENT_KERNEL_EXEC);
set_pmd(pmd, entry); set_pmd(pmd, entry);
pages++;
continue; continue;
} }
pte = boot_pte_alloc(); pte = boot_pte_alloc();
...@@ -307,12 +316,14 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e ...@@ -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); 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, static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long end,
enum populate_mode mode) enum populate_mode mode)
{ {
unsigned long next; unsigned long next, pages = 0;
pud_t *pud, entry; pud_t *pud, entry;
pmd_t *pmd; pmd_t *pmd;
...@@ -326,6 +337,7 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e ...@@ -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 = __pud(_pa(addr, _REGION3_SIZE, mode));
entry = set_pud_bit(entry, REGION3_KERNEL_EXEC); entry = set_pud_bit(entry, REGION3_KERNEL_EXEC);
set_pud(pud, entry); set_pud(pud, entry);
pages++;
continue; continue;
} }
pmd = boot_crst_alloc(_SEGMENT_ENTRY_EMPTY); 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 ...@@ -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); 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, static void pgtable_p4d_populate(pgd_t *pgd, unsigned long addr, unsigned long end,
......
...@@ -34,7 +34,7 @@ enum { ...@@ -34,7 +34,7 @@ enum {
PG_DIRECT_MAP_MAX PG_DIRECT_MAP_MAX
}; };
extern atomic_long_t direct_pages_count[PG_DIRECT_MAP_MAX]; extern atomic_long_t __bootdata_preserved(direct_pages_count[PG_DIRECT_MAP_MAX]);
static inline void update_page_count(int level, long count) static inline void update_page_count(int level, long count)
{ {
......
...@@ -41,7 +41,7 @@ void __storage_key_init_range(unsigned long start, unsigned long end) ...@@ -41,7 +41,7 @@ void __storage_key_init_range(unsigned long start, unsigned long end)
} }
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
atomic_long_t direct_pages_count[PG_DIRECT_MAP_MAX]; atomic_long_t __bootdata_preserved(direct_pages_count[PG_DIRECT_MAP_MAX]);
void arch_report_meminfo(struct seq_file *m) void arch_report_meminfo(struct seq_file *m)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment