| From 0b4a953a0a014bee0bc3eaa5ae791f4b985f2c7a Mon Sep 17 00:00:00 2001 |
| From: Ivo Sieben <meltedpianoman@gmail.com> |
| Date: Mon, 3 Jun 2013 10:12:02 +0000 |
| Subject: [PATCH] genirq: Set irq thread to RT priority on creation |
| |
| When a threaded irq handler is installed the irq thread is initially |
| created on normal scheduling priority. Only after the irq thread is |
| woken up it sets its priority to RT_FIFO MAX_USER_RT_PRIO/2 itself. |
| |
| This means that interrupts that occur directly after the irq handler |
| is installed will be handled on a normal scheduling priority instead |
| of the realtime priority that one would expect. |
| |
| Fix this by setting the RT priority on creation of the irq_thread. |
| |
| Signed-off-by: Ivo Sieben <meltedpianoman@gmail.com> |
| Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| Cc: Steven Rostedt <rostedt@goodmis.org> |
| Link: http://lkml.kernel.org/r/1370254322-17240-1-git-send-email-meltedpianoman@gmail.com |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| kernel/irq/manage.c | 11 ++++++----- |
| 1 file changed, 6 insertions(+), 5 deletions(-) |
| |
| --- a/kernel/irq/manage.c |
| +++ b/kernel/irq/manage.c |
| @@ -839,9 +839,6 @@ static void irq_thread_dtor(struct callb |
| static int irq_thread(void *data) |
| { |
| struct callback_head on_exit_work; |
| - static const struct sched_param param = { |
| - .sched_priority = MAX_USER_RT_PRIO/2, |
| - }; |
| struct irqaction *action = data; |
| struct irq_desc *desc = irq_to_desc(action->irq); |
| irqreturn_t (*handler_fn)(struct irq_desc *desc, |
| @@ -853,8 +850,6 @@ static int irq_thread(void *data) |
| else |
| handler_fn = irq_thread_fn; |
| |
| - sched_setscheduler(current, SCHED_FIFO, ¶m); |
| - |
| init_task_work(&on_exit_work, irq_thread_dtor); |
| task_work_add(current, &on_exit_work, false); |
| |
| @@ -949,6 +944,9 @@ __setup_irq(unsigned int irq, struct irq |
| */ |
| if (new->thread_fn && !nested) { |
| struct task_struct *t; |
| + static const struct sched_param param = { |
| + .sched_priority = MAX_USER_RT_PRIO/2, |
| + }; |
| |
| t = kthread_create(irq_thread, new, "irq/%d-%s", irq, |
| new->name); |
| @@ -956,6 +954,9 @@ __setup_irq(unsigned int irq, struct irq |
| ret = PTR_ERR(t); |
| goto out_mput; |
| } |
| + |
| + sched_setscheduler(t, SCHED_FIFO, ¶m); |
| + |
| /* |
| * We keep the reference to the task struct even if |
| * the thread dies to avoid that the interrupt code |