All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [gentoo-sparc] 2.6 kernel and docs
@ 2005-08-29 20:09 David S. Miller
  2005-08-30 15:04 ` Josh Grebe
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: David S. Miller @ 2005-08-29 20:09 UTC (permalink / raw)
  To: sparclinux


Ok, I think I killed the 2.6.x SMP bug on pre-Ultra-III systems using
Symbios scsi controllers, you can read about the process by which I
debugging this in my blog:

	http://vger.kernel.org/~davem/cgi-bin/blog.cgi/index.html

Anyways, the following patch over any recent kernel should provide
the fix.  If it doesn't, go into drivers/scsi/sym53c8xx_2/sym_hipd.c,
function sym_wakeup_done(), and comment out the MEMORY_READ_BARRIER()
that isn't already commented out and retest.

But I think this patch should cure it, for sure, and I'm rerunning
my stress tests to verify that locally as well.

Thanks for being so patient, I hope we got it...

diff-tree 4f07118f656c179740cad35b827032e2e29b1210 (from 442464a50077ff00454ff8d7628cbe1b8eacc034)
Author: David S. Miller <davem@davemloft.net>
Date:   Mon Aug 29 12:46:22 2005 -0700

    [SPARC64]: More fully work around Spitfire Errata 51.
    
    It appears that a memory barrier soon after a mispredicted
    branch, not just in the delay slot, can cause the hang
    condition of this cpu errata.
    
    So move them out-of-line, and explicitly put them into
    a "branch always, predict taken" delay slot which should
    fully kill this problem.
    
    Signed-off-by: David S. Miller <davem@davemloft.net>

diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -466,7 +466,7 @@ do_flush_sync:
 		if (!limit)
 			break;
 		udelay(1);
-		membar("#LoadLoad");
+		rmb();
 	}
 	if (!limit)
 		printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout "
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -103,7 +103,7 @@ void cpu_idle(void)
 		 * other cpus see our increasing idleness for the buddy
 		 * redistribution algorithm.  -DaveM
 		 */
-		membar("#StoreStore | #StoreLoad");
+		membar_storeload_storestore();
 	}
 }
 
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -147,7 +147,7 @@ static void sbus_strbuf_flush(struct sbu
 		if (!limit)
 			break;
 		udelay(1);
-		membar("#LoadLoad");
+		rmb();
 	}
 	if (!limit)
 		printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout "
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -877,11 +877,12 @@ static void new_setup_frame32(struct k_s
 			unsigned long page = (unsigned long)
 				page_address(pte_page(*ptep));
 
-			__asm__ __volatile__(
-			"	membar	#StoreStore\n"
-			"	flush	%0 + %1"
-			: : "r" (page), "r" (address & (PAGE_SIZE - 1))
-			: "memory");
+			wmb();
+			__asm__ __volatile__("flush	%0 + %1"
+					     : /* no outputs */
+					     : "r" (page),
+					       "r" (address & (PAGE_SIZE - 1))
+					     : "memory");
 		}
 		pte_unmap(ptep);
 		preempt_enable();
@@ -1292,11 +1293,12 @@ static void setup_rt_frame32(struct k_si
 			unsigned long page = (unsigned long)
 				page_address(pte_page(*ptep));
 
-			__asm__ __volatile__(
-			"	membar	#StoreStore\n"
-			"	flush	%0 + %1"
-			: : "r" (page), "r" (address & (PAGE_SIZE - 1))
-			: "memory");
+			wmb();
+			__asm__ __volatile__("flush	%0 + %1"
+					     : /* no outputs */
+					     : "r" (page),
+					       "r" (address & (PAGE_SIZE - 1))
+					     : "memory");
 		}
 		pte_unmap(ptep);
 		preempt_enable();
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -144,7 +144,7 @@ void __init smp_callin(void)
 	current->active_mm = &init_mm;
 
 	while (!cpu_isset(cpuid, smp_commenced_mask))
-		membar("#LoadLoad");
+		rmb();
 
 	cpu_set(cpuid, cpu_online_map);
 }
@@ -184,11 +184,11 @@ static inline long get_delta (long *rt, 
 	for (i = 0; i < NUM_ITERS; i++) {
 		t0 = tick_ops->get_tick();
 		go[MASTER] = 1;
-		membar("#StoreLoad");
+		membar_storeload();
 		while (!(tm = go[SLAVE]))
-			membar("#LoadLoad");
+			rmb();
 		go[SLAVE] = 0;
-		membar("#StoreStore");
+		wmb();
 		t1 = tick_ops->get_tick();
 
 		if (t1 - t0 < best_t1 - best_t0)
@@ -221,7 +221,7 @@ void smp_synchronize_tick_client(void)
 	go[MASTER] = 1;
 
 	while (go[MASTER])
-		membar("#LoadLoad");
+		rmb();
 
 	local_irq_save(flags);
 	{
@@ -273,21 +273,21 @@ static void smp_synchronize_one_tick(int
 
 	/* wait for client to be ready */
 	while (!go[MASTER])
-		membar("#LoadLoad");
+		rmb();
 
 	/* now let the client proceed into his loop */
 	go[MASTER] = 0;
-	membar("#StoreLoad");
+	membar_storeload();
 
 	spin_lock_irqsave(&itc_sync_lock, flags);
 	{
 		for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) {
 			while (!go[MASTER])
-				membar("#LoadLoad");
+				rmb();
 			go[MASTER] = 0;
-			membar("#StoreStore");
+			wmb();
 			go[SLAVE] = tick_ops->get_tick();
-			membar("#StoreLoad");
+			membar_storeload();
 		}
 	}
 	spin_unlock_irqrestore(&itc_sync_lock, flags);
@@ -927,11 +927,11 @@ void smp_capture(void)
 		       smp_processor_id());
 #endif
 		penguins_are_doing_time = 1;
-		membar("#StoreStore | #LoadStore");
+		membar_storestore_loadstore();
 		atomic_inc(&smp_capture_registry);
 		smp_cross_call(&xcall_capture, 0, 0, 0);
 		while (atomic_read(&smp_capture_registry) != ncpus)
-			membar("#LoadLoad");
+			rmb();
 #ifdef CAPTURE_DEBUG
 		printk("done\n");
 #endif
@@ -947,7 +947,7 @@ void smp_release(void)
 		       smp_processor_id());
 #endif
 		penguins_are_doing_time = 0;
-		membar("#StoreStore | #StoreLoad");
+		membar_storeload_storestore();
 		atomic_dec(&smp_capture_registry);
 	}
 }
@@ -970,9 +970,9 @@ void smp_penguin_jailcell(int irq, struc
 	save_alternate_globals(global_save);
 	prom_world(1);
 	atomic_inc(&smp_capture_registry);
-	membar("#StoreLoad | #StoreStore");
+	membar_storeload_storestore();
 	while (penguins_are_doing_time)
-		membar("#LoadLoad");
+		rmb();
 	restore_alternate_globals(global_save);
 	atomic_dec(&smp_capture_registry);
 	prom_world(0);
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -406,3 +406,12 @@ EXPORT_SYMBOL(xor_vis_4);
 EXPORT_SYMBOL(xor_vis_5);
 
 EXPORT_SYMBOL(prom_palette);
+
+/* memory barriers */
+EXPORT_SYMBOL(mb);
+EXPORT_SYMBOL(rmb);
+EXPORT_SYMBOL(wmb);
+EXPORT_SYMBOL(membar_storeload);
+EXPORT_SYMBOL(membar_storeload_storestore);
+EXPORT_SYMBOL(membar_storeload_loadload);
+EXPORT_SYMBOL(membar_storestore_loadstore);
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
--- a/arch/sparc64/lib/Makefile
+++ b/arch/sparc64/lib/Makefile
@@ -12,7 +12,7 @@ lib-y := PeeCeeI.o copy_page.o clear_pag
 	 U1memcpy.o U1copy_from_user.o U1copy_to_user.o \
 	 U3memcpy.o U3copy_from_user.o U3copy_to_user.o U3patch.o \
 	 copy_in_user.o user_fixup.o memmove.o \
-	 mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o
+	 mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o mb.o
 
 lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
 lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
diff --git a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c
--- a/arch/sparc64/lib/debuglocks.c
+++ b/arch/sparc64/lib/debuglocks.c
@@ -61,7 +61,7 @@ again:
 			     : "=r" (val)
 			     : "r" (&(lock->lock))
 			     : "memory");
-	membar("#StoreLoad | #StoreStore");
+	membar_storeload_storestore();
 	if (val) {
 		while (lock->lock) {
 			if (!--stuck) {
@@ -69,7 +69,7 @@ again:
 					show(str, lock, caller);
 				stuck = INIT_STUCK;
 			}
-			membar("#LoadLoad");
+			rmb();
 		}
 		goto again;
 	}
@@ -90,7 +90,7 @@ int _do_spin_trylock(spinlock_t *lock, u
 			     : "=r" (val)
 			     : "r" (&(lock->lock))
 			     : "memory");
-	membar("#StoreLoad | #StoreStore");
+	membar_storeload_storestore();
 	if (!val) {
 		lock->owner_pc = ((unsigned int)caller);
 		lock->owner_cpu = cpu;
@@ -107,7 +107,7 @@ void _do_spin_unlock(spinlock_t *lock)
 {
 	lock->owner_pc = 0;
 	lock->owner_cpu = NO_PROC_ID;
-	membar("#StoreStore | #LoadStore");
+	membar_storestore_loadstore();
 	lock->lock = 0;
 	current->thread.smp_lock_count--;
 }
@@ -129,7 +129,7 @@ wlock_again:
 				show_read(str, rw, caller);
 			stuck = INIT_STUCK;
 		}
-		membar("#LoadLoad");
+		rmb();
 	}
 	/* Try once to increment the counter.  */
 	__asm__ __volatile__(
@@ -142,7 +142,7 @@ wlock_again:
 "2:"	: "=r" (val)
 	: "0" (&(rw->lock))
 	: "g1", "g7", "memory");
-	membar("#StoreLoad | #StoreStore");
+	membar_storeload_storestore();
 	if (val)
 		goto wlock_again;
 	rw->reader_pc[cpu] = ((unsigned int)caller);
@@ -201,7 +201,7 @@ wlock_again:
 				show_write(str, rw, caller);
 			stuck = INIT_STUCK;
 		}
-		membar("#LoadLoad");
+		rmb();
 	}
 
 	/* Try to acuire the write bit.  */
@@ -256,7 +256,7 @@ wlock_again:
 					show_write(str, rw, caller);
 				stuck = INIT_STUCK;
 			}
-			membar("#LoadLoad");
+			rmb();
 		}
 		goto wlock_again;
 	}
diff --git a/arch/sparc64/lib/mb.S b/arch/sparc64/lib/mb.S
new file mode 100644
--- /dev/null
+++ b/arch/sparc64/lib/mb.S
@@ -0,0 +1,73 @@
+/* mb.S: Out of line memory barriers.
+ *
+ * Copyright (C) 2005 David S. Miller (davem@davemloft.net)
+ */
+
+	/* These are here in an effort to more fully work around
+	 * Spitfire Errata #51.  Essentially, if a memory barrier
+	 * occurs soon after a mispredicted branch, the chip can stop
+	 * executing instructions until a trap occurs.  Therefore, if
+	 * interrupts are disabled, the chip can hang forever.
+	 *
+	 * It used to be believed that the memory barrier had to be
+	 * right in the delay slot, but a case has been traced
+	 * recently wherein the memory barrier was one instruction
+	 * after the branch delay slot and the chip still hung.  The
+	 * offending sequence was the following in sym_wakeup_done()
+	 * of the sym53c8xx_2 driver:
+	 *
+	 *	call	sym_ccb_from_dsa, 0
+	 *	 movge	%icc, 0, %l0
+	 *	brz,pn	%o0, .LL1303
+	 *	 mov	%o0, %l2
+	 *	membar	#LoadLoad
+	 *
+	 * The branch has to be mispredicted for the bug to occur.
+	 * Therefore, we put the memory barrier explicitly into a
+	 * "branch always, predicted taken" delay slot to avoid the
+	 * problem case.
+	 */
+
+	.text
+
+99:	retl
+	 nop
+
+	.globl	mb
+mb:	ba,pt	%xcc, 99b
+	 membar	#LoadLoad | #LoadStore | #StoreStore | #StoreLoad
+	.size	mb, .-mb
+
+	.globl	rmb
+rmb:	ba,pt	%xcc, 99b
+	 membar	#LoadLoad
+	.size	rmb, .-rmb
+
+	.globl	wmb
+wmb:	ba,pt	%xcc, 99b
+	 membar	#StoreStore
+	.size	wmb, .-wmb
+
+	.globl	membar_storeload
+membar_storeload:
+	ba,pt	%xcc, 99b
+	 membar	#StoreLoad
+	.size	membar_storeload, .-membar_storeload
+
+	.globl	membar_storeload_storestore
+membar_storeload_storestore:
+	ba,pt	%xcc, 99b
+	 membar	#StoreLoad | #StoreStore
+	.size	membar_storeload_storestore, .-membar_storeload_storestore
+
+	.globl	membar_storeload_loadload
+membar_storeload_loadload:
+	ba,pt	%xcc, 99b
+	 membar	#StoreLoad | #LoadLoad
+	.size	membar_storeload_loadload, .-membar_storeload_loadload
+
+	.globl	membar_storestore_loadstore
+membar_storestore_loadstore:
+	ba,pt	%xcc, 99b
+	 membar	#StoreStore | #LoadStore
+	.size	membar_storestore_loadstore, .-membar_storestore_loadstore
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -737,7 +737,8 @@ MODULE_LICENSE("GPL");
 extern u32 tl0_solaris[8];
 #define update_ttable(x) 										\
 	tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000;			\
-	__asm__ __volatile__ ("membar #StoreStore; flush %0" : : "r" (&tl0_solaris[3]))
+	wmb();		\
+	__asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3]))
 #else
 #endif	
 
@@ -761,7 +762,8 @@ int init_module(void)
 	entry64_personality_patch | 		(offsetof(struct task_struct, personality) +
 		 (sizeof(unsigned long) - 1));
-	__asm__ __volatile__("membar #StoreStore; flush %0"
+	wmb();
+	__asm__ __volatile__("flush %0"
 			     : : "r" (&entry64_personality_patch));
 	return 0;
 }
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -72,10 +72,10 @@ extern int atomic64_sub_ret(int, atomic6
 
 /* Atomic operations are already serializing */
 #ifdef CONFIG_SMP
-#define smp_mb__before_atomic_dec()	membar("#StoreLoad | #LoadLoad")
-#define smp_mb__after_atomic_dec()	membar("#StoreLoad | #StoreStore")
-#define smp_mb__before_atomic_inc()	membar("#StoreLoad | #LoadLoad")
-#define smp_mb__after_atomic_inc()	membar("#StoreLoad | #StoreStore")
+#define smp_mb__before_atomic_dec()	membar_storeload_loadload();
+#define smp_mb__after_atomic_dec()	membar_storeload_storestore();
+#define smp_mb__before_atomic_inc()	membar_storeload_loadload();
+#define smp_mb__after_atomic_inc()	membar_storeload_storestore();
 #else
 #define smp_mb__before_atomic_dec()	barrier()
 #define smp_mb__after_atomic_dec()	barrier()
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
--- a/include/asm-sparc64/bitops.h
+++ b/include/asm-sparc64/bitops.h
@@ -72,8 +72,8 @@ static inline int __test_and_change_bit(
 }
 
 #ifdef CONFIG_SMP
-#define smp_mb__before_clear_bit()	membar("#StoreLoad | #LoadLoad")
-#define smp_mb__after_clear_bit()	membar("#StoreLoad | #StoreStore")
+#define smp_mb__before_clear_bit()	membar_storeload_loadload()
+#define smp_mb__after_clear_bit()	membar_storeload_storestore()
 #else
 #define smp_mb__before_clear_bit()	barrier()
 #define smp_mb__after_clear_bit()	barrier()
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -43,7 +43,7 @@ typedef struct {
 #define spin_is_locked(lp)  ((lp)->lock != 0)
 
 #define spin_unlock_wait(lp)	\
-do {	membar("#LoadLoad");	\
+do {	rmb();			\
 } while((lp)->lock)
 
 static inline void _raw_spin_lock(spinlock_t *lock)
@@ -129,7 +129,7 @@ typedef struct {
 #define spin_is_locked(__lock)	((__lock)->lock != 0)
 #define spin_unlock_wait(__lock)	\
 do { \
-	membar("#LoadLoad"); \
+	rmb(); \
 } while((__lock)->lock)
 
 extern void _do_spin_lock(spinlock_t *lock, char *str, unsigned long caller);
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -28,6 +28,14 @@ enum sparc_cpu {
 #define ARCH_SUN4C_SUN4 0
 #define ARCH_SUN4 0
 
+extern void mb(void);
+extern void rmb(void);
+extern void wmb(void);
+extern void membar_storeload(void);
+extern void membar_storeload_storestore(void);
+extern void membar_storeload_loadload(void);
+extern void membar_storestore_loadstore(void);
+
 #endif
 
 #define setipl(__new_ipl) \
@@ -78,16 +86,11 @@ enum sparc_cpu {
 
 #define nop() 		__asm__ __volatile__ ("nop")
 
-#define membar(type)	__asm__ __volatile__ ("membar " type : : : "memory")
-#define mb()		\
-	membar("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad")
-#define rmb()		membar("#LoadLoad")
-#define wmb()		membar("#StoreStore")
 #define read_barrier_depends()		do { } while(0)
 #define set_mb(__var, __value) \
-	do { __var = __value; membar("#StoreLoad | #StoreStore"); } while(0)
+	do { __var = __value; membar_storeload_storestore(); } while(0)
 #define set_wmb(__var, __value) \
-	do { __var = __value; membar("#StoreStore"); } while(0)
+	do { __var = __value; wmb(); } while(0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [gentoo-sparc] 2.6 kernel and docs
  2005-08-29 20:09 [gentoo-sparc] 2.6 kernel and docs David S. Miller
@ 2005-08-30 15:04 ` Josh Grebe
  2005-08-30 18:01 ` David S. Miller
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Josh Grebe @ 2005-08-30 15:04 UTC (permalink / raw)
  To: sparclinux

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

Hi Dave,

Well, its a little different now! I crashed very quickly the first
run, before I commented out that MEMORY_READ_BARRIER(). After
commenting it out, I ran for a couple of hours. The difference is...
Once I've crashed, I can hit enter on my serial console and it echos
it back. Previously, it would not echo back. Sending breaks and sysrq
commands doesn't generate any response.

I do not have a framebuffer/keyboard on this box, and it is remote to
me, but I may be able to assemble an identical box locally that I can
put a frambuffer into, and I'll ask Ferris to test on his box in a
console mode as well. Also, as per your blog, I'll try commenting out
the line in sym53c8xx_2.c that you reference in your blog entry and
see if it makes a difference.

Josh





David S. Miller wrote:
> Ok, I think I killed the 2.6.x SMP bug on pre-Ultra-III systems using
> Symbios scsi controllers, you can read about the process by which I
> debugging this in my blog:
> 
> 	http://vger.kernel.org/~davem/cgi-bin/blog.cgi/index.html
> 
> Anyways, the following patch over any recent kernel should provide
> the fix.  If it doesn't, go into drivers/scsi/sym53c8xx_2/sym_hipd.c,
> function sym_wakeup_done(), and comment out the MEMORY_READ_BARRIER()
> that isn't already commented out and retest.
> 
> But I think this patch should cure it, for sure, and I'm rerunning
> my stress tests to verify that locally as well.
> 
> Thanks for being so patient, I hope we got it...
> 
> diff-tree 4f07118f656c179740cad35b827032e2e29b1210 (from 442464a50077ff00454ff8d7628cbe1b8eacc034)
> Author: David S. Miller <davem@davemloft.net>
> Date:   Mon Aug 29 12:46:22 2005 -0700
> 
>     [SPARC64]: More fully work around Spitfire Errata 51.
>     
>     It appears that a memory barrier soon after a mispredicted
>     branch, not just in the delay slot, can cause the hang
>     condition of this cpu errata.
>     
>     So move them out-of-line, and explicitly put them into
>     a "branch always, predict taken" delay slot which should
>     fully kill this problem.
>     
>     Signed-off-by: David S. Miller <davem@davemloft.net>
> 
> diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
> --- a/arch/sparc64/kernel/pci_iommu.c
> +++ b/arch/sparc64/kernel/pci_iommu.c
> @@ -466,7 +466,7 @@ do_flush_sync:
>  		if (!limit)
>  			break;
>  		udelay(1);
> -		membar("#LoadLoad");
> +		rmb();
>  	}
>  	if (!limit)
>  		printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout "
> diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
> --- a/arch/sparc64/kernel/process.c
> +++ b/arch/sparc64/kernel/process.c
> @@ -103,7 +103,7 @@ void cpu_idle(void)
>  		 * other cpus see our increasing idleness for the buddy
>  		 * redistribution algorithm.  -DaveM
>  		 */
> -		membar("#StoreStore | #StoreLoad");
> +		membar_storeload_storestore();
>  	}
>  }
>  
> diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
> --- a/arch/sparc64/kernel/sbus.c
> +++ b/arch/sparc64/kernel/sbus.c
> @@ -147,7 +147,7 @@ static void sbus_strbuf_flush(struct sbu
>  		if (!limit)
>  			break;
>  		udelay(1);
> -		membar("#LoadLoad");
> +		rmb();
>  	}
>  	if (!limit)
>  		printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout "
> diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
> --- a/arch/sparc64/kernel/signal32.c
> +++ b/arch/sparc64/kernel/signal32.c
> @@ -877,11 +877,12 @@ static void new_setup_frame32(struct k_s
>  			unsigned long page = (unsigned long)
>  				page_address(pte_page(*ptep));
>  
> -			__asm__ __volatile__(
> -			"	membar	#StoreStore\n"
> -			"	flush	%0 + %1"
> -			: : "r" (page), "r" (address & (PAGE_SIZE - 1))
> -			: "memory");
> +			wmb();
> +			__asm__ __volatile__("flush	%0 + %1"
> +					     : /* no outputs */
> +					     : "r" (page),
> +					       "r" (address & (PAGE_SIZE - 1))
> +					     : "memory");
>  		}
>  		pte_unmap(ptep);
>  		preempt_enable();
> @@ -1292,11 +1293,12 @@ static void setup_rt_frame32(struct k_si
>  			unsigned long page = (unsigned long)
>  				page_address(pte_page(*ptep));
>  
> -			__asm__ __volatile__(
> -			"	membar	#StoreStore\n"
> -			"	flush	%0 + %1"
> -			: : "r" (page), "r" (address & (PAGE_SIZE - 1))
> -			: "memory");
> +			wmb();
> +			__asm__ __volatile__("flush	%0 + %1"
> +					     : /* no outputs */
> +					     : "r" (page),
> +					       "r" (address & (PAGE_SIZE - 1))
> +					     : "memory");
>  		}
>  		pte_unmap(ptep);
>  		preempt_enable();
> diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
> --- a/arch/sparc64/kernel/smp.c
> +++ b/arch/sparc64/kernel/smp.c
> @@ -144,7 +144,7 @@ void __init smp_callin(void)
>  	current->active_mm = &init_mm;
>  
>  	while (!cpu_isset(cpuid, smp_commenced_mask))
> -		membar("#LoadLoad");
> +		rmb();
>  
>  	cpu_set(cpuid, cpu_online_map);
>  }
> @@ -184,11 +184,11 @@ static inline long get_delta (long *rt, 
>  	for (i = 0; i < NUM_ITERS; i++) {
>  		t0 = tick_ops->get_tick();
>  		go[MASTER] = 1;
> -		membar("#StoreLoad");
> +		membar_storeload();
>  		while (!(tm = go[SLAVE]))
> -			membar("#LoadLoad");
> +			rmb();
>  		go[SLAVE] = 0;
> -		membar("#StoreStore");
> +		wmb();
>  		t1 = tick_ops->get_tick();
>  
>  		if (t1 - t0 < best_t1 - best_t0)
> @@ -221,7 +221,7 @@ void smp_synchronize_tick_client(void)
>  	go[MASTER] = 1;
>  
>  	while (go[MASTER])
> -		membar("#LoadLoad");
> +		rmb();
>  
>  	local_irq_save(flags);
>  	{
> @@ -273,21 +273,21 @@ static void smp_synchronize_one_tick(int
>  
>  	/* wait for client to be ready */
>  	while (!go[MASTER])
> -		membar("#LoadLoad");
> +		rmb();
>  
>  	/* now let the client proceed into his loop */
>  	go[MASTER] = 0;
> -	membar("#StoreLoad");
> +	membar_storeload();
>  
>  	spin_lock_irqsave(&itc_sync_lock, flags);
>  	{
>  		for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) {
>  			while (!go[MASTER])
> -				membar("#LoadLoad");
> +				rmb();
>  			go[MASTER] = 0;
> -			membar("#StoreStore");
> +			wmb();
>  			go[SLAVE] = tick_ops->get_tick();
> -			membar("#StoreLoad");
> +			membar_storeload();
>  		}
>  	}
>  	spin_unlock_irqrestore(&itc_sync_lock, flags);
> @@ -927,11 +927,11 @@ void smp_capture(void)
>  		       smp_processor_id());
>  #endif
>  		penguins_are_doing_time = 1;
> -		membar("#StoreStore | #LoadStore");
> +		membar_storestore_loadstore();
>  		atomic_inc(&smp_capture_registry);
>  		smp_cross_call(&xcall_capture, 0, 0, 0);
>  		while (atomic_read(&smp_capture_registry) != ncpus)
> -			membar("#LoadLoad");
> +			rmb();
>  #ifdef CAPTURE_DEBUG
>  		printk("done\n");
>  #endif
> @@ -947,7 +947,7 @@ void smp_release(void)
>  		       smp_processor_id());
>  #endif
>  		penguins_are_doing_time = 0;
> -		membar("#StoreStore | #StoreLoad");
> +		membar_storeload_storestore();
>  		atomic_dec(&smp_capture_registry);
>  	}
>  }
> @@ -970,9 +970,9 @@ void smp_penguin_jailcell(int irq, struc
>  	save_alternate_globals(global_save);
>  	prom_world(1);
>  	atomic_inc(&smp_capture_registry);
> -	membar("#StoreLoad | #StoreStore");
> +	membar_storeload_storestore();
>  	while (penguins_are_doing_time)
> -		membar("#LoadLoad");
> +		rmb();
>  	restore_alternate_globals(global_save);
>  	atomic_dec(&smp_capture_registry);
>  	prom_world(0);
> diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
> --- a/arch/sparc64/kernel/sparc64_ksyms.c
> +++ b/arch/sparc64/kernel/sparc64_ksyms.c
> @@ -406,3 +406,12 @@ EXPORT_SYMBOL(xor_vis_4);
>  EXPORT_SYMBOL(xor_vis_5);
>  
>  EXPORT_SYMBOL(prom_palette);
> +
> +/* memory barriers */
> +EXPORT_SYMBOL(mb);
> +EXPORT_SYMBOL(rmb);
> +EXPORT_SYMBOL(wmb);
> +EXPORT_SYMBOL(membar_storeload);
> +EXPORT_SYMBOL(membar_storeload_storestore);
> +EXPORT_SYMBOL(membar_storeload_loadload);
> +EXPORT_SYMBOL(membar_storestore_loadstore);
> diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
> --- a/arch/sparc64/lib/Makefile
> +++ b/arch/sparc64/lib/Makefile
> @@ -12,7 +12,7 @@ lib-y := PeeCeeI.o copy_page.o clear_pag
>  	 U1memcpy.o U1copy_from_user.o U1copy_to_user.o \
>  	 U3memcpy.o U3copy_from_user.o U3copy_to_user.o U3patch.o \
>  	 copy_in_user.o user_fixup.o memmove.o \
> -	 mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o
> +	 mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o mb.o
>  
>  lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
>  lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
> diff --git a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c
> --- a/arch/sparc64/lib/debuglocks.c
> +++ b/arch/sparc64/lib/debuglocks.c
> @@ -61,7 +61,7 @@ again:
>  			     : "=r" (val)
>  			     : "r" (&(lock->lock))
>  			     : "memory");
> -	membar("#StoreLoad | #StoreStore");
> +	membar_storeload_storestore();
>  	if (val) {
>  		while (lock->lock) {
>  			if (!--stuck) {
> @@ -69,7 +69,7 @@ again:
>  					show(str, lock, caller);
>  				stuck = INIT_STUCK;
>  			}
> -			membar("#LoadLoad");
> +			rmb();
>  		}
>  		goto again;
>  	}
> @@ -90,7 +90,7 @@ int _do_spin_trylock(spinlock_t *lock, u
>  			     : "=r" (val)
>  			     : "r" (&(lock->lock))
>  			     : "memory");
> -	membar("#StoreLoad | #StoreStore");
> +	membar_storeload_storestore();
>  	if (!val) {
>  		lock->owner_pc = ((unsigned int)caller);
>  		lock->owner_cpu = cpu;
> @@ -107,7 +107,7 @@ void _do_spin_unlock(spinlock_t *lock)
>  {
>  	lock->owner_pc = 0;
>  	lock->owner_cpu = NO_PROC_ID;
> -	membar("#StoreStore | #LoadStore");
> +	membar_storestore_loadstore();
>  	lock->lock = 0;
>  	current->thread.smp_lock_count--;
>  }
> @@ -129,7 +129,7 @@ wlock_again:
>  				show_read(str, rw, caller);
>  			stuck = INIT_STUCK;
>  		}
> -		membar("#LoadLoad");
> +		rmb();
>  	}
>  	/* Try once to increment the counter.  */
>  	__asm__ __volatile__(
> @@ -142,7 +142,7 @@ wlock_again:
>  "2:"	: "=r" (val)
>  	: "0" (&(rw->lock))
>  	: "g1", "g7", "memory");
> -	membar("#StoreLoad | #StoreStore");
> +	membar_storeload_storestore();
>  	if (val)
>  		goto wlock_again;
>  	rw->reader_pc[cpu] = ((unsigned int)caller);
> @@ -201,7 +201,7 @@ wlock_again:
>  				show_write(str, rw, caller);
>  			stuck = INIT_STUCK;
>  		}
> -		membar("#LoadLoad");
> +		rmb();
>  	}
>  
>  	/* Try to acuire the write bit.  */
> @@ -256,7 +256,7 @@ wlock_again:
>  					show_write(str, rw, caller);
>  				stuck = INIT_STUCK;
>  			}
> -			membar("#LoadLoad");
> +			rmb();
>  		}
>  		goto wlock_again;
>  	}
> diff --git a/arch/sparc64/lib/mb.S b/arch/sparc64/lib/mb.S
> new file mode 100644
> --- /dev/null
> +++ b/arch/sparc64/lib/mb.S
> @@ -0,0 +1,73 @@
> +/* mb.S: Out of line memory barriers.
> + *
> + * Copyright (C) 2005 David S. Miller (davem@davemloft.net)
> + */
> +
> +	/* These are here in an effort to more fully work around
> +	 * Spitfire Errata #51.  Essentially, if a memory barrier
> +	 * occurs soon after a mispredicted branch, the chip can stop
> +	 * executing instructions until a trap occurs.  Therefore, if
> +	 * interrupts are disabled, the chip can hang forever.
> +	 *
> +	 * It used to be believed that the memory barrier had to be
> +	 * right in the delay slot, but a case has been traced
> +	 * recently wherein the memory barrier was one instruction
> +	 * after the branch delay slot and the chip still hung.  The
> +	 * offending sequence was the following in sym_wakeup_done()
> +	 * of the sym53c8xx_2 driver:
> +	 *
> +	 *	call	sym_ccb_from_dsa, 0
> +	 *	 movge	%icc, 0, %l0
> +	 *	brz,pn	%o0, .LL1303
> +	 *	 mov	%o0, %l2
> +	 *	membar	#LoadLoad
> +	 *
> +	 * The branch has to be mispredicted for the bug to occur.
> +	 * Therefore, we put the memory barrier explicitly into a
> +	 * "branch always, predicted taken" delay slot to avoid the
> +	 * problem case.
> +	 */
> +
> +	.text
> +
> +99:	retl
> +	 nop
> +
> +	.globl	mb
> +mb:	ba,pt	%xcc, 99b
> +	 membar	#LoadLoad | #LoadStore | #StoreStore | #StoreLoad
> +	.size	mb, .-mb
> +
> +	.globl	rmb
> +rmb:	ba,pt	%xcc, 99b
> +	 membar	#LoadLoad
> +	.size	rmb, .-rmb
> +
> +	.globl	wmb
> +wmb:	ba,pt	%xcc, 99b
> +	 membar	#StoreStore
> +	.size	wmb, .-wmb
> +
> +	.globl	membar_storeload
> +membar_storeload:
> +	ba,pt	%xcc, 99b
> +	 membar	#StoreLoad
> +	.size	membar_storeload, .-membar_storeload
> +
> +	.globl	membar_storeload_storestore
> +membar_storeload_storestore:
> +	ba,pt	%xcc, 99b
> +	 membar	#StoreLoad | #StoreStore
> +	.size	membar_storeload_storestore, .-membar_storeload_storestore
> +
> +	.globl	membar_storeload_loadload
> +membar_storeload_loadload:
> +	ba,pt	%xcc, 99b
> +	 membar	#StoreLoad | #LoadLoad
> +	.size	membar_storeload_loadload, .-membar_storeload_loadload
> +
> +	.globl	membar_storestore_loadstore
> +membar_storestore_loadstore:
> +	ba,pt	%xcc, 99b
> +	 membar	#StoreStore | #LoadStore
> +	.size	membar_storestore_loadstore, .-membar_storestore_loadstore
> diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
> --- a/arch/sparc64/solaris/misc.c
> +++ b/arch/sparc64/solaris/misc.c
> @@ -737,7 +737,8 @@ MODULE_LICENSE("GPL");
>  extern u32 tl0_solaris[8];
>  #define update_ttable(x) 										\
>  	tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000;			\
> -	__asm__ __volatile__ ("membar #StoreStore; flush %0" : : "r" (&tl0_solaris[3]))
> +	wmb();		\
> +	__asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3]))
>  #else
>  #endif	
>  
> @@ -761,7 +762,8 @@ int init_module(void)
>  	entry64_personality_patch |>  		(offsetof(struct task_struct, personality) +
>  		 (sizeof(unsigned long) - 1));
> -	__asm__ __volatile__("membar #StoreStore; flush %0"
> +	wmb();
> +	__asm__ __volatile__("flush %0"
>  			     : : "r" (&entry64_personality_patch));
>  	return 0;
>  }
> diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
> --- a/include/asm-sparc64/atomic.h
> +++ b/include/asm-sparc64/atomic.h
> @@ -72,10 +72,10 @@ extern int atomic64_sub_ret(int, atomic6
>  
>  /* Atomic operations are already serializing */
>  #ifdef CONFIG_SMP
> -#define smp_mb__before_atomic_dec()	membar("#StoreLoad | #LoadLoad")
> -#define smp_mb__after_atomic_dec()	membar("#StoreLoad | #StoreStore")
> -#define smp_mb__before_atomic_inc()	membar("#StoreLoad | #LoadLoad")
> -#define smp_mb__after_atomic_inc()	membar("#StoreLoad | #StoreStore")
> +#define smp_mb__before_atomic_dec()	membar_storeload_loadload();
> +#define smp_mb__after_atomic_dec()	membar_storeload_storestore();
> +#define smp_mb__before_atomic_inc()	membar_storeload_loadload();
> +#define smp_mb__after_atomic_inc()	membar_storeload_storestore();
>  #else
>  #define smp_mb__before_atomic_dec()	barrier()
>  #define smp_mb__after_atomic_dec()	barrier()
> diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
> --- a/include/asm-sparc64/bitops.h
> +++ b/include/asm-sparc64/bitops.h
> @@ -72,8 +72,8 @@ static inline int __test_and_change_bit(
>  }
>  
>  #ifdef CONFIG_SMP
> -#define smp_mb__before_clear_bit()	membar("#StoreLoad | #LoadLoad")
> -#define smp_mb__after_clear_bit()	membar("#StoreLoad | #StoreStore")
> +#define smp_mb__before_clear_bit()	membar_storeload_loadload()
> +#define smp_mb__after_clear_bit()	membar_storeload_storestore()
>  #else
>  #define smp_mb__before_clear_bit()	barrier()
>  #define smp_mb__after_clear_bit()	barrier()
> diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
> --- a/include/asm-sparc64/spinlock.h
> +++ b/include/asm-sparc64/spinlock.h
> @@ -43,7 +43,7 @@ typedef struct {
>  #define spin_is_locked(lp)  ((lp)->lock != 0)
>  
>  #define spin_unlock_wait(lp)	\
> -do {	membar("#LoadLoad");	\
> +do {	rmb();			\
>  } while((lp)->lock)
>  
>  static inline void _raw_spin_lock(spinlock_t *lock)
> @@ -129,7 +129,7 @@ typedef struct {
>  #define spin_is_locked(__lock)	((__lock)->lock != 0)
>  #define spin_unlock_wait(__lock)	\
>  do { \
> -	membar("#LoadLoad"); \
> +	rmb(); \
>  } while((__lock)->lock)
>  
>  extern void _do_spin_lock(spinlock_t *lock, char *str, unsigned long caller);
> diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
> --- a/include/asm-sparc64/system.h
> +++ b/include/asm-sparc64/system.h
> @@ -28,6 +28,14 @@ enum sparc_cpu {
>  #define ARCH_SUN4C_SUN4 0
>  #define ARCH_SUN4 0
>  
> +extern void mb(void);
> +extern void rmb(void);
> +extern void wmb(void);
> +extern void membar_storeload(void);
> +extern void membar_storeload_storestore(void);
> +extern void membar_storeload_loadload(void);
> +extern void membar_storestore_loadstore(void);
> +
>  #endif
>  
>  #define setipl(__new_ipl) \
> @@ -78,16 +86,11 @@ enum sparc_cpu {
>  
>  #define nop() 		__asm__ __volatile__ ("nop")
>  
> -#define membar(type)	__asm__ __volatile__ ("membar " type : : : "memory")
> -#define mb()		\
> -	membar("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad")
> -#define rmb()		membar("#LoadLoad")
> -#define wmb()		membar("#StoreStore")
>  #define read_barrier_depends()		do { } while(0)
>  #define set_mb(__var, __value) \
> -	do { __var = __value; membar("#StoreLoad | #StoreStore"); } while(0)
> +	do { __var = __value; membar_storeload_storestore(); } while(0)
>  #define set_wmb(__var, __value) \
> -	do { __var = __value; membar("#StoreStore"); } while(0)
> +	do { __var = __value; wmb(); } while(0)
>  
>  #ifdef CONFIG_SMP
>  #define smp_mb()	mb()
> -
> To unsubscribe from this list: send the line "unsubscribe sparclinux" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> !DSPAM:43136ac7289081123014463!
> 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFDFHVpT/OY5rt9JCMRA1rRAJ4k3gRRknYJ6AjDFXXr9vJIGzJadQCfaSab
xa1roJpo3gorPa597FDc2Vs=nCiu
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [gentoo-sparc] 2.6 kernel and docs
  2005-08-29 20:09 [gentoo-sparc] 2.6 kernel and docs David S. Miller
  2005-08-30 15:04 ` Josh Grebe
@ 2005-08-30 18:01 ` David S. Miller
  2005-09-07 20:01 ` Josh Grebe
  2005-09-07 20:36 ` David S. Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David S. Miller @ 2005-08-30 18:01 UTC (permalink / raw)
  To: sparclinux

From: Josh Grebe <josh@brokedown.net>
Date: Tue, 30 Aug 2005 10:04:10 -0500

> Well, its a little different now! I crashed very quickly the first
> run, before I commented out that MEMORY_READ_BARRIER().

We really can't be testing the same kernels then.
Mine ran for hours and hours on end, even spamming my
xterms with tar output over the network to my workstation
in parallel.

Linus's current 2.6.14 GIT tree has all of my fixes in
it, maybe you can test that.

And if you get a wedge again, please turn on spinlock
debugging, CONFIG_DEBUG_SPINLOCK, because that is how I
got my traces.

And please do it with a head and keyboard attached so we
can eliminate the sketchy serial console layer as a variable.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [gentoo-sparc] 2.6 kernel and docs
  2005-08-29 20:09 [gentoo-sparc] 2.6 kernel and docs David S. Miller
  2005-08-30 15:04 ` Josh Grebe
  2005-08-30 18:01 ` David S. Miller
@ 2005-09-07 20:01 ` Josh Grebe
  2005-09-07 20:36 ` David S. Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Josh Grebe @ 2005-09-07 20:01 UTC (permalink / raw)
  To: sparclinux

[-- Attachment #1: Type: text/plain, Size: 2270 bytes --]

Hi Dave,

Sorry it took a few days to get back on this, but I wanted to get some
additional testing in before I came back in.

Linus' current git tree crashes on my netra 1405, the same as previous 2.6
kernels. It also crashes on Ferris McCormick's Ultra60. I have tried both with
and without the second MEMORY_READ_BARRIER() call commented. Once the crash hit,
Ferris was unable to issue sysrq commands from the keyboard.

To complicate matters, I built a second Netra 1405 with a similar configuratino
(4x440 and 1G ram) but added a keyboard and framebuffer, and I could not trigger
the crash. Ferris' Ultra60 also has a keyboard and framebuffer and happily crashes.

I also built a T1125 (ultra60) with 2x440 and 1G ram, and I could not convince
it to crash. This unit used serial console. Since Ferris' Ultra60 has 2x300, I
also tried underclocking to that speed and could not trigger the crash.

To further complicate things, and to rule out compiler/toolchain, I used the
same binary kernel image on all boxes. I'm trying to kill every variable I can.

I guess my next step is to pick up the crashing Netra and throw a
framebuffer/keyboard on it, but I think that base has been covered by Ferris'
Ultra60. This will take a few days to do.

Josh



David S. Miller wrote:
> From: Josh Grebe <josh@brokedown.net>
> Date: Tue, 30 Aug 2005 10:04:10 -0500
> 
> 
>>Well, its a little different now! I crashed very quickly the first
>>run, before I commented out that MEMORY_READ_BARRIER().
> 
> 
> We really can't be testing the same kernels then.
> Mine ran for hours and hours on end, even spamming my
> xterms with tar output over the network to my workstation
> in parallel.
> 
> Linus's current 2.6.14 GIT tree has all of my fixes in
> it, maybe you can test that.
> 
> And if you get a wedge again, please turn on spinlock
> debugging, CONFIG_DEBUG_SPINLOCK, because that is how I
> got my traces.
> 
> And please do it with a head and keyboard attached so we
> can eliminate the sketchy serial console layer as a variable.
> -
> To unsubscribe from this list: send the line "unsubscribe sparclinux" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> !DSPAM:43149e2d95798517817808!
> 

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 256 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [gentoo-sparc] 2.6 kernel and docs
  2005-08-29 20:09 [gentoo-sparc] 2.6 kernel and docs David S. Miller
                   ` (2 preceding siblings ...)
  2005-09-07 20:01 ` Josh Grebe
@ 2005-09-07 20:36 ` David S. Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David S. Miller @ 2005-09-07 20:36 UTC (permalink / raw)
  To: sparclinux

From: Josh Grebe <squash@gentoo.org>
Date: Wed, 07 Sep 2005 15:01:35 -0500

> Sorry it took a few days to get back on this, but I wanted to get
> some additional testing in before I came back in.

Thanks for the report Josh.

One thing you can do to make debugging easier is to make the sym53c8xx
interrupts sit on one cpu and make all the other interrupt on other
cpus.  This way if the cpu dies in the sym53c8xx interrupt handler,
it won't take out all the other devices.

You can do this using /proc/irq/???/smp_affinity on sparc64.

As an example, my Ultra60 reports in /proc/interrupts:

  0:  194764100          0  timer:dead
  4:         40   12856363  su(mouse):7ea, sym53c8xx:7e0, sym53c8xx:7e6
  5:          0    7738341  eth0:7e1
  9:         91          5  su(kbd):7e9
 15:          0          0  PSYCHO UE:7ee, PSYCHO CE:7ef, PSYCHO PCIERR:7f0, PSYCHO PCIERR:7f1

After each IRQ name is the 3-hex IRQ number.  The 'smp_affinity' value
is a bit-mask.  The cpu numbers on my machine are 0 and 2, so all
the smp_affinity values default to "00000005" enabling both cpus.

So what you'd want to do is, for example:

1) Set the smp_affinity of 7e0 and 7e6 (the two sym53c8xx driver
   irqs) to "00000001"

2) Set the smp_affinity of all other interrupts to "00000004"

In this way the serial console, network, and keyboard/framebuffer
will not die if the cpu hangs in the sym53c8xx interrupt handler
which I am certain is the root of this bug.

Once you have that setup, CONFIG_DEBUG_SPINLOCK should give meaningful
output when the system wedges.

Hope this helps.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-09-07 20:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-29 20:09 [gentoo-sparc] 2.6 kernel and docs David S. Miller
2005-08-30 15:04 ` Josh Grebe
2005-08-30 18:01 ` David S. Miller
2005-09-07 20:01 ` Josh Grebe
2005-09-07 20:36 ` David S. Miller

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.