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);