Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=eb5b5f024c40f02e9b0f3801173769a726f170fb
Commit:     eb5b5f024c40f02e9b0f3801173769a726f170fb
Parent:     76ebd0548df6ee48586e9b80d8fc2f58aa5fb51c
Author:     Thomas Gleixner <[EMAIL PROTECTED]>
AuthorDate: Sat Feb 9 23:24:09 2008 +0100
Committer:  Thomas Gleixner <[EMAIL PROTECTED]>
CommitDate: Sat Feb 9 23:24:09 2008 +0100

    x86: cpa, use page pool
    
    Switch the split page code to use the page pool. We do this
    unconditionally to avoid different behaviour with and without
    DEBUG_PAGEALLOC enabled.
    
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
---
 arch/x86/mm/pageattr.c |   35 +++++++++++++++++++++++++----------
 1 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 831462c..e5d29a1 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -411,20 +411,29 @@ void __init cpa_init(void)
 static int split_large_page(pte_t *kpte, unsigned long address)
 {
        unsigned long flags, pfn, pfninc = 1;
-       gfp_t gfp_flags = GFP_KERNEL;
        unsigned int i, level;
        pte_t *pbase, *tmp;
        pgprot_t ref_prot;
        struct page *base;
 
-#ifdef CONFIG_DEBUG_PAGEALLOC
-       gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
-#endif
-       base = alloc_pages(gfp_flags, 0);
-       if (!base)
+       /*
+        * Get a page from the pool. The pool list is protected by the
+        * pgd_lock, which we have to take anyway for the split
+        * operation:
+        */
+       spin_lock_irqsave(&pgd_lock, flags);
+       if (list_empty(&page_pool)) {
+               spin_unlock_irqrestore(&pgd_lock, flags);
                return -ENOMEM;
+       }
+
+       base = list_first_entry(&page_pool, struct page, lru);
+       list_del(&base->lru);
+       pool_pages--;
+
+       if (pool_pages < pool_low)
+               pool_low = pool_pages;
 
-       spin_lock_irqsave(&pgd_lock, flags);
        /*
         * Check for races, another CPU might have split this page
         * up for us already:
@@ -469,11 +478,17 @@ static int split_large_page(pte_t *kpte, unsigned long 
address)
        base = NULL;
 
 out_unlock:
+       /*
+        * If we dropped out via the lookup_address check under
+        * pgd_lock then stick the page back into the pool:
+        */
+       if (base) {
+               list_add(&base->lru, &page_pool);
+               pool_pages++;
+       } else
+               pool_used++;
        spin_unlock_irqrestore(&pgd_lock, flags);
 
-       if (base)
-               __free_pages(base, 0);
-
        return 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