[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <tip-fda7c08b1349cc4c65f8a5240b10f7e9938604b8@git.kernel.org>
Date: Wed, 26 Nov 2014 15:20:08 -0800
From: tip-bot for Jiang Liu <tipbot@...or.com>
To: linux-tip-commits@...r.kernel.org
Cc: mingo@...nel.org, rdunlap@...radead.org, bhelgaas@...gle.com,
hpa@...or.com, tony.luck@...el.com, rjw@...ysocki.net,
jiang.liu@...ux.intel.com, grant.likely@...aro.org,
konrad.wilk@...cle.com, bp@...en8.de, gregkh@...uxfoundation.org,
tglx@...utronix.de, yinghai@...nel.org, joro@...tes.org,
linux-kernel@...r.kernel.org, benh@...nel.crashing.org,
jroedel@...e.de
Subject: [tip:x86/apic] x86, irq:
Use cached IOAPIC entry instead of reading from hardware
Commit-ID: fda7c08b1349cc4c65f8a5240b10f7e9938604b8
Gitweb: http://git.kernel.org/tip/fda7c08b1349cc4c65f8a5240b10f7e9938604b8
Author: Jiang Liu <jiang.liu@...ux.intel.com>
AuthorDate: Tue, 25 Nov 2014 15:49:53 +0800
Committer: Thomas Gleixner <tglx@...utronix.de>
CommitDate: Wed, 26 Nov 2014 23:52:49 +0100
x86, irq: Use cached IOAPIC entry instead of reading from hardware
Use cached IOAPIC entry instead of reading data from IOAPIC hardware
registers to improve performance.
Signed-off-by: Jiang Liu <jiang.liu@...ux.intel.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@...cle.com>
Cc: Tony Luck <tony.luck@...el.com>
Cc: Joerg Roedel <joro@...tes.org>
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc: Bjorn Helgaas <bhelgaas@...gle.com>
Cc: Benjamin Herrenschmidt <benh@...nel.crashing.org>
Cc: Rafael J. Wysocki <rjw@...ysocki.net>
Cc: Randy Dunlap <rdunlap@...radead.org>
Cc: Yinghai Lu <yinghai@...nel.org>
Cc: Borislav Petkov <bp@...en8.de>
Cc: Grant Likely <grant.likely@...aro.org>
Link: http://lkml.kernel.org/r/1416901802-24211-30-git-send-email-jiang.liu@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
Tested-by: Joerg Roedel <jroedel@...e.de>
---
arch/x86/kernel/apic/io_apic.c | 78 ++++++++++++------------------------------
1 file changed, 21 insertions(+), 57 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index a915ee0..8a62933 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -69,8 +69,13 @@
int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
/*
- * Is the SiS APIC rmw bug present ?
+ * Is the SiS APIC rmw bug present ?
* -1 = don't know, 0 = no, 1 = yes
+ * When doing a read-modify-write operation on IOAPIC registers, older SiS APIC
+ * requires we rewrite the index register again where the read already set up
+ * the index register.
+ * The code to make use of sis_apic_bug has been removed, but we don't want to
+ * loss this knowledge.
*/
int sis_apic_bug = -1;
@@ -290,22 +295,6 @@ static void io_apic_write(unsigned int apic, unsigned int reg,
writel(value, &io_apic->data);
}
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- *
- * Older SiS APIC requires we rewrite the index register
- */
-static void io_apic_modify(unsigned int apic, unsigned int reg,
- unsigned int value)
-{
- struct io_apic __iomem *io_apic = io_apic_base(apic);
-
- if (sis_apic_bug)
- writel(reg, &io_apic->index);
- writel(value, &io_apic->data);
-}
-
union entry_union {
struct { u32 w1, w2; };
struct IO_APIC_route_entry entry;
@@ -442,29 +431,23 @@ static void __init replace_pin_at_irq_node(struct mp_chip_data *data, int node,
add_pin_to_irq_node(data, node, newapic, newpin);
}
-static void __io_apic_modify_irq(struct irq_pin_list *entry,
- int mask_and, int mask_or,
- void (*final)(struct irq_pin_list *entry))
-{
- unsigned int reg, pin;
-
- pin = entry->pin;
- reg = io_apic_read(entry->apic, 0x10 + pin * 2);
- reg &= mask_and;
- reg |= mask_or;
- io_apic_modify(entry->apic, 0x10 + pin * 2, reg);
- if (final)
- final(entry);
-}
-
static void io_apic_modify_irq(struct mp_chip_data *data,
int mask_and, int mask_or,
void (*final)(struct irq_pin_list *entry))
{
+ union entry_union eu;
struct irq_pin_list *entry;
- for_each_irq_pin(entry, data->irq_2_pin)
- __io_apic_modify_irq(entry, mask_and, mask_or, final);
+ eu.entry = data->entry;
+ eu.w1 &= mask_and;
+ eu.w1 |= mask_or;
+ data->entry = eu.entry;
+
+ for_each_irq_pin(entry, data->irq_2_pin) {
+ io_apic_write(entry->apic, 0x10 + 2 * entry->pin, eu.w1);
+ if (final)
+ final(entry);
+ }
}
static void io_apic_sync(struct irq_pin_list *entry)
@@ -1729,28 +1712,6 @@ static unsigned int startup_ioapic_irq(struct irq_data *data)
return was_pending;
}
-static void __target_IO_APIC_irq(unsigned int irq, struct irq_cfg *cfg,
- struct mp_chip_data *data)
-{
- int apic, pin;
- struct irq_pin_list *entry;
- u8 vector = cfg->vector;
- unsigned int dest = SET_APIC_LOGICAL_ID(cfg->dest_apicid);
-
- for_each_irq_pin(entry, data->irq_2_pin) {
- unsigned int reg;
-
- apic = entry->apic;
- pin = entry->pin;
-
- io_apic_write(apic, 0x11 + pin*2, dest);
- reg = io_apic_read(apic, 0x10 + pin*2);
- reg &= ~IO_APIC_REDIR_VECTOR_MASK;
- reg |= vector;
- io_apic_modify(apic, 0x10 + pin*2, reg);
- }
-}
-
atomic_t irq_mis_count;
#ifdef CONFIG_GENERIC_PENDING_IRQ
@@ -1916,6 +1877,7 @@ static int ioapic_set_affinity(struct irq_data *irq_data,
{
struct irq_data *parent = irq_data->parent_data;
struct mp_chip_data *data = irq_data->chip_data;
+ struct irq_pin_list *entry;
struct irq_cfg *cfg;
unsigned long flags;
int ret;
@@ -1926,7 +1888,9 @@ static int ioapic_set_affinity(struct irq_data *irq_data,
cfg = irqd_cfg(irq_data);
data->entry.dest = SET_APIC_LOGICAL_ID(cfg->dest_apicid);
data->entry.vector = cfg->vector;
- __target_IO_APIC_irq(irq_data->irq, cfg, irq_data->chip_data);
+ for_each_irq_pin(entry, data->irq_2_pin)
+ __ioapic_write_entry(entry->apic, entry->pin,
+ data->entry);
}
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists