Re: [PATCH] SysRq-n changes RT tasks to normal

From: Måns Rullgård
Date: Fri Oct 29 2004 - 06:56:49 EST


Ingo Molnar <mingo@xxxxxxx> writes:

> * Måns Rullgård <mru@xxxxxxxxxxxxx> 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@xxxxxxxxxxxxx
-
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/