* [RFC][PATCH] genirq: support multiple interrupt priorities
@ 2007-08-06 10:30 Paul Mundt
2007-08-06 10:36 ` Ingo Molnar
0 siblings, 1 reply; 3+ messages in thread
From: Paul Mundt @ 2007-08-06 10:30 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner; +Cc: linux-kernel
This is a simple patch for adding trivial interrupt priority support.
I've added a ->set_prio() to the irq_chip which is implemented
effectively the same way as ->set_type(), it's an optional component for
those that really care about it.
This follows the rationale that PICs that do support multiple priorities
are going to support a fairly wide range, which is not something that can
easily be represented generically. Given that, the only IRQF_PRIO_* flags
that are introduced are for generic priorities that we assume all
priority-capable PICs can support -- namely, high, low, and default (or
none). In addition to this there is also a set_irq_prio() modelled after
set_irq_type() which platform-specific code can set to more specific
values that aren't suitable for generic abstraction.
My primary use case for this is for making sure we have high priorities
where we want them in the platform code, especially chained handlers,
timers, things of that nature. Going the genirq route is certainly much
cleaner than trying to hack up my own arch-specific API for this. I
imagine other people will have similar use cases for this.
Comments? Flames?
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
--
include/linux/interrupt.h | 5 +++++
include/linux/irq.h | 3 +++
kernel/irq/chip.c | 26 ++++++++++++++++++++++++++
kernel/irq/manage.c | 16 ++++++++++++++++
4 files changed, 50 insertions(+)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 5523f19..503754e 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -45,6 +45,8 @@
* IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
* registered first in an shared interrupt is considered for
* performance reasons)
+ * IRQF_PRIO_HIGH - Give IRQ a high priority
+ * IRQF_PRIO_LOW - Give IRQ a low priority
*/
#define IRQF_DISABLED 0x00000020
#define IRQF_SAMPLE_RANDOM 0x00000040
@@ -54,6 +56,9 @@
#define IRQF_PERCPU 0x00000400
#define IRQF_NOBALANCING 0x00000800
#define IRQF_IRQPOLL 0x00001000
+#define IRQF_PRIO_HIGH 0x00002000
+#define IRQF_PRIO_LOW 0x00004000
+#define IRQF_PRIO_MASK (IRQF_PRIO_HIGH | IRQF_PRIO_LOW)
/*
* Migration helpers. Scheduled for removal in 9/2007
diff --git a/include/linux/irq.h b/include/linux/irq.h
index efc8853..88cfd33 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -91,6 +96,7 @@ struct msi_desc;
* @retrigger: resend an IRQ to the CPU
* @set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
* @set_wake: enable/disable power-management wake-on of an IRQ
+ * @set_prio: set the priority of an IRQ
*
* @release: release function solely used by UML
* @typename: obsoleted by name, kept as migration helper
@@ -113,6 +119,7 @@ struct irq_chip {
int (*retrigger)(unsigned int irq);
int (*set_type)(unsigned int irq, unsigned int flow_type);
int (*set_wake)(unsigned int irq, unsigned int on);
+ int (*set_prio)(unsigned int irq, unsigned int prio);
/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
@@ -381,6 +388,7 @@ extern int set_irq_data(unsigned int irq, void *data);
extern int set_irq_chip_data(unsigned int irq, void *data);
extern int set_irq_type(unsigned int irq, unsigned int type);
extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
+extern int set_irq_prio(unsigned int irq, unsigned int prio);
#define get_irq_chip(irq) (irq_desc[irq].chip)
#define get_irq_chip_data(irq) (irq_desc[irq].chip_data)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 615ce97..fa7df4d 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -141,6 +141,32 @@ int set_irq_type(unsigned int irq, unsigned int type)
EXPORT_SYMBOL(set_irq_type);
/**
+ * set_irq_prio - set the irq priority for an irq
+ * @irq: irq number
+ * @prio: interrupt priority - see include/linux/interrupt.h
+ */
+int set_irq_prio(unsigned int irq, unsigned int prio)
+{
+ struct irq_desc *desc;
+ unsigned long flags;
+ int ret = -ENXIO;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to set irq priority for IRQ%d\n", irq);
+ return -ENODEV;
+ }
+
+ desc = irq_desc + irq;
+ if (desc->chip->set_prio) {
+ spin_lock_irqsave(&desc->lock, flags);
+ ret = desc->chip->set_prio(irq, prio);
+ spin_unlock_irqrestore(&desc->lock, flags);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(set_irq_prio);
+
+/**
* set_irq_data - set irq type data for an irq
* @irq: Interrupt number
* @data: Pointer to interrupt specific data
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 203a518..f51f8d2 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -347,6 +353,22 @@ int setup_irq(unsigned int irq, struct irqaction *new)
} else
compat_irq_chip_set_default_handler(desc);
+ /* Setup the priority if configured: */
+ if (new->flags & IRQF_PRIO_MASK) {
+ if (desc->chip && desc->chip->set_prio)
+ desc->chip->set_prio(irq,
+ new->flags & IRQF_PRIO_MASK);
+ else
+ /*
+ * IRQF_PRIO_* but the PIC does not support
+ * multiple priorities?
+ */
+ printk(KERN_WARNING "No IRQF_PRIO set_prio "
+ "function for IRQ %d (%s)\n", irq,
+ desc->chip ? desc->chip->name :
+ "unknown");
+ }
+
desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
IRQ_INPROGRESS);
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [RFC][PATCH] genirq: support multiple interrupt priorities
2007-08-06 10:30 [RFC][PATCH] genirq: support multiple interrupt priorities Paul Mundt
@ 2007-08-06 10:36 ` Ingo Molnar
2007-08-06 10:46 ` Paul Mundt
0 siblings, 1 reply; 3+ messages in thread
From: Ingo Molnar @ 2007-08-06 10:36 UTC (permalink / raw)
To: Paul Mundt, Thomas Gleixner, linux-kernel
* Paul Mundt <lethal@linux-sh.org> wrote:
> This is a simple patch for adding trivial interrupt priority support.
>
> I've added a ->set_prio() to the irq_chip which is implemented
> effectively the same way as ->set_type(), it's an optional component
> for those that really care about it.
i have no fundamental objections but it would be nice to actually
prototype this by implementing real priority support in the hardware:
both the i8259A and the IO-APIC/local-apic has such IRQ prioritization
features.
> + * IRQF_PRIO_HIGH - Give IRQ a high priority
> + * IRQF_PRIO_LOW - Give IRQ a low priority
this should be a numeric scale. (Preferably in the 1-99 range (the
hardware can then do a lower-resolution thing out of it), so that we can
directly map this to IRQ threads and SCHED_FIFO priorities in -rt.)
Ingo
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFC][PATCH] genirq: support multiple interrupt priorities
2007-08-06 10:36 ` Ingo Molnar
@ 2007-08-06 10:46 ` Paul Mundt
0 siblings, 0 replies; 3+ messages in thread
From: Paul Mundt @ 2007-08-06 10:46 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Thomas Gleixner, linux-kernel
On Mon, Aug 06, 2007 at 12:36:09PM +0200, Ingo Molnar wrote:
> * Paul Mundt <lethal@linux-sh.org> wrote:
> > This is a simple patch for adding trivial interrupt priority support.
> >
> > I've added a ->set_prio() to the irq_chip which is implemented
> > effectively the same way as ->set_type(), it's an optional component
> > for those that really care about it.
>
> i have no fundamental objections but it would be nice to actually
> prototype this by implementing real priority support in the hardware:
> both the i8259A and the IO-APIC/local-apic has such IRQ prioritization
> features.
>
I would not have written the patch if I did not have hardware that
supported it. I suppose I can start with interfacing the x86 PICs if that
makes it easier to swallow, though ;-)
> > + * IRQF_PRIO_HIGH - Give IRQ a high priority
> > + * IRQF_PRIO_LOW - Give IRQ a low priority
>
> this should be a numeric scale. (Preferably in the 1-99 range (the
> hardware can then do a lower-resolution thing out of it), so that we can
> directly map this to IRQ threads and SCHED_FIFO priorities in -rt.)
>
I don't disagree with that, but that makes it a little hard to pass in a
priority at request_irq() time. These IRQF_PRIO_HIGH/LOW are only for
such usage, the intent is to have a numeric value that's more meaningful
to the underlying hardware passed on to set_irq_prio() otherwise.
In any event, there's no problem with doing that anyways, both
IRQF_PRIO_HIGH and IRQF_PRIO_LOW are substantially above the 1-99 range
that the mask can be tested for if the underlying controller isn't
interested in mapping the 1-99 range to its own view of priorities.
Presumably you want this numeric range also reflected in the irq_desc for
-rt? If so, I'll start hacking something up.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-08-06 10:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-06 10:30 [RFC][PATCH] genirq: support multiple interrupt priorities Paul Mundt
2007-08-06 10:36 ` Ingo Molnar
2007-08-06 10:46 ` Paul Mundt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox