* [PATCH] x86/IO-APIC: streamline level ack/end handling
@ 2012-09-19 7:36 Jan Beulich
2012-09-19 7:57 ` Keir Fraser
0 siblings, 1 reply; 2+ messages in thread
From: Jan Beulich @ 2012-09-19 7:36 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: Type: text/plain, Size: 4708 bytes --]
Rather than evaluating "ioapic_ack_new" on each invocation, and
considering that the two methods really have almost no code in common,
split the handlers.
While at it, also move ioapic_ack_{new,forced} into .init.data
(eliminating the single non-__init reference to the former).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -43,8 +43,8 @@ static struct { int pin, apic; } ioapic_
static DEFINE_SPINLOCK(ioapic_lock);
bool_t __read_mostly skip_ioapic_setup;
-bool_t __read_mostly ioapic_ack_new = 1;
-bool_t __read_mostly ioapic_ack_forced = 0;
+bool_t __initdata ioapic_ack_new = 1;
+bool_t __initdata ioapic_ack_forced = 0;
/*
* # of IRQ routing registers
@@ -918,7 +918,7 @@ static inline int IO_APIC_irq_trigger(in
return 0;
}
-static hw_irq_controller ioapic_level_type;
+static struct hw_interrupt_type ioapic_level_type;
static hw_irq_controller ioapic_edge_type;
#define IOAPIC_AUTO -1
@@ -1605,9 +1605,6 @@ static void mask_and_ack_level_ioapic_ir
irq_complete_move(desc);
- if ( ioapic_ack_new )
- return;
-
if ( !directed_eoi_enabled )
mask_IO_APIC_irq(desc);
@@ -1651,34 +1648,29 @@ static void mask_and_ack_level_ioapic_ir
}
}
-static void end_level_ioapic_irq(struct irq_desc *desc, u8 vector)
+static void end_level_ioapic_irq_old(struct irq_desc *desc, u8 vector)
{
- unsigned long v;
- int i;
-
- if ( !ioapic_ack_new )
+ if ( directed_eoi_enabled )
{
- if ( directed_eoi_enabled )
+ if ( !(desc->status & (IRQ_DISABLED|IRQ_MOVE_PENDING)) )
{
- if ( !(desc->status & (IRQ_DISABLED|IRQ_MOVE_PENDING)) )
- {
- eoi_IO_APIC_irq(desc);
- return;
- }
-
- mask_IO_APIC_irq(desc);
eoi_IO_APIC_irq(desc);
- if ( (desc->status & IRQ_MOVE_PENDING) &&
- !io_apic_level_ack_pending(desc->irq) )
- move_masked_irq(desc);
+ return;
}
- if ( !(desc->status & IRQ_DISABLED) )
- unmask_IO_APIC_irq(desc);
-
- return;
+ mask_IO_APIC_irq(desc);
+ eoi_IO_APIC_irq(desc);
+ if ( (desc->status & IRQ_MOVE_PENDING) &&
+ !io_apic_level_ack_pending(desc->irq) )
+ move_masked_irq(desc);
}
+ if ( !(desc->status & IRQ_DISABLED) )
+ unmask_IO_APIC_irq(desc);
+}
+
+static void end_level_ioapic_irq_new(struct irq_desc *desc, u8 vector)
+{
/*
* It appears there is an erratum which affects at least version 0x11
* of I/O APIC (that's the 82093AA and cores integrated into various
@@ -1698,7 +1690,7 @@ static void end_level_ioapic_irq(struct
* operation to prevent an edge-triggered interrupt escaping meanwhile.
* The idea is from Manfred Spraul. --macro
*/
- i = desc->arch.vector;
+ unsigned int v, i = desc->arch.vector;
/* Manually EOI the old vector if we are moving to the new */
if ( vector && i != vector )
@@ -1741,14 +1733,14 @@ static hw_irq_controller ioapic_edge_typ
.set_affinity = set_ioapic_affinity_irq,
};
-static hw_irq_controller ioapic_level_type = {
+static struct hw_interrupt_type __read_mostly ioapic_level_type = {
.typename = "IO-APIC-level",
.startup = startup_level_ioapic_irq,
.shutdown = mask_IO_APIC_irq,
.enable = unmask_IO_APIC_irq,
.disable = mask_IO_APIC_irq,
.ack = mask_and_ack_level_ioapic_irq,
- .end = end_level_ioapic_irq,
+ .end = end_level_ioapic_irq_old,
.set_affinity = set_ioapic_affinity_irq,
};
@@ -2006,6 +1998,11 @@ void __init setup_IO_APIC(void)
printk("ENABLING IO-APIC IRQs\n");
printk(" -> Using %s ACK method\n", ioapic_ack_new ? "new" : "old");
+ if (ioapic_ack_new) {
+ ioapic_level_type.ack = irq_complete_move;
+ ioapic_level_type.end = end_level_ioapic_irq_new;
+ }
+
/*
* Set up IO-APIC IRQ routing.
*/
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1495,7 +1495,8 @@ static int pirq_acktype(struct domain *d
* on which they were received. This is because we tickle the LAPIC to EOI.
*/
if ( !strcmp(desc->handler->typename, "IO-APIC-level") )
- return ioapic_ack_new ? ACKTYPE_EOI : ACKTYPE_UNMASK;
+ return desc->handler->ack == irq_complete_move ?
+ ACKTYPE_EOI : ACKTYPE_UNMASK;
/* Legacy PIC interrupts can be acknowledged from any CPU. */
if ( !strcmp(desc->handler->typename, "XT-PIC") )
[-- Attachment #2: x86-ioapic-streamline-level.patch --]
[-- Type: text/plain, Size: 4754 bytes --]
x86/IO-APIC: streamline level ack/end handling
Rather than evaluating "ioapic_ack_new" on each invocation, and
considering that the two methods really have almost no code in common,
split the handlers.
While at it, also move ioapic_ack_{new,forced} into .init.data
(eliminating the single non-__init reference to the former).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -43,8 +43,8 @@ static struct { int pin, apic; } ioapic_
static DEFINE_SPINLOCK(ioapic_lock);
bool_t __read_mostly skip_ioapic_setup;
-bool_t __read_mostly ioapic_ack_new = 1;
-bool_t __read_mostly ioapic_ack_forced = 0;
+bool_t __initdata ioapic_ack_new = 1;
+bool_t __initdata ioapic_ack_forced = 0;
/*
* # of IRQ routing registers
@@ -918,7 +918,7 @@ static inline int IO_APIC_irq_trigger(in
return 0;
}
-static hw_irq_controller ioapic_level_type;
+static struct hw_interrupt_type ioapic_level_type;
static hw_irq_controller ioapic_edge_type;
#define IOAPIC_AUTO -1
@@ -1605,9 +1605,6 @@ static void mask_and_ack_level_ioapic_ir
irq_complete_move(desc);
- if ( ioapic_ack_new )
- return;
-
if ( !directed_eoi_enabled )
mask_IO_APIC_irq(desc);
@@ -1651,34 +1648,29 @@ static void mask_and_ack_level_ioapic_ir
}
}
-static void end_level_ioapic_irq(struct irq_desc *desc, u8 vector)
+static void end_level_ioapic_irq_old(struct irq_desc *desc, u8 vector)
{
- unsigned long v;
- int i;
-
- if ( !ioapic_ack_new )
+ if ( directed_eoi_enabled )
{
- if ( directed_eoi_enabled )
+ if ( !(desc->status & (IRQ_DISABLED|IRQ_MOVE_PENDING)) )
{
- if ( !(desc->status & (IRQ_DISABLED|IRQ_MOVE_PENDING)) )
- {
- eoi_IO_APIC_irq(desc);
- return;
- }
-
- mask_IO_APIC_irq(desc);
eoi_IO_APIC_irq(desc);
- if ( (desc->status & IRQ_MOVE_PENDING) &&
- !io_apic_level_ack_pending(desc->irq) )
- move_masked_irq(desc);
+ return;
}
- if ( !(desc->status & IRQ_DISABLED) )
- unmask_IO_APIC_irq(desc);
-
- return;
+ mask_IO_APIC_irq(desc);
+ eoi_IO_APIC_irq(desc);
+ if ( (desc->status & IRQ_MOVE_PENDING) &&
+ !io_apic_level_ack_pending(desc->irq) )
+ move_masked_irq(desc);
}
+ if ( !(desc->status & IRQ_DISABLED) )
+ unmask_IO_APIC_irq(desc);
+}
+
+static void end_level_ioapic_irq_new(struct irq_desc *desc, u8 vector)
+{
/*
* It appears there is an erratum which affects at least version 0x11
* of I/O APIC (that's the 82093AA and cores integrated into various
@@ -1698,7 +1690,7 @@ static void end_level_ioapic_irq(struct
* operation to prevent an edge-triggered interrupt escaping meanwhile.
* The idea is from Manfred Spraul. --macro
*/
- i = desc->arch.vector;
+ unsigned int v, i = desc->arch.vector;
/* Manually EOI the old vector if we are moving to the new */
if ( vector && i != vector )
@@ -1741,14 +1733,14 @@ static hw_irq_controller ioapic_edge_typ
.set_affinity = set_ioapic_affinity_irq,
};
-static hw_irq_controller ioapic_level_type = {
+static struct hw_interrupt_type __read_mostly ioapic_level_type = {
.typename = "IO-APIC-level",
.startup = startup_level_ioapic_irq,
.shutdown = mask_IO_APIC_irq,
.enable = unmask_IO_APIC_irq,
.disable = mask_IO_APIC_irq,
.ack = mask_and_ack_level_ioapic_irq,
- .end = end_level_ioapic_irq,
+ .end = end_level_ioapic_irq_old,
.set_affinity = set_ioapic_affinity_irq,
};
@@ -2006,6 +1998,11 @@ void __init setup_IO_APIC(void)
printk("ENABLING IO-APIC IRQs\n");
printk(" -> Using %s ACK method\n", ioapic_ack_new ? "new" : "old");
+ if (ioapic_ack_new) {
+ ioapic_level_type.ack = irq_complete_move;
+ ioapic_level_type.end = end_level_ioapic_irq_new;
+ }
+
/*
* Set up IO-APIC IRQ routing.
*/
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1495,7 +1495,8 @@ static int pirq_acktype(struct domain *d
* on which they were received. This is because we tickle the LAPIC to EOI.
*/
if ( !strcmp(desc->handler->typename, "IO-APIC-level") )
- return ioapic_ack_new ? ACKTYPE_EOI : ACKTYPE_UNMASK;
+ return desc->handler->ack == irq_complete_move ?
+ ACKTYPE_EOI : ACKTYPE_UNMASK;
/* Legacy PIC interrupts can be acknowledged from any CPU. */
if ( !strcmp(desc->handler->typename, "XT-PIC") )
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] x86/IO-APIC: streamline level ack/end handling
2012-09-19 7:36 [PATCH] x86/IO-APIC: streamline level ack/end handling Jan Beulich
@ 2012-09-19 7:57 ` Keir Fraser
0 siblings, 0 replies; 2+ messages in thread
From: Keir Fraser @ 2012-09-19 7:57 UTC (permalink / raw)
To: Jan Beulich, xen-devel
On 19/09/2012 08:36, "Jan Beulich" <JBeulich@suse.com> wrote:
> Rather than evaluating "ioapic_ack_new" on each invocation, and
> considering that the two methods really have almost no code in common,
> split the handlers.
>
> While at it, also move ioapic_ack_{new,forced} into .init.data
> (eliminating the single non-__init reference to the former).
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
> --- a/xen/arch/x86/io_apic.c
> +++ b/xen/arch/x86/io_apic.c
> @@ -43,8 +43,8 @@ static struct { int pin, apic; } ioapic_
> static DEFINE_SPINLOCK(ioapic_lock);
>
> bool_t __read_mostly skip_ioapic_setup;
> -bool_t __read_mostly ioapic_ack_new = 1;
> -bool_t __read_mostly ioapic_ack_forced = 0;
> +bool_t __initdata ioapic_ack_new = 1;
> +bool_t __initdata ioapic_ack_forced = 0;
>
> /*
> * # of IRQ routing registers
> @@ -918,7 +918,7 @@ static inline int IO_APIC_irq_trigger(in
> return 0;
> }
>
> -static hw_irq_controller ioapic_level_type;
> +static struct hw_interrupt_type ioapic_level_type;
> static hw_irq_controller ioapic_edge_type;
>
> #define IOAPIC_AUTO -1
> @@ -1605,9 +1605,6 @@ static void mask_and_ack_level_ioapic_ir
>
> irq_complete_move(desc);
>
> - if ( ioapic_ack_new )
> - return;
> -
> if ( !directed_eoi_enabled )
> mask_IO_APIC_irq(desc);
>
> @@ -1651,34 +1648,29 @@ static void mask_and_ack_level_ioapic_ir
> }
> }
>
> -static void end_level_ioapic_irq(struct irq_desc *desc, u8 vector)
> +static void end_level_ioapic_irq_old(struct irq_desc *desc, u8 vector)
> {
> - unsigned long v;
> - int i;
> -
> - if ( !ioapic_ack_new )
> + if ( directed_eoi_enabled )
> {
> - if ( directed_eoi_enabled )
> + if ( !(desc->status & (IRQ_DISABLED|IRQ_MOVE_PENDING)) )
> {
> - if ( !(desc->status & (IRQ_DISABLED|IRQ_MOVE_PENDING)) )
> - {
> - eoi_IO_APIC_irq(desc);
> - return;
> - }
> -
> - mask_IO_APIC_irq(desc);
> eoi_IO_APIC_irq(desc);
> - if ( (desc->status & IRQ_MOVE_PENDING) &&
> - !io_apic_level_ack_pending(desc->irq) )
> - move_masked_irq(desc);
> + return;
> }
>
> - if ( !(desc->status & IRQ_DISABLED) )
> - unmask_IO_APIC_irq(desc);
> -
> - return;
> + mask_IO_APIC_irq(desc);
> + eoi_IO_APIC_irq(desc);
> + if ( (desc->status & IRQ_MOVE_PENDING) &&
> + !io_apic_level_ack_pending(desc->irq) )
> + move_masked_irq(desc);
> }
>
> + if ( !(desc->status & IRQ_DISABLED) )
> + unmask_IO_APIC_irq(desc);
> +}
> +
> +static void end_level_ioapic_irq_new(struct irq_desc *desc, u8 vector)
> +{
> /*
> * It appears there is an erratum which affects at least version 0x11
> * of I/O APIC (that's the 82093AA and cores integrated into various
> @@ -1698,7 +1690,7 @@ static void end_level_ioapic_irq(struct
> * operation to prevent an edge-triggered interrupt escaping meanwhile.
> * The idea is from Manfred Spraul. --macro
> */
> - i = desc->arch.vector;
> + unsigned int v, i = desc->arch.vector;
>
> /* Manually EOI the old vector if we are moving to the new */
> if ( vector && i != vector )
> @@ -1741,14 +1733,14 @@ static hw_irq_controller ioapic_edge_typ
> .set_affinity = set_ioapic_affinity_irq,
> };
>
> -static hw_irq_controller ioapic_level_type = {
> +static struct hw_interrupt_type __read_mostly ioapic_level_type = {
> .typename = "IO-APIC-level",
> .startup = startup_level_ioapic_irq,
> .shutdown = mask_IO_APIC_irq,
> .enable = unmask_IO_APIC_irq,
> .disable = mask_IO_APIC_irq,
> .ack = mask_and_ack_level_ioapic_irq,
> - .end = end_level_ioapic_irq,
> + .end = end_level_ioapic_irq_old,
> .set_affinity = set_ioapic_affinity_irq,
> };
>
> @@ -2006,6 +1998,11 @@ void __init setup_IO_APIC(void)
> printk("ENABLING IO-APIC IRQs\n");
> printk(" -> Using %s ACK method\n", ioapic_ack_new ? "new" : "old");
>
> + if (ioapic_ack_new) {
> + ioapic_level_type.ack = irq_complete_move;
> + ioapic_level_type.end = end_level_ioapic_irq_new;
> + }
> +
> /*
> * Set up IO-APIC IRQ routing.
> */
> --- a/xen/arch/x86/irq.c
> +++ b/xen/arch/x86/irq.c
> @@ -1495,7 +1495,8 @@ static int pirq_acktype(struct domain *d
> * on which they were received. This is because we tickle the LAPIC to
> EOI.
> */
> if ( !strcmp(desc->handler->typename, "IO-APIC-level") )
> - return ioapic_ack_new ? ACKTYPE_EOI : ACKTYPE_UNMASK;
> + return desc->handler->ack == irq_complete_move ?
> + ACKTYPE_EOI : ACKTYPE_UNMASK;
>
> /* Legacy PIC interrupts can be acknowledged from any CPU. */
> if ( !strcmp(desc->handler->typename, "XT-PIC") )
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-09-19 7:57 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-19 7:36 [PATCH] x86/IO-APIC: streamline level ack/end handling Jan Beulich
2012-09-19 7:57 ` Keir Fraser
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).