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>
This commit is contained in:
		
					parent
					
						
							
								9dbd90f17e
							
						
					
				
			
			
				commit
				
					
						ee23871389
					
				
			
		
					 1 changed files with 6 additions and 5 deletions
				
			
		|  | @ -840,9 +840,6 @@ static void irq_thread_dtor(struct callback_head *unused) | ||||||
| static int irq_thread(void *data) | static int irq_thread(void *data) | ||||||
| { | { | ||||||
| 	struct callback_head on_exit_work; | 	struct callback_head on_exit_work; | ||||||
| 	static const struct sched_param param = { |  | ||||||
| 		.sched_priority = MAX_USER_RT_PRIO/2, |  | ||||||
| 	}; |  | ||||||
| 	struct irqaction *action = data; | 	struct irqaction *action = data; | ||||||
| 	struct irq_desc *desc = irq_to_desc(action->irq); | 	struct irq_desc *desc = irq_to_desc(action->irq); | ||||||
| 	irqreturn_t (*handler_fn)(struct irq_desc *desc, | 	irqreturn_t (*handler_fn)(struct irq_desc *desc, | ||||||
|  | @ -854,8 +851,6 @@ static int irq_thread(void *data) | ||||||
| 	else | 	else | ||||||
| 		handler_fn = irq_thread_fn; | 		handler_fn = irq_thread_fn; | ||||||
| 
 | 
 | ||||||
| 	sched_setscheduler(current, SCHED_FIFO, ¶m); |  | ||||||
| 
 |  | ||||||
| 	init_task_work(&on_exit_work, irq_thread_dtor); | 	init_task_work(&on_exit_work, irq_thread_dtor); | ||||||
| 	task_work_add(current, &on_exit_work, false); | 	task_work_add(current, &on_exit_work, false); | ||||||
| 
 | 
 | ||||||
|  | @ -950,6 +945,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | ||||||
| 	 */ | 	 */ | ||||||
| 	if (new->thread_fn && !nested) { | 	if (new->thread_fn && !nested) { | ||||||
| 		struct task_struct *t; | 		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, | 		t = kthread_create(irq_thread, new, "irq/%d-%s", irq, | ||||||
| 				   new->name); | 				   new->name); | ||||||
|  | @ -957,6 +955,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | ||||||
| 			ret = PTR_ERR(t); | 			ret = PTR_ERR(t); | ||||||
| 			goto out_mput; | 			goto out_mput; | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		sched_setscheduler(t, SCHED_FIFO, ¶m); | ||||||
|  | 
 | ||||||
| 		/*
 | 		/*
 | ||||||
| 		 * We keep the reference to the task struct even if | 		 * We keep the reference to the task struct even if | ||||||
| 		 * the thread dies to avoid that the interrupt code | 		 * the thread dies to avoid that the interrupt code | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ivo Sieben
				Ivo Sieben