From: Ingo Molnar Date: Wed, 30 Jan 2008 12:33:57 +0000 (+0100) Subject: x86: cpa: simplify locking X-Git-Tag: v2.6.25-rc1~1143^2~101 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a3dc7804e9856668caef41efc54179e61ffccc0;p=linux-2.6 x86: cpa: simplify locking further simplify cpa locking: since the largepage-split is a slowpath, use the pgd_lock for the whole operation, intead of the mmap_sem. This also makes it suitable for DEBUG_PAGEALLOC purposes again. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- diff --git a/arch/x86/mm/pageattr_32.c b/arch/x86/mm/pageattr_32.c index 0966023dfd..9cf2fea54e 100644 --- a/arch/x86/mm/pageattr_32.c +++ b/arch/x86/mm/pageattr_32.c @@ -37,9 +37,8 @@ pte_t *lookup_address(unsigned long address, int *level) return pte_offset_kernel(pmd, address); } -static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) +static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) { - unsigned long flags; struct page *page; /* change init_mm */ @@ -47,7 +46,6 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) if (SHARED_KERNEL_PMD) return; - spin_lock_irqsave(&pgd_lock, flags); for (page = pgd_list; page; page = (struct page *)page->index) { pgd_t *pgd; pud_t *pud; @@ -58,12 +56,12 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) pmd = pmd_offset(pud, address); set_pte_atomic((pte_t *)pmd, pte); } - spin_unlock_irqrestore(&pgd_lock, flags); } static int split_large_page(pte_t *kpte, unsigned long address) { pgprot_t ref_prot = pte_pgprot(pte_clrhuge(*kpte)); + unsigned long flags; unsigned long addr; pte_t *pbase, *tmp; struct page *base; @@ -73,7 +71,7 @@ static int split_large_page(pte_t *kpte, unsigned long address) if (!base) return -ENOMEM; - down_write(&init_mm.mmap_sem); + spin_lock_irqsave(&pgd_lock, flags); /* * Check for races, another CPU might have split this page * up for us already: @@ -95,11 +93,11 @@ static int split_large_page(pte_t *kpte, unsigned long address) /* * Install the new, split up pagetable: */ - set_pmd_pte(kpte, address, mk_pte(base, ref_prot)); + __set_pmd_pte(kpte, address, mk_pte(base, ref_prot)); base = NULL; out_unlock: - up_write(&init_mm.mmap_sem); + spin_unlock_irqrestore(&pgd_lock, flags); if (base) __free_pages(base, 0);