]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Bug fix: Do not free direct mapping pages twice.
authorTang Chen <tangchen@cn.fujitsu.com>
Wed, 20 Feb 2013 02:14:16 +0000 (13:14 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 20 Feb 2013 05:52:30 +0000 (16:52 +1100)
Direct mapped pages were freed when they were offlined, or they were not
allocated.  So we only need to free vmemmap pages, no need to free direct
mapped pages.

Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
Cc: Wen Congyang <wency@cn.fujitsu.com>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Tang Chen <tangchen@cn.fujitsu.com>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
arch/x86/mm/init_64.c

index 56bedb1a8224e384faece4de9e7fa93cde817450..841816abc1b38f0f6d61f420083da9ab1659f9cd 100644 (file)
@@ -829,6 +829,10 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 
                if (IS_ALIGNED(addr, PAGE_SIZE) &&
                    IS_ALIGNED(next, PAGE_SIZE)) {
+                       /*
+                        * Do not free direct mapping pages since they were
+                        * freed when offlining.
+                        */
                        if (!direct)
                                free_pagetable(pte_page(*pte), 0);
 
@@ -844,10 +848,11 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
                         * remove the page when it is wholly filled with 0xFD.
                         */
                        memset((void *)addr, PAGE_INUSE, next - addr);
-                       page_addr = page_address(pte_page(*pte));
 
+                       page_addr = page_address(pte_page(*pte));
                        if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) {
-                               free_pagetable(pte_page(*pte), 0);
+                               if (!direct)
+                                       free_pagetable(pte_page(*pte), 0);
 
                                spin_lock(&init_mm.page_table_lock);
                                pte_clear(&init_mm, addr, pte);