[patch, 2.6.9-rc4-mm1] fix oops in sched_setscheduler
From: Ingo Molnar
Date: Fri Oct 15 2004 - 04:03:20 EST
* Mateusz.Blaszczyk@xxxxxxx <Mateusz.Blaszczyk@xxxxxxx> wrote:
> Running cdrecord caused oops in sched_setscheduler syscall (i think)
> so i tested with my little setp.c program that follows. It seems that
> it always oops - no matter what policy I request. It runs ok on
> 2.6.9-rc2-mm1, same config. Rc3 not tested. I run setp. 3 times. The
> first I decoded using ksymoops. My .config follows at the end.
the crash happens if 1) someone doesnt have profiling enabled 2) uses an
UP kernel and 3) does setscheduler. The patch below fixes 3 problems:
finishes and fixes the consolidation and fixes the profile=schedule
feature. Against 2.6.9-rc4-mm1. Tested.
also it seems that some serious mismerge happened of the
profile=schedule feature. Wli or akpm merge damage?
in the next mail i will send a patch against 2.6.9-rc4 too (which
luckily doesnt have the crash bug, but has the feature mismerge).
Ingo
Signed-off-by: Ingo Molnar <mingo@xxxxxxx>
--- linux/kernel/sched.c.orig
+++ linux/kernel/sched.c
@@ -2744,6 +2744,7 @@ asmlinkage void __sched schedule(void)
dump_stack();
}
}
+ profile_hit(SCHED_PROFILING, __builtin_return_address(0));
need_resched:
preempt_disable();
@@ -3342,7 +3343,6 @@ static int setscheduler(pid_t pid, int p
policy != SCHED_NORMAL)
goto out_unlock;
}
- profile_hit(SCHED_PROFILING, __builtin_return_address(0));
/*
* Valid priorities for SCHED_FIFO and SCHED_RR are
--- linux/kernel/profile.c.orig
+++ linux/kernel/profile.c
@@ -49,14 +49,14 @@ static int __init profile_setup(char * s
int par;
if (!strncmp(str, "schedule", 8)) {
- prof_on = 2;
+ prof_on = SCHED_PROFILING;
printk(KERN_INFO "kernel schedule profiling enabled\n");
if (str[7] == ',')
str += 8;
}
if (get_option(&str,&par)) {
prof_shift = par;
- prof_on = 1;
+ prof_on = CPU_PROFILING;
printk(KERN_INFO "kernel profiling enabled (shift: %ld)\n",
prof_shift);
}
@@ -385,6 +385,8 @@ inline void profile_hit(int type, void *
{
unsigned long pc;
+ if (prof_on != type || !prof_buffer)
+ return;
pc = ((unsigned long)__pc - (unsigned long)_stext) >> prof_shift;
atomic_inc(&prof_buffer[min(pc, prof_len - 1)]);
}
@@ -394,8 +396,6 @@ void profile_tick(int type, struct pt_re
{
if (type == CPU_PROFILING)
profile_hook(regs);
- if (prof_on != type || !prof_buffer)
- return;
if (!user_mode(regs) && cpu_isset(smp_processor_id(), prof_cpu_mask))
profile_hit(type, (void *)profile_pc(regs));
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/