aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/pageattr.c
diff options
context:
space:
mode:
authorAndi Kleen <andi@firstfloor.org>2008-05-02 05:46:49 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-08 02:11:45 -0400
commitce0c0e50f94e8c55b00a722e8c6e8d6c802be211 (patch)
treecd8917c9f7917c75d2c65f2eaa2e4d4c60794bef /arch/x86/mm/pageattr.c
parent1b40a895df6c7d5a80e71f65674060b03d84bbef (diff)
x86, generic: CPA add statistics about state of direct mapping v4
Add information about the mapping state of the direct mapping to /proc/meminfo. I chose /proc/meminfo because that is where all the other memory statistics are too and it is a generally useful metric even outside debugging situations. A lot of split kernel pages means the kernel will run slower. This way we can see how many large pages are really used for it and how many are split. Useful for general insight into the kernel. v2: Add hotplug locking to 64bit to plug a very obscure theoretical race. 32bit doesn't need it because it doesn't support hotadd for lowmem. Fix some typos v3: Rename dpages_cnt Add CONFIG ifdef for count update as requested by tglx Expand description v4: Fix stupid bugs added in v3 Move update_page_count to pageattr.c Signed-off-by: Andi Kleen <andi@firstfloor.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r--arch/x86/mm/pageattr.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 60bcb5b6a37e..668205bca15e 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -34,6 +34,19 @@ struct cpa_data {
34 unsigned force_split : 1; 34 unsigned force_split : 1;
35}; 35};
36 36
37static unsigned long direct_pages_count[PG_LEVEL_NUM];
38
39void __meminit update_page_count(int level, unsigned long pages)
40{
41#ifdef CONFIG_PROC_FS
42 unsigned long flags;
43 /* Protect against CPA */
44 spin_lock_irqsave(&pgd_lock, flags);
45 direct_pages_count[level] += pages;
46 spin_unlock_irqrestore(&pgd_lock, flags);
47#endif
48}
49
37#ifdef CONFIG_X86_64 50#ifdef CONFIG_X86_64
38 51
39static inline unsigned long highmap_start_pfn(void) 52static inline unsigned long highmap_start_pfn(void)
@@ -500,6 +513,12 @@ static int split_large_page(pte_t *kpte, unsigned long address)
500 for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc) 513 for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc)
501 set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); 514 set_pte(&pbase[i], pfn_pte(pfn, ref_prot));
502 515
516 if (address >= (unsigned long)__va(0) &&
517 address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT)) {
518 direct_pages_count[level]--;
519 direct_pages_count[level - 1] += PTRS_PER_PTE;
520 }
521
503 /* 522 /*
504 * Install the new, split up pagetable. Important details here: 523 * Install the new, split up pagetable. Important details here:
505 * 524 *
@@ -1029,6 +1048,22 @@ bool kernel_page_present(struct page *page)
1029 1048
1030#endif /* CONFIG_DEBUG_PAGEALLOC */ 1049#endif /* CONFIG_DEBUG_PAGEALLOC */
1031 1050
1051#ifdef CONFIG_PROC_FS
1052int arch_report_meminfo(char *page)
1053{
1054 int n;
1055 n = sprintf(page, "DirectMap4k: %8lu\n"
1056 "DirectMap2M: %8lu\n",
1057 direct_pages_count[PG_LEVEL_4K],
1058 direct_pages_count[PG_LEVEL_2M]);
1059#ifdef CONFIG_X86_64
1060 n += sprintf(page + n, "DirectMap1G: %8lu\n",
1061 direct_pages_count[PG_LEVEL_1G]);
1062#endif
1063 return n;
1064}
1065#endif
1066
1032/* 1067/*
1033 * The testcases use internal knowledge of the implementation that shouldn't 1068 * The testcases use internal knowledge of the implementation that shouldn't
1034 * be exposed to the rest of the kernel. Include these directly here. 1069 * be exposed to the rest of the kernel. Include these directly here.