Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Alexander Beregalov" <a.beregalov@xxxxxxxxx>
Date: Sat, 21 Jun 2008 02:42:36 +0400

> I can not see such messages in lockdep output:
> 
> [   17.960404] Console: colour dummy device 80x25
> [   18.060543] console handover: boot [earlyprom0] -> real [tty0]
> [   18.169062] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc.,
> Ingo Molnar
> [   18.169180] ... MAX_LOCKDEP_SUBCLASSES:    8
> [   18.169246] ... MAX_LOCK_DEPTH:          48
> [   18.169310] ... MAX_LOCKDEP_KEYS:        2048
> [   18.169376] ... CLASSHASH_SIZE:           1024
> [   18.169444] ... MAX_LOCKDEP_ENTRIES:     8192
> [   18.169509] ... MAX_LOCKDEP_CHAINS:      16384
> [   18.169577] ... CHAINHASH_SIZE:          8192
> [   18.169643]  memory used by lock dependency info: 1648 kB
> [   18.169722]  per task-struct memory footprint: 2688 bytes
> [   18.169798] ------------------------
> [   18.169855] | Locking API testsuite:

Something is screwey here... Hmmm...

When I added the changeset in question, it fixed a problem in that
any backtrace of a kernel thread would loop forever at the end.
Any stack backtrace would hang or reach a safety limit (such as
the one imposed by lockdep).

Please double check that you are precisely reverting this patch
below _before_ doing these tests:

commit a051bc5bb1ac6dc138d529077fa20cbbc6622d95
Author: David S. Miller <davem@xxxxxxxxxxxxx>
Date:   Wed May 21 18:14:28 2008 -0700

    sparc64: Fix kernel thread stack termination.
    
    Because of the silly way I set up the initial stack for
    new kernel threads, there is a loop at the top of the
    stack.
    
    To fix this, properly add another stack frame that is copied
    from the parent and terminate it in the child by setting
    the frame pointer in that frame to zero.
    
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>

diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 0a0c05f..2084f81 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -657,20 +657,39 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 		struct task_struct *p, struct pt_regs *regs)
 {
 	struct thread_info *t = task_thread_info(p);
+	struct sparc_stackf *parent_sf;
+	unsigned long child_stack_sz;
 	char *child_trap_frame;
+	int kernel_thread;
 
-	/* Calculate offset to stack_frame & pt_regs */
-	child_trap_frame = task_stack_page(p) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ));
-	memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ));
+	kernel_thread = (regs->tstate & TSTATE_PRIV) ? 1 : 0;
+	parent_sf = ((struct sparc_stackf *) regs) - 1;
 
-	t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) |
+	/* Calculate offset to stack_frame & pt_regs */
+	child_stack_sz = ((STACKFRAME_SZ + TRACEREG_SZ) +
+			  (kernel_thread ? STACKFRAME_SZ : 0));
+	child_trap_frame = (task_stack_page(p) +
+			    (THREAD_SIZE - child_stack_sz));
+	memcpy(child_trap_frame, parent_sf, child_stack_sz);
+
+	t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) |
+				 (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) |
 		(((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT);
 	t->new_child = 1;
 	t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS;
-	t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct sparc_stackf));
+	t->kregs = (struct pt_regs *) (child_trap_frame +
+				       sizeof(struct sparc_stackf));
 	t->fpsaved[0] = 0;
 
-	if (regs->tstate & TSTATE_PRIV) {
+	if (kernel_thread) {
+		struct sparc_stackf *child_sf = (struct sparc_stackf *)
+			(child_trap_frame + (STACKFRAME_SZ + TRACEREG_SZ));
+
+		/* Zero terminate the stack backtrace.  */
+		child_sf->fp = NULL;
+		t->kregs->u_regs[UREG_FP] =
+		  ((unsigned long) child_sf) - STACK_BIAS;
+
 		/* Special case, if we are spawning a kernel thread from
 		 * a userspace task (via KMOD, NFS, or similar) we must
 		 * disable performance counters in the child because the
@@ -681,12 +700,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 			t->pcr_reg = 0;
 			t->flags &= ~_TIF_PERFCTR;
 		}
-		t->kregs->u_regs[UREG_FP] = t->ksp;
 		t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT);
-		flush_register_windows();
-		memcpy((void *)(t->ksp + STACK_BIAS),
-		       (void *)(regs->u_regs[UREG_FP] + STACK_BIAS),
-		       sizeof(struct sparc_stackf));
 		t->kregs->u_regs[UREG_G6] = (unsigned long) t;
 		t->kregs->u_regs[UREG_G4] = (unsigned long) t->task;
 	} else {
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Development]     [DCCP]     [Linux ARM Development]     [Linux]     [Photo]     [Yosemite Help]     [Linux ARM Kernel]     [Linux SCSI]     [Linux x86_64]     [Linux Hams]

  Powered by Linux