lkml.org 
[lkml]   [2008]   [Sep]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch 5/7] x86, cpa: fix taking the pgd_lock with interrupts off
Interrupt context no longer does the large page split, so no need to use
spin_lock_irqsave()

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
Index: tip/arch/x86/mm/pageattr.c
===================================================================
--- tip.orig/arch/x86/mm/pageattr.c 2008-09-11 13:19:54.000000000 -0700
+++ tip/arch/x86/mm/pageattr.c 2008-09-11 13:25:53.000000000 -0700
@@ -43,12 +43,10 @@

void update_page_count(int level, unsigned long pages)
{
- unsigned long flags;
-
/* Protect against CPA */
- spin_lock_irqsave(&pgd_lock, flags);
+ spin_lock(&pgd_lock);
direct_pages_count[level] += pages;
- spin_unlock_irqrestore(&pgd_lock, flags);
+ spin_unlock(&pgd_lock);
}

static void split_page_count(int level)
@@ -338,7 +336,7 @@
try_preserve_large_page(pte_t *kpte, unsigned long address,
struct cpa_data *cpa)
{
- unsigned long nextpage_addr, numpages, pmask, psize, flags, addr, pfn;
+ unsigned long nextpage_addr, numpages, pmask, psize, addr, pfn;
pte_t new_pte, old_pte, *tmp;
pgprot_t old_prot, new_prot;
int i, do_split = 1;
@@ -347,7 +345,7 @@
if (cpa->force_split)
return 1;

- spin_lock_irqsave(&pgd_lock, flags);
+ spin_lock(&pgd_lock);
/*
* Check for races, another CPU might have split this page
* up already:
@@ -442,7 +440,7 @@
}

out_unlock:
- spin_unlock_irqrestore(&pgd_lock, flags);
+ spin_unlock(&pgd_lock);

return do_split;
}
@@ -454,7 +452,6 @@
static void cpa_fill_pool(struct page **ret)
{
gfp_t gfp = GFP_KERNEL;
- unsigned long flags;
struct page *p;

/*
@@ -484,10 +481,10 @@
*ret = p;
continue;
}
- spin_lock_irqsave(&pgd_lock, flags);
+ spin_lock(&pgd_lock);
list_add(&p->lru, &page_pool);
pool_pages++;
- spin_unlock_irqrestore(&pgd_lock, flags);
+ spin_unlock(&pgd_lock);
}

current->flags &= ~PF_MEMALLOC;
@@ -527,7 +524,7 @@

static int split_large_page(pte_t *kpte, unsigned long address)
{
- unsigned long flags, pfn, pfninc = 1;
+ unsigned long pfn, pfninc = 1;
unsigned int i, level;
pte_t *pbase, *tmp;
pgprot_t ref_prot;
@@ -538,14 +535,14 @@
* pgd_lock, which we have to take anyway for the split
* operation:
*/
- spin_lock_irqsave(&pgd_lock, flags);
+ spin_lock(&pgd_lock);
if (list_empty(&page_pool)) {
- spin_unlock_irqrestore(&pgd_lock, flags);
+ spin_unlock(&pgd_lock);
base = NULL;
cpa_fill_pool(&base);
if (!base)
return -ENOMEM;
- spin_lock_irqsave(&pgd_lock, flags);
+ spin_lock(&pgd_lock);
} else {
base = list_first_entry(&page_pool, struct page, lru);
list_del(&base->lru);
@@ -616,7 +613,7 @@
pool_pages++;
} else
pool_used++;
- spin_unlock_irqrestore(&pgd_lock, flags);
+ spin_unlock(&pgd_lock);

return 0;
}
@@ -676,6 +673,10 @@
return 0;
}

+#ifdef CONFIG_DEBUG_PAGEALLOC
+ BUG_ON(irqs_disabled());
+#endif
+
/*
* Check, whether we can keep the large page intact
* and just change the pte:
--



\
 
 \ /
  Last update: 2008-09-11 23:35    [from the cache]
©2003-2011 Jasper Spaans. Advertise on this site