Hello Darren, Juergen and Ingo,

> > All I need is one IRQ at priority 51, all other can still run at 50. And I
> > don't want to search at system's runtime for the right PID of driver's
> > thread to set its priority via "chrt". There is no user at this system, its
> > an embedded one.
>
> It seems reasonable then, for such a specialized case, to consider Remy's
> reply to my previous mail:
>
> "To suit my needs, I did this by just patching the kernel thread
> priorities at the places where they are started.

Attached I have put my patch to change the priorities of the
soft-irq's and the IRQ threads.
Maybe Juergen can use it so suit his needs. (Sorry for attaching
instead of inlining, but I have not find a way to inline a patch
without corrupting it while using Gmail from within Firefox)

But, I think that the mechanism to change the soft-irq priorities can
be integrated in the mainline RT-patch, I have modified the
softirq_info struct with the soft-irq thread names such that it also
contains the thread priority per soft-irq. For customisation it is
easier to adapt this struct, than to apply the entire patch over and
over. Until now the code seems to change that frequently that I have
to reimplement this patch over and over...

Maybe Ingo can look at it, and find a way to implement it more
generic? (In the softirq_info struct we could default set all prios
back to 50, and than from functional point of view there will be no
change for other RT-patch users, but makes Embedded-users life easier.

While looking at the IRQ-threads: Notice that setting all IRQ-threads
priorities to 50 with SCHED_FIFO is a bit strange to begin with,
because on a non-RT kernel all IRQ's have different priorities and a
higher prio irq can preempt a lower prio one. (on X86) The current
implementation will not preempt another irq-thread due to the same
prios and fifo scheduling.
The implementation I have in this patch follows the original behaviour
more closely, but changing that also could lead to some discussion...

Kind Regards,

Remy
This patch changes the soft-irq priority for all kernel daemon threads
like Interrupt threads and soft-irqs to match them with our
applications.

Signed-off-by: Remy Bohmer <[EMAIL PROTECTED]>
---
 kernel/irq/manage.c |   12 +++++++++--
 kernel/softirq.c    |   53 +++++++++++++++++++++++++++++++++-------------------
 2 files changed, 44 insertions(+), 21 deletions(-)

Index: linux-2.6.22/kernel/irq/manage.c
===================================================================
--- linux-2.6.22.orig/kernel/irq/manage.c	2007-07-24 16:40:15.000000000 +0200
+++ linux-2.6.22/kernel/irq/manage.c	2007-07-24 16:46:52.000000000 +0200
@@ -757,10 +757,13 @@ static void do_hardirq(struct irq_desc *
 		wake_up(&desc->wait_for_handler);
 }
 
+#define base_irq_prio  45
+
 static int do_irqd(void * __desc)
 {
 	struct sched_param param = { 0, };
 	struct irq_desc *desc = __desc;
+	int irq = desc - irq_desc;
 
 #ifdef CONFIG_SMP
 	cpumask_t cpus_allowed, mask;
@@ -776,12 +779,17 @@ static int do_irqd(void * __desc)
 	current->flags |= PF_NOFREEZE | PF_HARDIRQ;
 
 	/*
-	 * Set irq thread priority to SCHED_FIFO/50:
+	 * Use a custom irq thread priority mechanism:
 	 */
-	param.sched_priority = MAX_USER_RT_PRIO/2;
+	param.sched_priority = base_irq_prio - irq;
+	if (param.sched_priority < 1)
+		param.sched_priority = 1;
 
 	sys_sched_setscheduler(current->pid, SCHED_FIFO, &param);
 
+	printk(KERN_INFO "[IRQ-%d] started with prio:%i\n",
+		irq, param.sched_priority);
+
 	while (!kthread_should_stop()) {
 		local_irq_disable_nort();
 		do {
Index: linux-2.6.22/kernel/softirq.c
===================================================================
--- linux-2.6.22.orig/kernel/softirq.c	2007-07-24 16:40:15.000000000 +0200
+++ linux-2.6.22/kernel/softirq.c	2007-07-24 16:49:05.000000000 +0200
@@ -764,10 +764,30 @@ EXPORT_SYMBOL(tasklet_unlock_wait);
 
 #endif
 
+static struct
+{
+	const char *name;
+	const int   prio;
+} softirq_info [] =
+{
+  [HI_SOFTIRQ]      = {"high",    33},
+  [SCHED_SOFTIRQ]   = {"sched",   73},
+  [TIMER_SOFTIRQ]   = {"timer",   72},
+  [NET_TX_SOFTIRQ]  = {"net-tx",  20},
+  [NET_RX_SOFTIRQ]  = {"net-rx",  20},
+  [BLOCK_SOFTIRQ]   = {"block",   32},
+  [TASKLET_SOFTIRQ] = {"tasklet", 31},
+#ifdef CONFIG_HIGH_RES_TIMERS
+  [HRTIMER_SOFTIRQ] = {"hrtimer", 72},
+#endif
+  [RCU_SOFTIRQ]     = {"rcu",     20}
+};
+
 static int ksoftirqd(void * __data)
 {
-	struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO/2 };
 	struct softirqdata *data = __data;
+	struct sched_param param = {
+		.sched_priority = softirq_info[data->nr].prio };
 	u32 softirq_mask = (1 << data->nr);
 	struct softirq_action *h;
 	int cpu = data->cpu;
@@ -776,6 +796,16 @@ static int ksoftirqd(void * __data)
 	init_waitqueue_head(&data->wait);
 #endif
 
+	if ( (param.sched_priority < 1) ||
+		 (param.sched_priority > MAX_RT_PRIO) ) {
+		BUG();
+		param.sched_priority = 1;
+	}
+
+	printk(KERN_INFO "softirq-%s/%lu started up, pid:%d, RT prio: %d.\n",
+		softirq_info[data->nr].name, data->cpu,
+		current->pid, param.sched_priority);
+
 	sys_sched_setscheduler(current->pid, SCHED_FIFO, &param);
 	current->flags |= PF_NOFREEZE | PF_SOFTIRQ;
 
@@ -906,21 +936,6 @@ void takeover_tasklets(unsigned int cpu)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static const char *softirq_names [] =
-{
-  [HI_SOFTIRQ]		= "high",
-  [SCHED_SOFTIRQ]	= "sched",
-  [TIMER_SOFTIRQ]	= "timer",
-  [NET_TX_SOFTIRQ]	= "net-tx",
-  [NET_RX_SOFTIRQ]	= "net-rx",
-  [BLOCK_SOFTIRQ]	= "block",
-  [TASKLET_SOFTIRQ]	= "tasklet",
-#ifdef CONFIG_HIGH_RES_TIMERS
-  [HRTIMER_SOFTIRQ]	= "hrtimer",
-#endif
-  [RCU_SOFTIRQ]		= "rcu",
-};
-
 static int __cpuinit cpu_callback(struct notifier_block *nfb,
 				  unsigned long action,
 				  void *hcpu)
@@ -938,9 +953,9 @@ static int __cpuinit cpu_callback(struct
 		}
 		for (i = 0; i < MAX_SOFTIRQ; i++) {
 			p = kthread_create(ksoftirqd,
-					   &per_cpu(ksoftirqd, hotcpu)[i],
-					   "softirq-%s/%d", softirq_names[i],
-					   hotcpu);
+					&per_cpu(ksoftirqd, hotcpu)[i],
+					"softirq-%s/%d", softirq_info[i].name,
+					hotcpu);
 			if (IS_ERR(p)) {
 				printk("ksoftirqd %d for %i failed\n", i,
 				       hotcpu);

Reply via email to