Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Feb 2006 13:48:24 +0100
From:      Marius Strobl <marius@alchemy.franken.de>
To:        Antoine Brodin <antoine.brodin@laposte.net>, jhb@freebsd.org
Cc:        freebsd-sparc64@freebsd.org
Subject:   Re: sparc64/93226: DEBUG_LOCKS (really stack_save()) causes panics on sparc64
Message-ID:  <20060216134823.S53619@newtrinity.zeist.de>
In-Reply-To: <20060214205432.38121641.antoine.brodin@laposte.net>; from antoine.brodin@laposte.net on Tue, Feb 14, 2006 at 08:54:32PM %2B0100
References:  <200602131150.k1DBo6S1074438@freefall.freebsd.org> <200602131223.51561.jhb@freebsd.org> <20060213193613.547d1b8f.antoine.brodin@laposte.net> <200602131430.11228.jhb@freebsd.org> <20060213213719.7767921e.antoine.brodin@laposte.net> <20060214094744.A81690@newtrinity.zeist.de> <20060214205432.38121641.antoine.brodin@laposte.net>

next in thread | previous in thread | raw e-mail | index | archive | help

--uZ3hkaAS1mZxFaxD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Tue, Feb 14, 2006 at 08:54:32PM +0100, Antoine Brodin wrote:
> Marius Strobl <marius@alchemy.franken.de> wrote:
> > On Mon, Feb 13, 2006 at 09:37:19PM +0100, Antoine Brodin wrote:
> > > John Baldwin <jhb@freebsd.org> wrote:
> > > > On Monday 13 February 2006 13:36, Antoine Brodin wrote:
> > > > > John Baldwin <jhb@freebsd.org> wrote:
> > > > > > If there are kernel functions before the assembly ones (dependent on link
> > > > > > order) then this would wrongly bail when it hit those.  I think you need
> > > > > > to do what the ddb stack tracing code does which is to lookup the symbol
> > > > > > name and do a bcmp() on the first 4 chars to recognize trapframes.
> > > > >
> > > > > I ran objdump -d on a sparc64 kernel and it looks like tl0_* and tl1_*
> > > > > are always at the beginning of the code, there is some kind of magic.
> > > > 
> > > > magic aside, it would be best to use the same algorithm in both places IMO.  
> > > > It would also be a lot more intuitive to other folks later on.
> > > 
> > > There are 2 reasons why I didn't use db_search_symbol() and
> > > db_symbol_values() :
> > > 
> > > - first they aren't reentrant, they use a global variable
> > > db_last_symtab and they can panic if a thread sets db_last_symtab to 0
> > > while another one is using it. I found this in my mail archive :
> > > %%%
> > > Stopped at      X_db_symbol_values+0x18:        cmpl    $0,0xc(%eax)
> > > db> trace
> > > Tracing pid 34983 tid 100093 td 0xc2e9c640
> > > X_db_symbol_values(0,c0738214,e84859f4,e84859c4,7c) at X_db_symbol_values+0x18
> > > db_symbol_values(c0738214,e84859f4,0,c89d19c8,0) at db_symbol_values+0x40
> > > %%%
> > > It can be fixed easily but I don't have the fix anymore.
> > > You can use linker_ddb_search_symbol() and linker_ddb_symbol_values() 
> > > too that are safer.
> > > 
> > > - the second reason is performance. if you replace 
> > > CTRSTACK(KTR_LOCK, &stack, 0, 1);
> > > by
> > > CTRSTACK(KTR_LOCK, &stack, 0, 0);
> > > in kern_lock.c, i.e. if you print the symbol name in the ktr traces, you
> > > will notice that your box is extremely slow. (you type ls, you wait 4 or 5
> > > seconds and you have the result)
> > > 
> > 
> > Can't we just use what's done in support.S and add two dummy symbols
> > to mark the begin and end of the asm functions in question?
> 
> There's already a tl0_base symbol.  You can add a tl0_end (or tl1_end ?)
> symbol between tl1_intr and fork_trampoline.
> 

Ok, how about the attached patch? It uses two pairs of dummy symbols
in exception.S to determine in stack_save() whether it was one of the
tl0_*() or tl1_*() asm functions; one pair for those in the .trap
section that is "magically" placed at the beginning of the .text
section via the linker script and the other pair for those in the
regular .text section. That way we don't rely on the location of
these functions in the kernel and don't have the performance penalty
of *search_symbol()/*symbol_values(). For consistency db_backtrace()
is changed to also use the new markers instead of bcmp()'ing with
the symbol names.

Marius


-- 
This mail was scanned by AntiVir Milter.
This product is licensed for non-commercial use.
See www.antivir.de for details.
--uZ3hkaAS1mZxFaxD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="db_tl.diff"

Index: exception.S
===================================================================
RCS file: /mnt/futile/usr/data/bsd/cvs/fbsd/src/sys/sparc64/sparc64/exception.S,v
retrieving revision 1.71
diff -u -r1.71 exception.S
--- exception.S	16 Jan 2006 01:35:25 -0000	1.71
+++ exception.S	16 Feb 2006 11:59:50 -0000
@@ -166,6 +166,10 @@
 	ldx	[ASP_REG + 0], %g1 ; \
 	inc	16, ASP_REG
 
+	.globl	tl_text_begin
+tl_text_begin:
+	nop
+
 ENTRY(tl1_kstack_fault)
 	rdpr	%tl, %g1
 1:	cmp	%g1, 2
@@ -1818,6 +1822,10 @@
 	.endm
 
 	.sect	.trap
+	.globl	tl_trap_begin
+tl_trap_begin:
+	nop
+
 	.align	0x8000
 	.globl	tl0_base
 
@@ -2015,6 +2023,10 @@
 	tl1_gen		T_RSTRWP_VIRT			! 0x303
 	tl1_reserved	252				! 0x304-0x3ff
 
+	.globl	tl_trap_end
+tl_trap_end:
+	nop
+
 /*
  * User trap entry point.
  *
@@ -2901,6 +2913,10 @@
 	retry
 END(tl1_intr)
 
+	.globl	tl_text_end
+tl_text_end:
+	nop
+
 /*
  * Freshly forked processes come here when switched to for the first time.
  * The arguments to fork_exit() have been setup in the locals, we must move
Index: db_trace.c
===================================================================
RCS file: /mnt/futile/usr/data/bsd/cvs/fbsd/src/sys/sparc64/sparc64/db_trace.c,v
retrieving revision 1.24
diff -u -r1.24 db_trace.c
--- db_trace.c	3 Aug 2005 04:27:39 -0000	1.24
+++ db_trace.c	16 Feb 2006 11:51:27 -0000
@@ -49,6 +49,11 @@
 #include <ddb/db_variables.h>
 #include <ddb/db_watch.h>
 
+extern char tl_trap_begin[];
+extern char tl_trap_end[];
+extern char tl_text_begin[];
+extern char tl_text_end[];
+
 #define	INKERNEL(va) \
 	((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS)
 
@@ -259,8 +264,10 @@
 			name = "(null)";
 		fp = (struct frame *)(db_get_value((db_addr_t)&fp->fr_fp,
 		   sizeof(fp->fr_fp), FALSE) + SPOFF);
-		if (bcmp(name, "tl0_", 4) == 0 ||
-		    bcmp(name, "tl1_", 4) == 0) {
+		if ((value > (u_long)tl_trap_begin &&
+		    value < (u_long)tl_trap_end) ||
+		    (value > (u_long)tl_text_begin &&
+		    value < (u_long)tl_text_end)) {
 			tf = (struct trapframe *)(fp + 1);
 			npc = db_get_value((db_addr_t)&tf->tf_tpc,
 			    sizeof(tf->tf_tpc), FALSE);
@@ -307,6 +314,12 @@
 		callpc = fp->fr_pc;
 		if (!INKERNEL(callpc))
 			break;
+		/* Don't bother traversing trap frames. */
+		if ((callpc > (u_long)tl_trap_begin &&
+		    callpc < (u_long)tl_trap_end) ||
+		    (callpc > (u_long)tl_text_begin &&
+		    callpc < (u_long)tl_text_end))
+			break;
 		if (stack_put(st, callpc) == -1)
 			break;
 		fp = (struct frame *)(fp->fr_fp + SPOFF);


--uZ3hkaAS1mZxFaxD--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060216134823.S53619>