x86: keep the /proc/meminfo page count correct
authorYinghai Lu <yinghai@kernel.org>
Sun, 26 Oct 2008 05:58:21 +0000 (22:58 -0700)
committerIngo Molnar <mingo@elte.hu>
Mon, 27 Oct 2008 17:55:26 +0000 (18:55 +0100)
Impact: get correct page count in /proc/meminfo

found page count in /proc/meminfo is nor correct on 1G system in VirtualBox 2.0.4

# cat /proc/meminfo
MemTotal:        1017508 kB
MemFree:          822700 kB
Buffers:            1456 kB
Cached:            26632 kB
SwapCached:            0 kB
...
Hugepagesize:       2048 kB
DirectMap4k:      4032 kB
DirectMap2M:  18446744073709549568 kB

with this patch get:
...
DirectMap4k:      4032 kB
DirectMap2M:   1044480 kB

which is consistent to kernel_page_tables
---[ Low Kernel Mapping ]---
0xffff880000000000-0xffff880000001000           4K     RW     PCD     GLB x  pte
0xffff880000001000-0xffff88000009f000         632K     RW             GLB x  pte
0xffff88000009f000-0xffff8800000a0000           4K     RW     PCD     GLB x  pte
0xffff8800000a0000-0xffff880000200000        1408K     RW             GLB x  pte
0xffff880000200000-0xffff88003fe00000        1020M     RW         PSE GLB x  pmd
0xffff88003fe00000-0xffff88003fff0000        1984K     RW             GLB NX pte
0xffff88003fff0000-0xffff880040000000          64K                           pte
0xffff880040000000-0xffff888000000000         511G                           pud
0xffff888000000000-0xffffc20000000000       58880G                           pgd

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/mm/init_64.c

index b8e461d4941208fab60f977471dbe088ce48d23e..c7a4c5a9a21bf7663df9ea6ecf10ec82a83efcf1 100644 (file)
@@ -350,8 +350,10 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end,
                 * pagetable pages as RO. So assume someone who pre-setup
                 * these mappings are more intelligent.
                 */
-               if (pte_val(*pte))
+               if (pte_val(*pte)) {
+                       pages++;
                        continue;
+               }
 
                if (0)
                        printk("   pte=%p addr=%lx pte=%016lx\n",
@@ -418,8 +420,10 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
                         * not differ with respect to page frame and
                         * attributes.
                         */
-                       if (page_size_mask & (1 << PG_LEVEL_2M))
+                       if (page_size_mask & (1 << PG_LEVEL_2M)) {
+                               pages++;
                                continue;
+                       }
                        new_prot = pte_pgprot(pte_clrhuge(*(pte_t *)pmd));
                }
 
@@ -499,8 +503,10 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
                         * not differ with respect to page frame and
                         * attributes.
                         */
-                       if (page_size_mask & (1 << PG_LEVEL_1G))
+                       if (page_size_mask & (1 << PG_LEVEL_1G)) {
+                               pages++;
                                continue;
+                       }
                        prot = pte_pgprot(pte_clrhuge(*(pte_t *)pud));
                }