Re: [PATCH] fix loop with disabled tasklets

Andrea Arcangeli
2001-11-12T14:21:18Z

On Mon, Nov 12, 2001 at 03:04:52PM +0100, Andrea Arcangeli wrote:
> On Mon, Nov 12, 2001 at 12:03:05AM -0800, David S. Miller wrote:
> > From: Andrea Arcangeli <andrea@suse.de>
> > Date: Mon, 12 Nov 2001 02:11:42 +0100
> >
> > I'm just guessing: the scheduler isn't yet functional when
> > spawn_ksoftirqd is called.
> >
> > The scheduler is fully functional, this isn't what is going wrong.
>
> check ret_from_fork path, sparc32 scheduler is broken and this is why it
> deadlocks at boot, it has nothing to do with the softirq code, softirq
> code is innocent and it only get bitten by the sparc32 bug.

real fix looks like this (no idea what PSR_PIL means so not sure if this
really works on UP but certainly the sched_yield breakage is fixed now
and it won't deadlock in the softirq code any longer):

--- 2.4.15pre2aa1/arch/sparc/kernel/entry.S.~1~ Sat Feb 10 02:34:05 2001
+++ 2.4.15pre2aa1/arch/sparc/kernel/entry.S Mon Nov 12 15:17:32 2001
@@ -1466,8 +1466,7 @@
b C_LABEL(ret_sys_call)
ld [%sp + REGWIN_SZ + PT_I0], %o0

-#ifdef CONFIG_SMP
- .globl C_LABEL(ret_from_smpfork)
+ .globl C_LABEL(ret_from_fork)
C_LABEL(ret_from_smpfork):
wr %l0, PSR_ET, %psr
WRITE_PAUSE
@@ -1475,7 +1474,6 @@
mov %g3, %o0
b C_LABEL(ret_sys_call)
ld [%sp + REGWIN_SZ + PT_I0], %o0
-#endif

/* Linux native and SunOS system calls enter here... */
.align 4
--- 2.4.15pre2aa1/arch/sparc/kernel/process.c.~1~ Thu Oct 11 10:41:52 2001
+++ 2.4.15pre2aa1/arch/sparc/kernel/process.c Mon Nov 12 15:18:21 2001
@@ -455,11 +455,7 @@
* allocate the task_struct and kernel stack in
* do_fork().
*/
-#ifdef CONFIG_SMP
-extern void ret_from_smpfork(void);
-#else
-extern void ret_from_syscall(void);
-#endif
+extern void ret_from_smp(void);

int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
unsigned long unused,
@@ -493,13 +489,8 @@
copy_regwin(new_stack, (((struct reg_window *) regs) - 1));

p->thread.ksp = (unsigned long) new_stack;
-#ifdef CONFIG_SMP
p->thread.kpc = (((unsigned long) ret_from_smpfork) - 0x8);
p->thread.kpsr = current->thread.fork_kpsr | PSR_PIL;
-#else
- p->thread.kpc = (((unsigned long) ret_from_syscall) - 0x8);
- p->thread.kpsr = current->thread.fork_kpsr;
-#endif
p->thread.kwim = current->thread.fork_kwim;

/* This is used for sun4c only */

Andrea