diff options
Diffstat (limited to 'powerpc-Fix-deadlock-in-icswx-code.patch')
-rw-r--r-- | powerpc-Fix-deadlock-in-icswx-code.patch | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/powerpc-Fix-deadlock-in-icswx-code.patch b/powerpc-Fix-deadlock-in-icswx-code.patch new file mode 100644 index 000000000..a2ce3cf76 --- /dev/null +++ b/powerpc-Fix-deadlock-in-icswx-code.patch @@ -0,0 +1,74 @@ +From patchwork Wed Sep 14 19:43:15 2011 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: powerpc: Fix deadlock in icswx code +Date: Wed, 14 Sep 2011 09:43:15 -0000 +From: Anton Blanchard <anton@samba.org> +X-Patchwork-Id: 114701 +Message-Id: <20110915054315.5e5ae062@kryten> +To: benh@kernel.crashing.org, paulus@samba.org +Cc: linuxppc-dev@lists.ozlabs.org + +The icswx code introduced an A-B B-A deadlock: + + CPU0 CPU1 + ---- ---- +lock(&anon_vma->mutex); + lock(&mm->mmap_sem); + lock(&anon_vma->mutex); +lock(&mm->mmap_sem); + +Instead of using the mmap_sem to keep mm_users constant, take the +page table spinlock. + +Signed-off-by: Anton Blanchard <anton@samba.org> +Cc: <stable@kernel.org> + +--- + + +diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c +index 3bafc3d..4ff587e 100644 +--- a/arch/powerpc/mm/mmu_context_hash64.c ++++ b/arch/powerpc/mm/mmu_context_hash64.c +@@ -136,8 +136,8 @@ int use_cop(unsigned long acop, struct mm_struct *mm) + if (!mm || !acop) + return -EINVAL; + +- /* We need to make sure mm_users doesn't change */ +- down_read(&mm->mmap_sem); ++ /* The page_table_lock ensures mm_users won't change under us */ ++ spin_lock(&mm->page_table_lock); + spin_lock(mm->context.cop_lockp); + + if (mm->context.cop_pid == COP_PID_NONE) { +@@ -164,7 +164,7 @@ int use_cop(unsigned long acop, struct mm_struct *mm) + + out: + spin_unlock(mm->context.cop_lockp); +- up_read(&mm->mmap_sem); ++ spin_unlock(&mm->page_table_lock); + + return ret; + } +@@ -185,8 +185,8 @@ void drop_cop(unsigned long acop, struct mm_struct *mm) + if (WARN_ON_ONCE(!mm)) + return; + +- /* We need to make sure mm_users doesn't change */ +- down_read(&mm->mmap_sem); ++ /* The page_table_lock ensures mm_users won't change under us */ ++ spin_lock(&mm->page_table_lock); + spin_lock(mm->context.cop_lockp); + + mm->context.acop &= ~acop; +@@ -213,7 +213,7 @@ void drop_cop(unsigned long acop, struct mm_struct *mm) + } + + spin_unlock(mm->context.cop_lockp); +- up_read(&mm->mmap_sem); ++ spin_unlock(&mm->page_table_lock); + } + EXPORT_SYMBOL_GPL(drop_cop); + |