diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-10 23:58:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-10 23:58:02 -0400 |
commit | 8e3e076c5a78519a9f64cd384e8f18bc21882ce0 (patch) | |
tree | f032258fde3aa4771e86bf4552fe4530c221dec3 /include/linux | |
parent | 00b41ec2611dc98f87f30753ee00a53db648d662 (diff) |
BKL: revert back to the old spinlock implementation
The generic semaphore rewrite had a huge performance regression on AIM7
(and potentially other BKL-heavy benchmarks) because the generic
semaphores had been rewritten to be simple to understand and fair. The
latter, in particular, turns a semaphore-based BKL implementation into a
mess of scheduling.
The attempt to fix the performance regression failed miserably (see the
previous commit 00b41ec2611dc98f87f30753ee00a53db648d662 'Revert
"semaphore: fix"'), and so for now the simple and sane approach is to
instead just go back to the old spinlock-based BKL implementation that
never had any issues like this.
This patch also has the advantage of being reported to fix the
regression completely according to Yanmin Zhang, unlike the semaphore
hack which still left a couple percentage point regression.
As a spinlock, the BKL obviously has the potential to be a latency
issue, but it's not really any different from any other spinlock in that
respect. We do want to get rid of the BKL asap, but that has been the
plan for several years.
These days, the biggest users are in the tty layer (open/release in
particular) and Alan holds out some hope:
"tty release is probably a few months away from getting cured - I'm
afraid it will almost certainly be the very last user of the BKL in
tty to get fixed as it depends on everything else being sanely locked."
so while we're not there yet, we do have a plan of action.
Tested-by: Yanmin Zhang <yanmin_zhang@linux.intel.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Matthew Wilcox <matthew@wil.cx>
Cc: Alexander Viro <viro@ftp.linux.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/hardirq.h | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 897f723bd222..181006cc94a0 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -72,6 +72,14 @@ | |||
72 | #define in_softirq() (softirq_count()) | 72 | #define in_softirq() (softirq_count()) |
73 | #define in_interrupt() (irq_count()) | 73 | #define in_interrupt() (irq_count()) |
74 | 74 | ||
75 | #if defined(CONFIG_PREEMPT) | ||
76 | # define PREEMPT_INATOMIC_BASE kernel_locked() | ||
77 | # define PREEMPT_CHECK_OFFSET 1 | ||
78 | #else | ||
79 | # define PREEMPT_INATOMIC_BASE 0 | ||
80 | # define PREEMPT_CHECK_OFFSET 0 | ||
81 | #endif | ||
82 | |||
75 | /* | 83 | /* |
76 | * Are we running in atomic context? WARNING: this macro cannot | 84 | * Are we running in atomic context? WARNING: this macro cannot |
77 | * always detect atomic context; in particular, it cannot know about | 85 | * always detect atomic context; in particular, it cannot know about |
@@ -79,17 +87,11 @@ | |||
79 | * used in the general case to determine whether sleeping is possible. | 87 | * used in the general case to determine whether sleeping is possible. |
80 | * Do not use in_atomic() in driver code. | 88 | * Do not use in_atomic() in driver code. |
81 | */ | 89 | */ |
82 | #define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0) | 90 | #define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_INATOMIC_BASE) |
83 | |||
84 | #ifdef CONFIG_PREEMPT | ||
85 | # define PREEMPT_CHECK_OFFSET 1 | ||
86 | #else | ||
87 | # define PREEMPT_CHECK_OFFSET 0 | ||
88 | #endif | ||
89 | 91 | ||
90 | /* | 92 | /* |
91 | * Check whether we were atomic before we did preempt_disable(): | 93 | * Check whether we were atomic before we did preempt_disable(): |
92 | * (used by the scheduler) | 94 | * (used by the scheduler, *after* releasing the kernel lock) |
93 | */ | 95 | */ |
94 | #define in_atomic_preempt_off() \ | 96 | #define in_atomic_preempt_off() \ |
95 | ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET) | 97 | ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET) |