2.5: preemptive kernel on UP
Subsystems (2)
PATCH 1/1 2.5: preemptive kernel on UP
During 2.5.5-pre, an optimization was made that removed schedule_tail from UP kernels. This causes the initial preempt_count of a new task, which starts at 1, to never decrement to zero and thus never become preemptible.
Thanks to everyone who pointed out the lousy performance - it took awhile to find but it should be fixed now. Please comment if not.
Patch is against 2.5.6-pre2 and is critical for all UP+preempt users.
Robert Love
arch/alpha/kernel/entry.S +1 -1
@@ -495,7 +495,7 @@ ret $31,($26),1 .end alpha_switch_to -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT .globl ret_from_fork .align 3 .ent ret_from_fork
arch/i386/kernel/entry.S +1 -1
@@ -195,7 +195,7 @@ ENTRY(ret_from_fork) -#if CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT call SYMBOL_NAME(schedule_tail) #endif GET_THREAD_INFO(%ebx)
arch/ppc/kernel/entry.S +1 -1
@@ -343,7 +343,7 @@ .globl ret_from_fork ret_from_fork: -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT bl schedule_tail #endif rlwinm r3,r1,0,0,18
arch/ppc64/kernel/entry.S +1 -1
@@ -311,7 +311,7 @@ blr _GLOBAL(ret_from_fork) -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT bl .schedule_tail #endif clrrdi r4,r1,THREAD_SHIFT
arch/s390/kernel/entry.S +2 -2
@@ -295,7 +295,7 @@ stosm 24(%r15),0x03 # reenable interrupts sr %r0,%r0 # child returns 0 st %r0,SP_R2(%r15) # store return value (change R2 on stack) -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT l %r1,BASED(.Lschedtail) la %r14,BASED(sysc_return) br %r1 # call schedule_tail, return to sysc_return
@@ -896,7 +896,7 @@ #error .Ltrace: .long syscall_trace .Lvfork: .long sys_vfork -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT .Lschedtail: .long schedule_tail #endif
arch/s390x/kernel/entry.S +1 -1
@@ -280,7 +280,7 @@ GET_CURRENT # load pointer to task_struct to R9 stosm 48(%r15),0x03 # reenable interrupts xc SP_R2(8,%r15),SP_R2(%r15) # child returns 0 -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT larl %r14,sysc_return jg schedule_tail # return to sysc_return #else
kernel/sched.c +1 -1
@@ -397,7 +397,7 @@ p->sleep_avg) / (EXIT_WEIGHT + 1); } -#if CONFIG_SMP +#if CONFIG_SMP ||CONFIG_PREEMPT asmlinkage void schedule_tail(void) {spin_unlock_irq (&this_rq ()->lock);
Quoted 16 lines · Robert Love
During 2.5.5-pre, an optimization was made that removed
schedule_tailfrom UP kernels. This causes the initialpreempt_countof a new task, which starts at 1, to never decrement to zero and thus never become preemptible.Thanks to everyone who pointed out the lousy performance - it took awhile to find but it should be fixed now. Please comment if not.
Patch is against 2.5.6-pre2 and is critical for all UP+preempt users.
Robert Love
diff -urN
linux-2.5.6-pre2/arch/alpha/kernel/entry.Slinux/arch/alpha/kernel/entry.S
arch/alpha/kernel/entry.S line 498
Quoted 5 lines
arch/alpha/kernel/entry.S +1
-1@@ -495,7 +495,7 @@ ret $31,($26),1 .end alpha_switch_to -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT
Surely you really don't mean this?
Signature · 2 lines
Russell King ([email protected]) The developer of ARM Linux http://www.arm.linux.org.uk/personal/aboutme.html
Quoted 11 lines · Russell King
arch/alpha/kernel/entry.S line 498
Quoted 9 lines
diff -urN
linux-2.5.6-pre2/arch/alpha/kernel/entry.Slinux/arch/alpha/kernel/entry.Sarch/alpha/kernel/entry.S +1
-1@@ -495,7 +495,7 @@ ret $31,($26),1 .end alpha_switch_to -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPTSurely you really don't mean this?
Yes, why? We need to call schedule_tail ...
Robert Love
Quoted 9 lines · Robert Love
Quoted 7 lines · Russell King
Quoted 7 lines
diff -urN
linux-2.5.6-pre2/arch/alpha/kernel/entry.Slinux/arch/alpha/kernel/entry.Sarch/alpha/kernel/entry.S +0
-0@@ -495,7 +495,7 @@ ret $31,($26),1 .end alpha_switch_to
Quoted 6 lines
Quoted 4 lines
arch/alpha/kernel/entry.S line 498
Quoted 2 lines
arch/alpha/kernel/entry.S +1
-1-#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPTSurely you really don't mean this?
Yes, why? We need to call
schedule_tail...
It's a #ifdef, not a #if
Does this compiler message give you a better idea:
warning: extra tokens at end of #ifdef directive
Signature · 2 lines
Russell King ([email protected]) The developer of ARM Linux http://www.arm.linux.org.uk/personal/aboutme.html
Quoted 1 line · Russell King
It's a #ifdef, not a #if
Better?
Robert Love
arch/alpha/kernel/entry.S +1 -1
@@ -495,7 +495,7 @@ ret $31,($26),1 .end alpha_switch_to -#ifdef CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT .globl ret_from_fork .align 3 .ent ret_from_fork
arch/i386/kernel/entry.S +1 -1
@@ -195,7 +195,7 @@ ENTRY(ret_from_fork) -#if CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT call SYMBOL_NAME(schedule_tail) #endif GET_THREAD_INFO(%ebx)
arch/ppc/kernel/entry.S +1 -1
@@ -343,7 +343,7 @@ .globl ret_from_fork ret_from_fork: -#ifdef CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT bl schedule_tail #endif rlwinm r3,r1,0,0,18
arch/ppc64/kernel/entry.S +1 -1
@@ -311,7 +311,7 @@ blr _GLOBAL(ret_from_fork) -#ifdef CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT bl .schedule_tail #endif clrrdi r4,r1,THREAD_SHIFT
arch/s390/kernel/entry.S +2 -2
@@ -295,7 +295,7 @@ stosm 24(%r15),0x03 # reenable interrupts sr %r0,%r0 # child returns 0 st %r0,SP_R2(%r15) # store return value (change R2 on stack) -#ifdef CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT l %r1,BASED(.Lschedtail) la %r14,BASED(sysc_return) br %r1 # call schedule_tail, return to sysc_return
@@ -896,7 +896,7 @@ #error .Ltrace: .long syscall_trace .Lvfork: .long sys_vfork -#ifdef CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT .Lschedtail: .long schedule_tail #endif
arch/s390x/kernel/entry.S +1 -1
@@ -280,7 +280,7 @@ GET_CURRENT # load pointer to task_struct to R9 stosm 48(%r15),0x03 # reenable interrupts xc SP_R2(8,%r15),SP_R2(%r15) # child returns 0 -#ifdef CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT larl %r14,sysc_return jg schedule_tail # return to sysc_return #else
kernel/sched.c +1 -1
@@ -397,7 +397,7 @@ p->sleep_avg) / (EXIT_WEIGHT + 1); } -#if CONFIG_SMP +#if CONFIG_SMP ||CONFIG_PREEMPT asmlinkage void schedule_tail(void) {spin_unlock_irq (&this_rq ()->lock);
Quoted 1 line
Better?
Not really
Quoted 1 line
+#if
CONFIG_SMP||CONFIG_PREEMPT
#if [expression]
try
#if defined(a) || defined(b)
Interesting that the difference pre-empt makes is so large you didnt notice you hadn't re-enabled it ;)
Alan
--
"Nothing would please me more than being able to hire ten programmers
and deluge the hobby market with good software." -- Bill Gates 1976
We are still waiting ....
Quoted 3 lines · Alan Cox
try
#if defined(a) || defined(b)
Is that needed since the .config is defined to 1 and 0 in autoconf.h?
Quoted 2 lines
Interesting that the difference pre-empt makes is so large you didnt notice you hadn't re-enabled it ;)
The above fix isn't needed for i386 ... and I noticed the problem in the first place because performance was odd.
Robert Love
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Robert,
Quoted 1 line · In one message you
Patch [...] is critical for all UP+preempt users.
and in another (in the same thread) you write:
Quoted 1 line
The above fix isn't needed for i386
I don't understand what to do in the UP i386 case - apply or not apply?
I suspect I'm misunderstanding what you mean by "the above fix".
Ben
- --
Ben Clifford [email protected] GPG: 30F06950
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iD8DBQE8hEw+sYXoezDwaVARAmByAJ4iW2lVfJO61hRoAYmwige/7fyY3ACfS7Lk ytnH2rCLgTvKgchWtt3cvVw=
=tb/c
-----END PGP SIGNATURE-----
Quoted 4 lines · Alan Cox
"Nothing would please me more than being able to hire ten programmers
and deluge the hobby market with good software." -- Bill Gates 1976We are still waiting ....
After Bill, the deluge.
Signature · 4 lines
--------------------------------------------------------- Victor Yodaiken Finite State Machine Labs: The RTLinux Company. www.fsmlabs.com www.rtlinux.com
Quoted 10 lines · Robert Love
During 2.5.5-pre, an optimization was made that removed
schedule_tailfrom UP kernels. This causes the initialpreempt_countof a new task, which starts at 1, to never decrement to zero and thus never become preemptible.Thanks to everyone who pointed out the lousy performance - it took awhile to find but it should be fixed now. Please comment if not.
Patch is against 2.5.6-pre2 and is critical for all UP+preempt users.
With out a lot of looking, wouldn't it be easier to just change fork?
-g
Quoted 102 lines
Robert Love
diff -urN
linux-2.5.6-pre2/arch/alpha/kernel/entry.Slinux/arch/alpha/kernel/entry.Sarch/alpha/kernel/entry.S Mon Mar 4 17:49:27 2002 renamed from arch/alpha/kernel/entry.S Fri Mar 1 17:21:14 2002 +1
-1@@ -495,7 +495,7 @@ ret $31,($26),1 .end alpha_switch_to -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT .globl ret_from_fork .align 3 .ent ret_from_forkdiff -urN
linux-2.5.6-pre2/arch/i386/kernel/entry.Slinux/arch/i386/kernel/entry.Sarch/i386/kernel/entry.S Mon Mar 4 17:48:32 2002 renamed from arch/i386/kernel/entry.S Tue Feb 19 21:10:58 2002 +1
-1@@ -195,7 +195,7 @@ ENTRY(ret_from_fork) -#if CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT call SYMBOL_NAME(schedule_tail) #endif GET_THREAD_INFO(%ebx)diff -urN
linux-2.5.6-pre2/arch/ppc/kernel/entry.Slinux/arch/ppc/kernel/entry.Sarch/ppc/kernel/entry.S Mon Mar 4 17:48:41 2002 renamed from arch/ppc/kernel/entry.S Tue Feb 19 21:10:59 2002 +1
-1@@ -343,7 +343,7 @@ .globl ret_from_fork ret_from_fork: -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT bl schedule_tail #endif rlwinm r3,r1,0,0,18diff -urN
linux-2.5.6-pre2/arch/ppc64/kernel/entry.Slinux/arch/ppc64/kernel/entry.Sarch/ppc64/kernel/entry.S Mon Mar 4 17:52:16 2002 renamed from arch/ppc64/kernel/entry.S Tue Feb 19 21:10:53 2002 +1
-1@@ -311,7 +311,7 @@ blr _GLOBAL(ret_from_fork) -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT bl .schedule_tail #endif clrrdi r4,r1,THREAD_SHIFTdiff -urN
linux-2.5.6-pre2/arch/s390/kernel/entry.Slinux/arch/s390/kernel/entry.Sarch/s390/kernel/entry.S Mon Mar 4 17:48:12 2002 renamed from arch/s390/kernel/entry.S Tue Feb 19 21:10:57 2002 +2
-2@@ -295,7 +295,7 @@ stosm 24(%r15),0x03 # reenable interrupts sr %r0,%r0 # child returns 0 st %r0,SP_R2(%r15) # store return value (change R2 on stack) -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT l %r1,BASED(.Lschedtail) la %r14,BASED(sysc_return) br %r1 # call schedule_tail, return to sysc_return@@ -896,7 +896,7 @@ #error .Ltrace: .long syscall_trace .Lvfork: .long sys_vfork -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT .Lschedtail: .long schedule_tail #endifdiff -urN
linux-2.5.6-pre2/arch/s390x/kernel/entry.Slinux/arch/s390x/kernel/entry.Sarch/s390x/kernel/entry.S Mon Mar 4 17:53:31 2002 renamed from arch/s390x/kernel/entry.S Tue Feb 19 21:10:58 2002 +1
-1@@ -280,7 +280,7 @@ GET_CURRENT # load pointer to task_struct to R9 stosm 48(%r15),0x03 # reenable interrupts xc SP_R2(8,%r15),SP_R2(%r15) # child returns 0 -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP || CONFIG_PREEMPT larl %r14,sysc_return jg schedule_tail # return to sysc_return #elsediff -urN
linux-2.5.6-pre2/kernel/sched.clinux/kernel/sched.ckernel/sched.c Mon Mar 4 17:54:00 2002 renamed from kernel/sched.c Fri Mar 1 17:21:16 2002 +1
-2@@ -397,7 +397,7 @@ p->sleep_avg) / (EXIT_WEIGHT + 1); } -#if CONFIG_SMP +#if CONFIG_SMP || CONFIG_PREEMPT asmlinkage void schedule_tail(void) { spin_unlock_irq(&this_rq()->lock); -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 3 lines
George [email protected] High-res-timers: http://sourceforge.net/projects/high-res-timers/ Real time sched: http://sourceforge.net/projects/rtsched/
Quoted 1 line · george anzinger
With out a lot of looking, wouldn't it be easier to just change fork?
Don't we need to unlock the rq regardless of what fork does?
Also, the alternative would be to set preempt_count to 0 if CONFIG_PREEMPT and 1 if CONFIG_PREEMPT && CONFIG_SMP. I figured Linus would balk at that sort #if/#else in do_fork. And, even then, is it safe to start the task with a preempt_count of 0?
Robert Love