Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=509a80c49c512ac88bd67b981145f925a306111b
Commit:     509a80c49c512ac88bd67b981145f925a306111b
Parent:     1e3e19723ecd58149388f3eecbd3285825f64f3b
Author:     Ingo Molnar <[EMAIL PROTECTED]>
AuthorDate: Wed Oct 17 18:04:34 2007 +0200
Committer:  Thomas Gleixner <[EMAIL PROTECTED]>
CommitDate: Wed Oct 17 20:15:39 2007 +0200

    x86: fix CONFIG_PAGEALLOC related boot hangs/OOMs
    
    if CONFIG_PAGEALLOC is enabled then X86_FEATURE_PSE is disabled and all
    the kernel physical RAM pagetables are set up as 4K pages. This is
    needed so that CONFIG_PAGEALLOC can do finegrained mapping and unmapping
    of pages.
    
    as a side-effect though, the total size of memory allocated as kernel
    pagetables increases significantly. All these pagetables are allocated
    via alloc_bootmem_low_pages(), straight out of the lowmem DMA pool. If
    the system has enough RAM and a large kernel image then almost all of
    the 16 MB lowmem DMA pool is allocated to the image and to pagetables -
    leaving no space for __GFP_DMA allocations.
    
    this results in drivers failing and the bootup hanging:
    
     swapper invoked oom-killer: gfp_mask=0x80d1, order=0, oomkilladj=0
      [<4015059f>] out_of_memory+0x17f/0x1c0
      [<40151f3c>] __alloc_pages+0x37c/0x3a0
      [<40168cd7>] slob_new_page+0x37/0x50
      [<40168dff>] slob_alloc+0x10f/0x190
      [<40169010>] __kmalloc_node+0x80/0x90
      [<405a17e3>] scsi_host_alloc+0x33/0x2c0
      [<405a1a82>] scsi_register+0x12/0x60
      [<40d5889e>] aha1542_detect+0x9e/0x940
      [<405c5ba5>] ultrastor_detect+0x265/0x5f0
      [<401352f5>] getnstimeofday+0x35/0xf0
      [<40d58751>] init_this_scsi_driver+0x41/0xf0
      [<40d0b856>] kernel_init+0x136/0x310
      [<40d58710>] init_this_scsi_driver+0x0/0xf0
      [<40d0b720>] kernel_init+0x0/0x310
      [<40105547>] kernel_thread_helper+0x7/0x10
      =======================
    
    the fix is to first allocate from above the DMA pool, and if that fails
    (for example due to it being a machine with less than 16 MB of RAM),
    allocate from the DMA pool as a fallback.
    
    With this fix applied i was able to boot a PAGEALLOC=y kernel that would
    hang before.
    
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
---
 arch/x86/mm/init_32.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index dda4e83..e4e37d4 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -85,13 +85,20 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd)
 static pte_t * __init one_page_table_init(pmd_t *pmd)
 {
        if (!(pmd_val(*pmd) & _PAGE_PRESENT)) {
-               pte_t *page_table = (pte_t *) 
alloc_bootmem_low_pages(PAGE_SIZE);
+               pte_t *page_table = NULL;
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+               page_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
+#endif
+               if (!page_table)
+                       page_table =
+                               (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
 
                paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
                set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
                BUG_ON(page_table != pte_offset_kernel(pmd, 0));
        }
-       
+
        return pte_offset_kernel(pmd, 0);
 }
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to