From: Måns Rullgård Teach sysrq-N to switch all rt-policy tasks to SCHED_OTHER. For recovering from (and diagnosing) userspace bugs. Acked-by: Ingo Molnar Signed-off-by: Andrew Morton --- 25-akpm/drivers/char/sysrq.c | 12 +++++++++++- 25-akpm/include/linux/sched.h | 6 ++++++ 25-akpm/kernel/sched.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff -puN drivers/char/sysrq.c~sysrq-n-changes-rt-tasks-to-normal drivers/char/sysrq.c --- 25/drivers/char/sysrq.c~sysrq-n-changes-rt-tasks-to-normal Mon Nov 1 14:40:17 2004 +++ 25-akpm/drivers/char/sysrq.c Mon Nov 1 14:40:17 2004 @@ -247,6 +247,16 @@ static struct sysrq_key_op sysrq_kill_op /* END SIGNAL SYSRQ HANDLERS BLOCK */ +static void sysrq_handle_unrt(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + normalize_rt_tasks(); +} +static struct sysrq_key_op sysrq_unrt_op = { + .handler = sysrq_handle_unrt, + .help_msg = "Nice", + .action_msg = "Nice All RT Tasks" +}; /* Key Operations table and lock */ static spinlock_t sysrq_key_table_lock = SPIN_LOCK_UNLOCKED; @@ -281,7 +291,7 @@ static struct sysrq_key_op *sysrq_key_ta #endif /* l */ NULL, /* m */ &sysrq_showmem_op, -/* n */ NULL, +/* n */ &sysrq_unrt_op, /* o */ NULL, /* This will often be registered as 'Off' at init time */ /* p */ &sysrq_showregs_op, diff -puN include/linux/sched.h~sysrq-n-changes-rt-tasks-to-normal include/linux/sched.h --- 25/include/linux/sched.h~sysrq-n-changes-rt-tasks-to-normal Mon Nov 1 14:40:17 2004 +++ 25-akpm/include/linux/sched.h Mon Nov 1 14:40:17 2004 @@ -1125,6 +1125,12 @@ static inline void arch_pick_mmap_layout extern long sched_setaffinity(pid_t pid, cpumask_t new_mask); extern long sched_getaffinity(pid_t pid, cpumask_t *mask); +#ifdef CONFIG_MAGIC_SYSRQ + +extern void normalize_rt_tasks(void); + +#endif + #endif /* __KERNEL__ */ extern void init_sched_domain_sysctl(void); diff -puN kernel/sched.c~sysrq-n-changes-rt-tasks-to-normal kernel/sched.c --- 25/kernel/sched.c~sysrq-n-changes-rt-tasks-to-normal Mon Nov 1 14:40:17 2004 +++ 25-akpm/kernel/sched.c Mon Nov 1 14:40:17 2004 @@ -4868,3 +4868,35 @@ void destroy_sched_domain_sysctl() { } #endif + +#ifdef CONFIG_MAGIC_SYSRQ +void normalize_rt_tasks(void) +{ + struct task_struct *p; + prio_array_t *array; + unsigned long flags; + runqueue_t *rq; + + read_lock_irq(&tasklist_lock); + for_each_process (p) { + if (!rt_task(p)) + continue; + + rq = task_rq_lock(p, &flags); + + array = p->array; + if (array) + deactivate_task(p, task_rq(p)); + __setscheduler(p, SCHED_NORMAL, 0); + if (array) { + __activate_task(p, task_rq(p)); + resched_task(rq->curr); + } + + task_rq_unlock(rq, &flags); + } + read_unlock_irq(&tasklist_lock); +} + +EXPORT_SYMBOL(normalize_rt_tasks); +#endif /* CONFIG_MAGIC_SYSRQ */ _