Patches contributed by Eötvös Lorand University
commit 43581a10075492445f65234384210492ff333eba
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Oct 16 23:26:08 2007 -0700
softlockup: improve debug output
Improve the debuggability of kernel lockups by enhancing the debug
output of the softlockup detector: print the task that causes the lockup
and try to print a more intelligent backtrace.
The old format was:
BUG: soft lockup detected on CPU#1!
[<c0105e4a>] show_trace_log_lvl+0x19/0x2e
[<c0105f43>] show_trace+0x12/0x14
[<c0105f59>] dump_stack+0x14/0x16
[<c015f6bc>] softlockup_tick+0xbe/0xd0
[<c013457d>] run_local_timers+0x12/0x14
[<c01346b8>] update_process_times+0x3e/0x63
[<c0145fb8>] tick_sched_timer+0x7c/0xc0
[<c0140a75>] hrtimer_interrupt+0x135/0x1ba
[<c011bde7>] smp_apic_timer_interrupt+0x6e/0x80
[<c0105aa3>] apic_timer_interrupt+0x33/0x38
[<c0104f8a>] syscall_call+0x7/0xb
=======================
The new format is:
BUG: soft lockup detected on CPU#1! [prctl:2363]
Pid: 2363, comm: prctl
EIP: 0060:[<c013915f>] CPU: 1
EIP is at sys_prctl+0x24/0x18c
EFLAGS: 00000213 Not tainted (2.6.22-cfs-v20 #26)
EAX: 00000001 EBX: 000003e7 ECX: 00000001 EDX: f6df0000
ESI: 000003e7 EDI: 000003e7 EBP: f6df0fb0 DS: 007b ES: 007b FS: 00d8
CR0: 8005003b CR2: 4d8c3340 CR3: 3731d000 CR4: 000006d0
[<c0105e4a>] show_trace_log_lvl+0x19/0x2e
[<c0105f43>] show_trace+0x12/0x14
[<c01040be>] show_regs+0x1ab/0x1b3
[<c015f807>] softlockup_tick+0xef/0x108
[<c013457d>] run_local_timers+0x12/0x14
[<c01346b8>] update_process_times+0x3e/0x63
[<c0145fcc>] tick_sched_timer+0x7c/0xc0
[<c0140a89>] hrtimer_interrupt+0x135/0x1ba
[<c011bde7>] smp_apic_timer_interrupt+0x6e/0x80
[<c0105aa3>] apic_timer_interrupt+0x33/0x38
[<c0104f8a>] syscall_call+0x7/0xb
=======================
Note that in the old format we only knew that some system call locked
up, we didnt know _which_. With the new format we know that it's at a
specific place in sys_prctl(). [which was where i created an artificial
kernel lockup to test the new format.]
This is also useful if the lockup happens in user-space - the user-space
EIP (and other registers) will be printed too. (such a lockup would
either suggest that the task was running at SCHED_FIFO:99 and looping
for more than 10 seconds, or that the softlockup detector has a
false-positive.)
The task name is printed too first, just in case we dont manage to print
a useful backtrace.
[satyam@infradead.org: fix warning]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Satyam Sharma <satyam@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index e423b3a918fd..65839c54abf5 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -15,6 +15,8 @@
#include <linux/notifier.h>
#include <linux/module.h>
+#include <asm/irq_regs.h>
+
static DEFINE_SPINLOCK(print_lock);
static DEFINE_PER_CPU(unsigned long, touch_timestamp);
@@ -72,6 +74,7 @@ void softlockup_tick(void)
int this_cpu = smp_processor_id();
unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu);
unsigned long print_timestamp;
+ struct pt_regs *regs = get_irq_regs();
unsigned long now;
if (touch_timestamp == 0) {
@@ -101,15 +104,18 @@ void softlockup_tick(void)
wake_up_process(per_cpu(watchdog_task, this_cpu));
/* Warn about unreasonable 10+ seconds delays: */
- if (now > (touch_timestamp + 10)) {
- per_cpu(print_timestamp, this_cpu) = touch_timestamp;
+ if (now <= (touch_timestamp + 10))
+ return;
- spin_lock(&print_lock);
- printk(KERN_ERR "BUG: soft lockup detected on CPU#%d!\n",
- this_cpu);
+ per_cpu(print_timestamp, this_cpu) = touch_timestamp;
+
+ spin_lock(&print_lock);
+ printk(KERN_ERR "BUG: soft lockup detected on CPU#%d!\n", this_cpu);
+ if (regs)
+ show_regs(regs);
+ else
dump_stack();
- spin_unlock(&print_lock);
- }
+ spin_unlock(&print_lock);
}
/*
commit ad3b82795f3f6e641081790409a051312622f2a6
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Oct 16 23:26:07 2007 -0700
softlockup: make asm/irq_regs.h available on every platform
The softlockup detector would like to use get_irq_regs(), so generalize the
availability on every Linux architecture.
(It is fine for an architecture to always return NULL to get_irq_regs(),
which it does by default.)
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: Ian Molton <spyro@f2s.com>
Cc: Kumar Gala <galak@gate.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Mikael Starvik <starvik@axis.com>
Cc: Miles Bader <uclinux-v850@lsi.nec.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/include/asm-arm26/irq_regs.h b/include/asm-arm26/irq_regs.h
new file mode 100644
index 000000000000..3dd9c0b70270
--- /dev/null
+++ b/include/asm-arm26/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-cris/irq_regs.h b/include/asm-cris/irq_regs.h
new file mode 100644
index 000000000000..3dd9c0b70270
--- /dev/null
+++ b/include/asm-cris/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-ppc/irq_regs.h b/include/asm-ppc/irq_regs.h
new file mode 100644
index 000000000000..3dd9c0b70270
--- /dev/null
+++ b/include/asm-ppc/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-v850/irq_regs.h b/include/asm-v850/irq_regs.h
new file mode 100644
index 000000000000..3dd9c0b70270
--- /dev/null
+++ b/include/asm-v850/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
commit a115d5caca1a2905ba7a32b408a6042b20179aaa
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Oct 16 23:26:06 2007 -0700
fix the softlockup watchdog to actually work
this Xen related commit:
commit 966812dc98e6a7fcdf759cbfa0efab77500a8868
Author: Jeremy Fitzhardinge <jeremy@goop.org>
Date: Tue May 8 00:28:02 2007 -0700
Ignore stolen time in the softlockup watchdog
broke the softlockup watchdog to never report any lockups. (!)
print_timestamp defaults to 0, this makes the following condition
always true:
if (print_timestamp < (touch_timestamp + 1) ||
and we'll in essence never report soft lockups.
apparently the functionality of the soft lockup watchdog was never
actually tested with that patch applied ...
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 68f7606b4160..e423b3a918fd 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -82,10 +82,11 @@ void softlockup_tick(void)
print_timestamp = per_cpu(print_timestamp, this_cpu);
/* report at most once a second */
- if (print_timestamp < (touch_timestamp + 1) ||
- did_panic ||
- !per_cpu(watchdog_task, this_cpu))
+ if ((print_timestamp >= touch_timestamp &&
+ print_timestamp < (touch_timestamp + 1)) ||
+ did_panic || !per_cpu(watchdog_task, this_cpu)) {
return;
+ }
/* do not print during early bootup: */
if (unlikely(system_state != SYSTEM_RUNNING)) {
commit a3b13c23f186ecb57204580cc1f2dbe9c284953a
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Oct 16 23:26:06 2007 -0700
softlockup: use cpu_clock() instead of sched_clock()
sched_clock() is not a reliable time-source, use cpu_clock() instead.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 708d4882c0c3..68f7606b4160 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -40,14 +40,16 @@ static struct notifier_block panic_block = {
* resolution, and we don't need to waste time with a big divide when
* 2^30ns == 1.074s.
*/
-static unsigned long get_timestamp(void)
+static unsigned long get_timestamp(int this_cpu)
{
- return sched_clock() >> 30; /* 2^30 ~= 10^9 */
+ return cpu_clock(this_cpu) >> 30; /* 2^30 ~= 10^9 */
}
void touch_softlockup_watchdog(void)
{
- __raw_get_cpu_var(touch_timestamp) = get_timestamp();
+ int this_cpu = raw_smp_processor_id();
+
+ __raw_get_cpu_var(touch_timestamp) = get_timestamp(this_cpu);
}
EXPORT_SYMBOL(touch_softlockup_watchdog);
@@ -91,7 +93,7 @@ void softlockup_tick(void)
return;
}
- now = get_timestamp();
+ now = get_timestamp(this_cpu);
/* Wake up the high-prio watchdog task every second: */
if (now > (touch_timestamp + 1))
commit 9be4bfb974b37410466db605abe3402236167e05
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Oct 15 17:23:21 2007 +0200
[PATCH] ssb: fix build failure
fix build failure if PCMCIA=m but SSB=y:
drivers/built-in.o: In function `ssb_pcmcia_switch_coreidx':
: undefined reference to `pcmcia_access_configuration_register'
(fix symmetric bug for PCI too.)
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Acked-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index b4a5e5e9d9fc..d976660cb7f0 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -22,7 +22,7 @@ config SSB
config SSB_PCIHOST_POSSIBLE
bool
- depends on SSB && PCI
+ depends on SSB && (PCI = y || PCI = SSB)
default y
config SSB_PCIHOST
@@ -37,7 +37,7 @@ config SSB_PCIHOST
config SSB_PCMCIAHOST_POSSIBLE
bool
- depends on SSB && PCMCIA && EXPERIMENTAL
+ depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL
default y
config SSB_PCMCIAHOST
commit bcb5febb248f7cc1e4a39ff61507f6343ba1c594
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Oct 16 20:44:59 2007 -0400
forcedeth: fix NAPI rx poll function
fix the forcedeth NAPI poll function to not emit this warning:
[ 186.635916] WARNING: at net/core/dev.c:2166 net_rx_action()
[ 186.641351] [<c060d9f5>] net_rx_action+0x145/0x1b0
[ 186.646191] [<c011d752>] __do_softirq+0x42/0x90
[ 186.650784] [<c011d7c6>] do_softirq+0x26/0x30
[ 186.655202] [<c011db48>] local_bh_enable+0x48/0xa0
[ 186.660055] [<c06023e0>] lock_sock_nested+0xa0/0xc0
[ 186.664995] [<c065da16>] tcp_recvmsg+0x16/0xbc0
[ 186.669588] [<c013e94b>] __generic_file_aio_write_nolock+0x27b/0x520
[ 186.676001] [<c0601d75>] sock_common_recvmsg+0x45/0x70
[ 186.681202] [<c05ff5df>] sock_aio_read+0x11f/0x140
[ 186.686054] [<c015c086>] do_sync_read+0xc6/0x110
[ 186.690735] [<c012b9b0>] autoremove_wake_function+0x0/0x40
[ 186.696280] [<c060dcfc>] net_tx_action+0x3c/0xe0
[ 186.700961] [<c015c9c2>] vfs_read+0x132/0x140
[ 186.705378] [<c015cd41>] sys_read+0x41/0x70
[ 186.709625] [<c0102b66>] sysenter_past_esp+0x5f/0x89
[ 186.714651] =======================
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index dae30b731342..2e708150b014 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2268,13 +2268,13 @@ static int nv_rx_process(struct net_device *dev, int limit)
{
struct fe_priv *np = netdev_priv(dev);
u32 flags;
- u32 rx_processed_cnt = 0;
+ int rx_work = 0;
struct sk_buff *skb;
int len;
while((np->get_rx.orig != np->put_rx.orig) &&
!((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) &&
- (rx_processed_cnt++ < limit)) {
+ (rx_work < limit)) {
dprintk(KERN_DEBUG "%s: nv_rx_process: flags 0x%x.\n",
dev->name, flags);
@@ -2396,9 +2396,11 @@ static int nv_rx_process(struct net_device *dev, int limit)
np->get_rx.orig = np->first_rx.orig;
if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx))
np->get_rx_ctx = np->first_rx_ctx;
+
+ rx_work++;
}
- return rx_processed_cnt;
+ return rx_work;
}
static int nv_rx_process_optimized(struct net_device *dev, int limit)
commit f20bf6125605acbbc7eb8c9420d7221c91aa83eb
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Oct 16 16:09:20 2007 +0200
time: introduce xtime_seconds
improve performance of sys_time(). sys_time() returns time in seconds,
but it does so by calling do_gettimeofday() and then returning the
tv_sec portion of the GTOD time. But the data structure "xtime", which
is updated by every timer/scheduler tick, already offers HZ granularity
time.
the patch improves the sysbench oltp macrobenchmark by 4-5% on an AMD
dual-core system:
v2.6.23:
#threads
1: transactions: 4073 (407.23 per sec.)
2: transactions: 8530 (852.81 per sec.)
3: transactions: 8321 (831.88 per sec.)
4: transactions: 8407 (840.58 per sec.)
5: transactions: 8070 (806.74 per sec.)
v2.6.23 + sys_time-speedup.patch:
1: transactions: 4281 (428.09 per sec.)
2: transactions: 8910 (890.85 per sec.)
3: transactions: 8659 (865.79 per sec.)
4: transactions: 8676 (867.34 per sec.)
5: transactions: 8532 (852.91 per sec.)
and by 4-5% on an Intel dual-core system too:
2.6.23:
1: transactions: 4560 (455.94 per sec.)
2: transactions: 10094 (1009.30 per sec.)
3: transactions: 9755 (975.36 per sec.)
4: transactions: 9859 (985.78 per sec.)
5: transactions: 9701 (969.72 per sec.)
2.6.23 + sys_time-speedup.patch:
1: transactions: 4779 (477.84 per sec.)
2: transactions: 10103 (1010.14 per sec.)
3: transactions: 10141 (1013.93 per sec.)
4: transactions: 10371 (1036.89 per sec.)
5: transactions: 10178 (1017.50 per sec.)
(the more CPUs the system has, the more speedup this patch gives for
this particular workload.)
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/kernel/time.c b/kernel/time.c
index 2289a8d68314..1afcc78dc3b1 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -57,11 +57,7 @@ EXPORT_SYMBOL(sys_tz);
*/
asmlinkage long sys_time(time_t __user * tloc)
{
- time_t i;
- struct timespec tv;
-
- getnstimeofday(&tv);
- i = tv.tv_sec;
+ time_t i = get_seconds();
if (tloc) {
if (put_user(i,tloc))
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 4ad79f6bdec6..7e8983aecf83 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -49,19 +49,12 @@ struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
static unsigned long total_sleep_time; /* seconds */
EXPORT_SYMBOL(xtime);
-
-#ifdef CONFIG_NO_HZ
static struct timespec xtime_cache __attribute__ ((aligned (16)));
static inline void update_xtime_cache(u64 nsec)
{
xtime_cache = xtime;
timespec_add_ns(&xtime_cache, nsec);
}
-#else
-#define xtime_cache xtime
-/* We do *not* want to evaluate the argument for this case */
-#define update_xtime_cache(n) do { } while (0)
-#endif
static struct clocksource *clock; /* pointer to current clocksource */
commit c2cbdbb1583830b77f169a717407f035d6627793
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Oct 16 14:42:30 2007 +0200
[ALSA] fix bootup crash in snd_gus_interrupt()
when simulating a storm of fake GUS interrupts (without actually owning
this venerable piece of ISA hardware) the driver falls over (crashes) in
two ways:
1) spinlocks being initialized too late:
INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
[<401058ca>] show_trace_log_lvl+0x1a/0x30
[<401064b2>] show_trace+0x12/0x20
[<401064d6>] dump_stack+0x16/0x20
[<4014a72b>] __lock_acquire+0xcfb/0x1030
[<4014aac0>] lock_acquire+0x60/0x80
[<40721a68>] _spin_lock_irqsave+0x38/0x50
[<4058fc12>] snd_gf1_i_look8+0x22/0x60
[<405906fe>] snd_gus_interrupt+0x13e/0x270
[<401548e8>] handle_IRQ_event+0x28/0x60
[<40155cc1>] handle_fasteoi_irq+0x71/0xe0
[<40107238>] do_IRQ+0x48/0xa0
[<401051fe>] common_interrupt+0x2e/0x40
[<40156822>] register_handler_proc+0x92/0xf0
[<401550c2>] setup_irq+0xe2/0x190
[<40155224>] request_irq+0xb4/0xd0
[<4058f524>] snd_gus_create+0x124/0x3c0
[<40aa4087>] snd_gusclassic_probe+0x2a7/0x4b0
[<403f5eff>] isa_bus_probe+0x1f/0x30
[<403f1944>] driver_probe_device+0x84/0x190
[<403f1a58>] __device_attach+0x8/0x10
[<403f0e63>] bus_for_each_drv+0x53/0x80
[<403f1b1b>] device_attach+0x8b/0x90
[<403f0dd8>] bus_attach_device+0x48/0x80
[<403efdbd>] device_add+0x45d/0x5a0
[<403eff12>] device_register+0x12/0x20
[<403f60c3>] isa_register_driver+0xb3/0x140
[<40aa3dd2>] alsa_card_gusclassic_init+0x12/0x20
[<40a665c3>] kernel_init+0x133/0x310
[<401054a7>] kernel_thread_helper+0x7/0x10
=======================
2) callback functions not being filled in yet:
BUG: unable to handle kernel NULL pointer dereference at virtual address 00000000
printing eip:
00000000
*pde = 00000000
Oops: 0000 [#1]
SMP DEBUG_PAGEALLOC
CPU: 0
EIP: 0060:[<00000000>] Not tainted VLI
EFLAGS: 00010002 (2.6.23 #37)
EIP is at 0x0
eax: 7fe94000 ebx: 7fe94000 ecx: 00000000 edx: 00000226
esi: 00000000 edi: 00000005 ebp: 7ff87c28 esp: 7ff87bf4
ds: 007b es: 007b fs: 00d8 gs: 0000 ss: 0068
Process swapper (pid: 1, ti=7ff86000 task=7ff84000 task.ti=7ff86000)
Stack: 40590683 408424a9 408db87c 00000029 40787406 00000064 00000046 ff000000
000000ff 00000001 7faefaf0 00000000 00000005 7ff87c40 401548e8 00000000
40a52000 7faefaf0 00000005 7ff87c58 40155cc1 40a52030 00000005 00000000
Call Trace:
[<401058ca>] show_trace_log_lvl+0x1a/0x30
[<4010598b>] show_stack_log_lvl+0xab/0xd0
[<40105b7c>] show_registers+0x1cc/0x2d0
[<40105d96>] die+0x116/0x240
[<4011d7bb>] do_page_fault+0x18b/0x670
[<40721d22>] error_code+0x72/0x80
[<401548e8>] handle_IRQ_event+0x28/0x60
[<40155cc1>] handle_fasteoi_irq+0x71/0xe0
[<40107238>] do_IRQ+0x48/0xa0
[<401051fe>] common_interrupt+0x2e/0x40
[<401a344e>] proc_create+0x3e/0x120
[<401a3733>] proc_mkdir_mode+0x23/0x50
[<401a376f>] proc_mkdir+0xf/0x20
[<40156864>] register_handler_proc+0xd4/0xf0
[<401550c2>] setup_irq+0xe2/0x190
[<40155224>] request_irq+0xb4/0xd0
[<4058f524>] snd_gus_create+0x124/0x3c0
[<40aa4087>] snd_gusclassic_probe+0x2a7/0x4b0
[<403f5eff>] isa_bus_probe+0x1f/0x30
[<403f1944>] driver_probe_device+0x84/0x190
[<403f1a58>] __device_attach+0x8/0x10
[<403f0e63>] bus_for_each_drv+0x53/0x80
[<403f1b1b>] device_attach+0x8b/0x90
[<403f0dd8>] bus_attach_device+0x48/0x80
[<403efdbd>] device_add+0x45d/0x5a0
[<403eff12>] device_register+0x12/0x20
[<403f60c3>] isa_register_driver+0xb3/0x140
[<40aa3dd2>] alsa_card_gusclassic_init+0x12/0x20
[<40a665c3>] kernel_init+0x133/0x310
[<401054a7>] kernel_thread_helper+0x7/0x10
=======================
Code: Bad EIP value.
EIP: [<00000000>] 0x0 SS:ESP 0068:7ff87bf4
Kernel panic - not syncing: Fatal exception in interrupt
with these things fixed, i get the expected 'no such hardware' result
from the driver initialization:
Calling initcall 0x40aa3dc0: alsa_card_gusclassic_init+0x0/0x20()
ALSA sound/isa/gus/gusclassic.c:136: [0x220] check 1 failed - 0xff
initcall 0x40aa3dc0: alsa_card_gusclassic_init+0x0/0x20() returned 0.
initcall 0x40aa3dc0 ran for 133 msecs:
alsa_card_gusclassic_init+0x0/0x20()
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c
index a0430b338d67..cd9a6f1c99e6 100644
--- a/sound/isa/gus/gus_irq.c
+++ b/sound/isa/gus/gus_irq.c
@@ -45,11 +45,13 @@ irqreturn_t snd_gus_interrupt(int irq, void *dev_id)
// snd_printk("IRQ: status = 0x%x\n", status);
if (status & 0x02) {
STAT_ADD(gus->gf1.interrupt_stat_midi_in);
- gus->gf1.interrupt_handler_midi_in(gus);
+ if (gus->gf1.interrupt_handler_midi_in)
+ gus->gf1.interrupt_handler_midi_in(gus);
}
if (status & 0x01) {
STAT_ADD(gus->gf1.interrupt_stat_midi_out);
- gus->gf1.interrupt_handler_midi_out(gus);
+ if (gus->gf1.interrupt_handler_midi_out)
+ gus->gf1.interrupt_handler_midi_out(gus);
}
if (status & (0x20 | 0x40)) {
unsigned int already, _current_;
@@ -85,20 +87,24 @@ irqreturn_t snd_gus_interrupt(int irq, void *dev_id)
}
if (status & 0x04) {
STAT_ADD(gus->gf1.interrupt_stat_timer1);
- gus->gf1.interrupt_handler_timer1(gus);
+ if (gus->gf1.interrupt_handler_timer1)
+ gus->gf1.interrupt_handler_timer1(gus);
}
if (status & 0x08) {
STAT_ADD(gus->gf1.interrupt_stat_timer2);
- gus->gf1.interrupt_handler_timer2(gus);
+ if (gus->gf1.interrupt_handler_timer2)
+ gus->gf1.interrupt_handler_timer2(gus);
}
if (status & 0x80) {
if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL) & 0x40) {
STAT_ADD(gus->gf1.interrupt_stat_dma_write);
- gus->gf1.interrupt_handler_dma_write(gus);
+ if (gus->gf1.interrupt_handler_dma_write)
+ gus->gf1.interrupt_handler_dma_write(gus);
}
if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL) & 0x40) {
STAT_ADD(gus->gf1.interrupt_stat_dma_read);
- gus->gf1.interrupt_handler_dma_read(gus);
+ if (gus->gf1.interrupt_handler_dma_read)
+ gus->gf1.interrupt_handler_dma_read(gus);
}
}
if (--loop > 0)
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index ada9209a93a6..b14d5d6d9a32 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -154,6 +154,14 @@ int snd_gus_create(struct snd_card *card,
gus = kzalloc(sizeof(*gus), GFP_KERNEL);
if (gus == NULL)
return -ENOMEM;
+ spin_lock_init(&gus->reg_lock);
+ spin_lock_init(&gus->voice_alloc);
+ spin_lock_init(&gus->active_voice_lock);
+ spin_lock_init(&gus->event_lock);
+ spin_lock_init(&gus->dma_lock);
+ spin_lock_init(&gus->pcm_volume_level_lock);
+ spin_lock_init(&gus->uart_cmd_lock);
+ mutex_init(&gus->dma_mutex);
gus->gf1.irq = -1;
gus->gf1.dma1 = -1;
gus->gf1.dma2 = -1;
@@ -218,14 +226,6 @@ int snd_gus_create(struct snd_card *card,
gus->gf1.pcm_channels = pcm_channels;
gus->gf1.volume_ramp = 25;
gus->gf1.smooth_pan = 1;
- spin_lock_init(&gus->reg_lock);
- spin_lock_init(&gus->voice_alloc);
- spin_lock_init(&gus->active_voice_lock);
- spin_lock_init(&gus->event_lock);
- spin_lock_init(&gus->dma_lock);
- spin_lock_init(&gus->pcm_volume_level_lock);
- spin_lock_init(&gus->uart_cmd_lock);
- mutex_init(&gus->dma_mutex);
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) {
snd_gus_free(gus);
return err;
commit 9c63d9c021f375a2708ad79043d6f4dd1291a085
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Oct 15 17:00:20 2007 +0200
sched: sync wakeups preempt too
make sure sync wakeups preempt too - the scheduler will not
overschedule as we've got various throttles against that.
As a result, sync wakeups can be used more widely in the kernel
(to signal wakeup affinity between tasks), and no arbitrary
latencies will be introduced either.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/kernel/sched.c b/kernel/sched.c
index 7fd343462597..bba57adb9504 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1596,16 +1596,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
schedstat_inc(p, se.nr_wakeups_remote);
update_rq_clock(rq);
activate_task(rq, p, 1);
- /*
- * Sync wakeups (i.e. those types of wakeups where the waker
- * has indicated that it will leave the CPU in short order)
- * don't trigger a preemption, if the woken up task will run on
- * this cpu. (in this case the 'I will reschedule' promise of
- * the waker guarantees that the freshly woken up task is going
- * to be considered on this CPU.)
- */
- if (!sync || rq->curr == rq->idle)
- check_preempt_curr(rq, p);
+ check_preempt_curr(rq, p);
success = 1;
out_running:
commit 71e20f1873d46e138c26ce83f8fe54b7221f572f
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Oct 15 17:00:19 2007 +0200
sched: affine sync wakeups
make sync wakeups affine for cache-cold tasks: if a cache-cold task
is woken up by a sync wakeup then use the opportunity to migrate it
straight away. (the two tasks are 'related' because they communicate)
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/fs/pipe.c b/fs/pipe.c
index f1fa2b412f0e..e66ec48e95d8 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -382,7 +382,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
/* Signal writers asynchronously that there is more room. */
if (do_wakeup) {
- wake_up_interruptible(&pipe->wait);
+ wake_up_interruptible_sync(&pipe->wait);
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
}
if (ret > 0)
@@ -555,7 +555,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
out:
mutex_unlock(&inode->i_mutex);
if (do_wakeup) {
- wake_up_interruptible(&pipe->wait);
+ wake_up_interruptible_sync(&pipe->wait);
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
}
if (ret > 0)
@@ -649,7 +649,7 @@ pipe_release(struct inode *inode, int decr, int decw)
if (!pipe->readers && !pipe->writers) {
free_pipe_info(inode);
} else {
- wake_up_interruptible(&pipe->wait);
+ wake_up_interruptible_sync(&pipe->wait);
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
}
diff --git a/kernel/sched.c b/kernel/sched.c
index 5a91fe0b5de6..7fd343462597 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1521,6 +1521,12 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
unsigned long tl = this_load;
unsigned long tl_per_task;
+ /*
+ * Attract cache-cold tasks on sync wakeups:
+ */
+ if (sync && !task_hot(p, rq->clock, this_sd))
+ goto out_set_cpu;
+
schedstat_inc(p, se.nr_wakeups_affine_attempts);
tl_per_task = cpu_avg_load_per_task(this_cpu);
@@ -1598,7 +1604,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
* the waker guarantees that the freshly woken up task is going
* to be considered on this CPU.)
*/
- if (!sync || cpu != this_cpu)
+ if (!sync || rq->curr == rq->idle)
check_preempt_curr(rq, p);
success = 1;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 2b57eaf66abc..6996cba5aa96 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -334,7 +334,7 @@ static void unix_write_space(struct sock *sk)
read_lock(&sk->sk_callback_lock);
if (unix_writable(sk)) {
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
- wake_up_interruptible(sk->sk_sleep);
+ wake_up_interruptible_sync(sk->sk_sleep);
sk_wake_async(sk, 2, POLL_OUT);
}
read_unlock(&sk->sk_callback_lock);
@@ -1639,7 +1639,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
if (!skb)
goto out_unlock;
- wake_up_interruptible(&u->peer_wait);
+ wake_up_interruptible_sync(&u->peer_wait);
if (msg->msg_name)
unix_copy_addr(msg, skb->sk);