From: Russell King <rmk@arm.linux.org.uk>
To: linux-arch@vger.kernel.org,
Linus Torvalds <torvalds@linux-foundation.org>,
Andrew Morton <akpm@linux-foundation.org>
Subject: [BUG] Fault handlers can deadlock
Date: Mon, 11 Jun 2007 17:00:27 +0100 [thread overview]
Message-ID: <20070611160026.GA16265@flint.arm.linux.org.uk> (raw)
Recently, a bug has been discovered on ARM whereby if futexes are
being used and the system is put under heavy load, a deadlock will
occur.
The deadlock involves mmap_sem having been taken by the futex code
and a page fault occuring in copy_from_user_inatomic(). We then
hit this:
/*
* As per x86, we may deadlock here. However, since the kernel only
* validly references user space from well defined areas of the code,
* we can bug out early if this is from code which shouldn't.
*/
if (!down_read_trylock(&mm->mmap_sem)) {
if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))
goto no_context;
down_read(&mm->mmap_sem);
}
which is more or less identical across many architectures. The
problem is that:
1. down_read_trylock() finds contention, so it returns 0.
2. we've been called from kernel mode
3. search_exception_tables() finds an entry in the exception
tables (see note about "well defined areas of the code") and
returns *non*-NULL
4. therefore, the second if statement is _false_.
5. we then deadlock on down_read(&mm->mmap_sem).
Note that search_exception_tables() is generic code, and I believe rwsems
are also generic code today.
For reference, he's the x86 version, which will perform in the same
way as the ARM version quoted above:
/* When running in the kernel we expect faults to occur only to
* addresses in user space. All other faults represent errors in the
* kernel and should generate an OOPS. Unfortunatly, in the case of an
* erroneous fault occurring in a code path which already holds mmap_sem
* we will deadlock attempting to validate the fault against the
* address space. Luckily the kernel only validly references user
* space from well defined areas of code, which are listed in the
* exceptions table.
*
* As the vast majority of faults will be valid we will only perform
* the source reference check when there is a possibilty of a deadlock.
* Attempt to lock the address space, if we cannot we then validate the
* source. If this is invalid we can skip the address space check,
* thus avoiding the deadlock.
*/
if (!down_read_trylock(&mm->mmap_sem)) {
if ((error_code & 4) == 0 &&
!search_exception_tables(regs->eip))
goto bad_area_nosemaphore;
down_read(&mm->mmap_sem);
}
Clearly, if we are expecting to deal with faults occuring from these "well
defined areas of code, which are listed in the exceptions table" the
sense if the test is wrong.
Therefore, I think the following patch is appropriate (and similar patches
are required for other architectures):
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 75d4914..e41efd9 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -238,7 +238,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
* we can bug out early if this is from code which shouldn't.
*/
if (!down_read_trylock(&mm->mmap_sem)) {
- if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))
+ if (!user_mode(regs) && search_exception_tables(regs->ARM_pc))
goto no_context;
down_read(&mm->mmap_sem);
}
Comments?
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of:
next reply other threads:[~2007-06-11 16:00 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-11 16:00 Russell King [this message]
2007-06-11 16:41 ` [BUG] Fault handlers can deadlock Andrew Morton
2007-06-11 16:53 ` Russell King
2007-06-11 17:31 ` Andrew Morton
2007-06-11 17:38 ` Russell King
2007-06-11 17:51 ` Linus Torvalds
2007-06-11 17:39 ` Linus Torvalds
2007-06-11 18:08 ` Russell King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070611160026.GA16265@flint.arm.linux.org.uk \
--to=rmk@arm.linux.org.uk \
--cc=akpm@linux-foundation.org \
--cc=linux-arch@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.