mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 19:56:18 +00:00
[PATCH] Reducing local_bh_enable/disable overhead in irqtrace
The recent changes from irqtrace feature has added overheads to local_bh_disable and local_bh_enable that reduces UDP performance across x86_64 and IA64, even though IA64 does not support the irqtrace feature. Patch in question is [PATCH]lockdep: irqtrace subsystem, core http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=c ommit;h=de30a2b355ea85350ca2f58f3b9bf4e5bc007986 Prior to this patch, local_bh_disable was a short macro. Now it is a function which calls __local_bh_disable with added irq flags save and restore. The irq flags save and restore were also added to local_bh_enable, probably for injecting the trace irqs code. This overhead is on the generic code path across all architectures. On a IA_64 test machine (Itanium-2 1.6 GHz) running a benchmark like netperf's UDP streaming test, the added overhead results in a drop of 3% in throughput, as udp_sendmsg calls the local_bh_enable/disable several times. Other workloads that have heavy usages of local_bh_enable/disable could also be affected. The patch ideally should not have affected IA-64 performance as it does not have IRQ tracing support. A significant portion of the overhead is in the added irq flags save and restore, which I think is not needed if IRQ tracing is unused. A suggested patch is attached below that recovers the lost performance. However, the "ifdef"s in the patch are a bit ugly. Signed-off-by: Tim Chen <tim.c.chen@intel.com> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
953a7f2066
commit
3c829c367a
1 changed files with 18 additions and 0 deletions
|
@ -65,6 +65,7 @@ static inline void wakeup_softirqd(void)
|
||||||
* This one is for softirq.c-internal use,
|
* This one is for softirq.c-internal use,
|
||||||
* where hardirqs are disabled legitimately:
|
* where hardirqs are disabled legitimately:
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
static void __local_bh_disable(unsigned long ip)
|
static void __local_bh_disable(unsigned long ip)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -80,6 +81,13 @@ static void __local_bh_disable(unsigned long ip)
|
||||||
trace_softirqs_off(ip);
|
trace_softirqs_off(ip);
|
||||||
raw_local_irq_restore(flags);
|
raw_local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
#else /* !CONFIG_TRACE_IRQFLAGS */
|
||||||
|
static inline void __local_bh_disable(unsigned long ip)
|
||||||
|
{
|
||||||
|
add_preempt_count(SOFTIRQ_OFFSET);
|
||||||
|
barrier();
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_TRACE_IRQFLAGS */
|
||||||
|
|
||||||
void local_bh_disable(void)
|
void local_bh_disable(void)
|
||||||
{
|
{
|
||||||
|
@ -121,12 +129,16 @@ EXPORT_SYMBOL(_local_bh_enable);
|
||||||
|
|
||||||
void local_bh_enable(void)
|
void local_bh_enable(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
WARN_ON_ONCE(in_irq());
|
WARN_ON_ONCE(in_irq());
|
||||||
|
#endif
|
||||||
WARN_ON_ONCE(irqs_disabled());
|
WARN_ON_ONCE(irqs_disabled());
|
||||||
|
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Are softirqs going to be turned on now:
|
* Are softirqs going to be turned on now:
|
||||||
*/
|
*/
|
||||||
|
@ -142,18 +154,22 @@ void local_bh_enable(void)
|
||||||
do_softirq();
|
do_softirq();
|
||||||
|
|
||||||
dec_preempt_count();
|
dec_preempt_count();
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
#endif
|
||||||
preempt_check_resched();
|
preempt_check_resched();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(local_bh_enable);
|
EXPORT_SYMBOL(local_bh_enable);
|
||||||
|
|
||||||
void local_bh_enable_ip(unsigned long ip)
|
void local_bh_enable_ip(unsigned long ip)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
WARN_ON_ONCE(in_irq());
|
WARN_ON_ONCE(in_irq());
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Are softirqs going to be turned on now:
|
* Are softirqs going to be turned on now:
|
||||||
*/
|
*/
|
||||||
|
@ -169,7 +185,9 @@ void local_bh_enable_ip(unsigned long ip)
|
||||||
do_softirq();
|
do_softirq();
|
||||||
|
|
||||||
dec_preempt_count();
|
dec_preempt_count();
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
#endif
|
||||||
preempt_check_resched();
|
preempt_check_resched();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(local_bh_enable_ip);
|
EXPORT_SYMBOL(local_bh_enable_ip);
|
||||||
|
|
Loading…
Reference in a new issue