* [PATCH] SysRq-n changes RT tasks to normal
@ 2004-10-29 11:25 Måns Rullgård
2004-10-29 11:34 ` Ingo Molnar
0 siblings, 1 reply; 4+ messages in thread
From: Måns Rullgård @ 2004-10-29 11:25 UTC (permalink / raw)
To: linux-kernel
This makes SysRq-n change all RT tasks into normal tasks. Useful for
regaining control if an RT task is behaving badly.
Signed-off-by: Måns Rullgård <mru@inprovide.com>
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/10/09 12:44:26+02:00 mru@ford.(none)
# sysrq-n changes all RT tasks into normally scheduled tasks
# this is useful in case an RT task is misbehaving
#
# kernel/sched.c
# 2004/10/09 12:44:13+02:00 mru@ford.(none) +32 -0
# normalize_rt_tasks() converts all RT tasks into normal tasks
#
# include/linux/sched.h
# 2004/10/09 12:44:13+02:00 mru@ford.(none) +6 -0
# prototype for normalize_rt_tasks()
#
# drivers/char/sysrq.c
# 2004/10/09 12:44:13+02:00 mru@ford.(none) +11 -1
# sysrq-n calls normalize_rt_tasks()
#
diff -Nru a/drivers/char/sysrq.c b/drivers/char/sysrq.c
--- a/drivers/char/sysrq.c 2004-10-29 13:19:05 +02:00
+++ b/drivers/char/sysrq.c 2004-10-29 13:19:05 +02:00
@@ -216,6 +216,16 @@
/* 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;
@@ -250,7 +260,7 @@
#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 -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h 2004-10-29 13:19:05 +02:00
+++ b/include/linux/sched.h 2004-10-29 13:19:05 +02:00
@@ -1027,6 +1027,12 @@
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__ */
#endif
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c 2004-10-29 13:19:05 +02:00
+++ b/kernel/sched.c 2004-10-29 13:19:05 +02:00
@@ -4767,3 +4767,35 @@
}
EXPORT_SYMBOL(__might_sleep);
#endif
+
+#ifdef CONFIG_MAGIC_SYSRQ
+void normalize_rt_tasks(void)
+{
+ struct task_struct *p;
+ prio_array_t *array;
+ unsigned long flags;
+ runqueue_t *rq;
+
+ for_each_process (p) {
+ if (!rt_task(p))
+ continue;
+
+ read_lock_irq(&tasklist_lock);
+ 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 */
--
Måns Rullgård
mru@inprovide.com
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] SysRq-n changes RT tasks to normal
2004-10-29 11:25 [PATCH] SysRq-n changes RT tasks to normal Måns Rullgård
@ 2004-10-29 11:34 ` Ingo Molnar
2004-10-29 11:51 ` Måns Rullgård
0 siblings, 1 reply; 4+ messages in thread
From: Ingo Molnar @ 2004-10-29 11:34 UTC (permalink / raw)
To: Måns Rullgård; +Cc: linux-kernel
* Måns Rullgård <mru@inprovide.com> wrote:
> + for_each_process (p) {
> + if (!rt_task(p))
> + continue;
> +
> + read_lock_irq(&tasklist_lock);
> + rq = task_rq_lock(p, &flags);
you must take the tasklist_lock outside the for_each_process().
otherwise, looks good.
Ingo
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] SysRq-n changes RT tasks to normal
2004-10-29 11:34 ` Ingo Molnar
@ 2004-10-29 11:51 ` Måns Rullgård
2004-10-29 12:30 ` Ingo Molnar
0 siblings, 1 reply; 4+ messages in thread
From: Måns Rullgård @ 2004-10-29 11:51 UTC (permalink / raw)
To: Ingo Molnar; +Cc: linux-kernel
Ingo Molnar <mingo@elte.hu> writes:
> * Måns Rullgård <mru@inprovide.com> wrote:
>
>> + for_each_process (p) {
>> + if (!rt_task(p))
>> + continue;
>> +
>> + read_lock_irq(&tasklist_lock);
>> + rq = task_rq_lock(p, &flags);
>
> you must take the tasklist_lock outside the for_each_process().
The danger of cut and paste programming. New diff below.
diff -Nru a/drivers/char/sysrq.c b/drivers/char/sysrq.c
--- a/drivers/char/sysrq.c 2004-10-29 13:19:05 +02:00
+++ b/drivers/char/sysrq.c 2004-10-29 13:19:05 +02:00
@@ -216,6 +216,16 @@
/* 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;
@@ -250,7 +260,7 @@
#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 -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h 2004-10-29 13:19:05 +02:00
+++ b/include/linux/sched.h 2004-10-29 13:19:05 +02:00
@@ -1027,6 +1027,12 @@
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__ */
#endif
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c 2004-10-29 13:19:05 +02:00
+++ b/kernel/sched.c 2004-10-29 13:19:05 +02:00
@@ -4590,3 +4590,35 @@
}
EXPORT_SYMBOL(__might_sleep);
#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 */
--
Måns Rullgård
mru@inprovide.com
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] SysRq-n changes RT tasks to normal
2004-10-29 11:51 ` Måns Rullgård
@ 2004-10-29 12:30 ` Ingo Molnar
0 siblings, 0 replies; 4+ messages in thread
From: Ingo Molnar @ 2004-10-29 12:30 UTC (permalink / raw)
To: Måns Rullgård; +Cc: linux-kernel
* Måns Rullgård <mru@inprovide.com> wrote:
> > you must take the tasklist_lock outside the for_each_process().
>
> The danger of cut and paste programming. New diff below.
it's looking good now.
Ingo
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2004-10-29 12:29 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-29 11:25 [PATCH] SysRq-n changes RT tasks to normal Måns Rullgård
2004-10-29 11:34 ` Ingo Molnar
2004-10-29 11:51 ` Måns Rullgård
2004-10-29 12:30 ` Ingo Molnar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).