All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@domain.hid>
To: adeos-main <adeos-main@gna.org>
Subject: Re: [Adeos-main] [RFC][PATCH] x86-64: Enable root domain IRQ migration
Date: Fri, 19 Dec 2008 16:18:50 +0100	[thread overview]
Message-ID: <494BBB5A.90805@domain.hid> (raw)
In-Reply-To: <494B6A26.1040001@domain.hid>

Jan Kiszka wrote:
> Currently, I-pipe breaks the setting of IRQ affinities through Linux,
> the root domain. This is because migrating IRQs while they are active is
> a tricky business on x86, requiring special measures within the IRQ ack
> path. And as this path is now used by non-root domains, the migration
> code had to be deactivated.
> 
> The following patch is a proof of concept for x86-64 how to overcome
> this unfortunate limitation (if you want to isolate RT from non-RT
> CPUs). The approach works without adding code to critical paths. First
> tests inside KVM indicate that things work as expected, but more testing
> on real iron is scheduled, e.g. to check MSI IRQs which I don't have in
> my KVM environment.
> 

Here is version 2, now also including 32-bit support (untested).

Meanwhile I've run this patch on an real dual core box with MSI, and all
works smoothly.

Jan
---
 arch/x86/kernel/io_apic_32.c |   24 ++++++++++++++++++++++++
 arch/x86/kernel/io_apic_64.c |   42 +++++++++++++++++++++++++++++++++++++-----
 include/asm-x86/ipipe.h      |   11 +++++++++++
 include/asm-x86/ipipe_64.h   |    5 +++--
 include/linux/irq.h          |    3 +++
 5 files changed, 78 insertions(+), 7 deletions(-)

Index: b/arch/x86/kernel/io_apic_64.c
===================================================================
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -174,7 +174,6 @@ static inline void io_apic_modify(unsign
 	writel(value, &io_apic->data);
 }
 
-#ifndef CONFIG_IPIPE
 static bool io_apic_level_ack_pending(unsigned int irq)
 {
 	struct irq_pin_list *entry;
@@ -203,7 +202,6 @@ static bool io_apic_level_ack_pending(un
 
 	return false;
 }
-#endif /* !CONFIG_IPIPE */
 
 /*
  * Synchronize the IO-APIC and the CPU by doing
@@ -1436,7 +1434,6 @@ unlock:
 	irq_exit();
 }
 
-#ifndef CONFIG_IPIPE
 static void irq_complete_move(unsigned int irq)
 {
 	struct irq_cfg *cfg = irq_cfg + irq;
@@ -1456,11 +1453,34 @@ static void irq_complete_move(unsigned i
 		cfg->move_in_progress = 0;
 	}
 }
-#endif
-#elif !defined(CONFIG_IPIPE)
+#else
 static inline void irq_complete_move(unsigned int irq) {}
 #endif
 
+#ifdef CONFIG_IPIPE
+static void move_apic_irq(unsigned int irq)
+{
+	struct irq_desc *desc = &irq_desc[irq];
+
+	if (desc->handle_irq == &handle_edge_irq) {
+		spin_lock(&desc->lock);
+		irq_complete_move(irq);
+		move_native_irq(irq);
+		spin_unlock(&desc->lock);
+	} else if (desc->handle_irq == &handle_fasteoi_irq) {
+		spin_lock(&desc->lock);
+		irq_complete_move(irq);
+		if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
+			if (!io_apic_level_ack_pending(irq))
+				move_masked_irq(irq);
+			unmask_IO_APIC_irq(irq);
+		}
+		spin_unlock(&desc->lock);
+	} else
+		WARN_ON_ONCE(1);
+}
+#endif /* CONFIG_IPIPE */
+
 static void ack_apic_edge(unsigned int irq)
 {
 #ifndef CONFIG_IPIPE
@@ -1544,6 +1564,9 @@ static struct irq_chip ioapic_chip __rea
 	.eoi 		= ack_apic_level,
 #ifdef CONFIG_SMP
 	.set_affinity 	= set_ioapic_affinity_irq,
+#ifdef CONFIG_IPIPE
+	.move		= move_apic_irq,
+#endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
 };
@@ -2087,6 +2110,9 @@ static struct irq_chip msi_chip = {
 	.ack		= ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_msi_irq_affinity,
+#ifdef CONFIG_IPIPE
+	.move		= move_apic_irq,
+#endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
 };
@@ -2156,6 +2182,9 @@ struct irq_chip dmar_msi_type = {
 	.ack = ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity = dmar_msi_set_affinity,
+#ifdef CONFIG_IPIPE
+	.move = move_apic_irq,
+#endif
 #endif
 	.retrigger = ioapic_retrigger_irq,
 };
@@ -2225,6 +2254,9 @@ static struct irq_chip ht_irq_chip = {
 	.ack		= ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_ht_irq_affinity,
+#ifdef CONFIG_IPIPE
+	.move		= move_apic_irq,
+#endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
 };
Index: b/include/asm-x86/ipipe_64.h
===================================================================
--- a/include/asm-x86/ipipe_64.h
+++ b/include/asm-x86/ipipe_64.h
@@ -144,10 +144,11 @@ static inline void __ipipe_call_root_vir
 	do {								\
 		local_irq_enable_nohead(ipd);				\
 		if (ipd == ipipe_root_domain) {				\
-			if (likely(!ipipe_virtual_irq_p(irq)))		\
+			if (likely(!ipipe_virtual_irq_p(irq))) {	\
+				__ipipe_move_root_irq(irq);		\
 				__ipipe_call_root_xirq_handler(		\
 					irq, (ipd)->irqs[irq].handler);	\
-			else						\
+			} else						\
 				__ipipe_call_root_virq_handler(		\
 					irq, (ipd)->irqs[irq].handler,	\
 					(ipd)->irqs[irq].cookie);	\
Index: b/include/linux/irq.h
===================================================================
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -111,6 +111,9 @@ struct irq_chip {
 
 	void		(*end)(unsigned int irq);
 	void		(*set_affinity)(unsigned int irq, cpumask_t dest);
+#ifdef CONFIG_IPIPE
+	void		(*move)(unsigned int irq);
+#endif /* CONFIG_IPIPE */
 	int		(*retrigger)(unsigned int irq);
 	int		(*set_type)(unsigned int irq, unsigned int flow_type);
 	int		(*set_wake)(unsigned int irq, unsigned int on);
Index: b/arch/x86/kernel/io_apic_32.c
===================================================================
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -1929,6 +1929,21 @@ static unsigned int startup_ioapic_irq(u
 	return was_pending;
 }
 
+#if defined(CONFIG_IPIPE) && defined(CONFIG_SMP)
+static void move_apic_irq(unsigned int irq)
+{
+	struct irq_desc *desc = &irq_desc[irq];
+
+	if (desc->handle_irq == &handle_edge_irq ||
+	    desc->handle_irq == &handle_fasteoi_irq) {
+		spin_lock(&desc->lock);
+		move_native_irq(irq);
+		spin_unlock(&desc->lock);
+	} else
+		WARN_ON_ONCE(1);
+}
+#endif /* CONFIG_IPIPE && CONFIG_SMP */
+
 static void ack_ioapic_irq(unsigned int irq)
 {
 #ifndef CONFIG_IPIPE
@@ -2018,6 +2033,9 @@ static struct irq_chip ioapic_chip __rea
 	.eoi 		= ack_ioapic_quirk_irq,
 #ifdef CONFIG_SMP
 	.set_affinity 	= set_ioapic_affinity_irq,
+#ifdef CONFIG_IPIPE
+	.move		= move_apic_irq,
+#endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
 };
@@ -2600,6 +2618,9 @@ static struct irq_chip msi_chip = {
 	.ack		= ack_ioapic_irq,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_msi_irq_affinity,
+#ifdef CONFIG_IPIPE
+	.move		= move_apic_irq,
+#endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
 };
@@ -2680,6 +2701,9 @@ static struct irq_chip ht_irq_chip = {
 	.ack		= ack_ioapic_irq,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_ht_irq_affinity,
+#ifdef CONFIG_IPIPE
+	.move		= move_apic_irq,
+#endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
 };
Index: b/include/asm-x86/ipipe.h
===================================================================
--- a/include/asm-x86/ipipe.h
+++ b/include/asm-x86/ipipe.h
@@ -118,6 +118,17 @@ int __ipipe_check_tickdev(const char *de
 
 #define __ipipe_root_tick_p(regs)	((regs)->flags & X86_EFLAGS_IF)
 
+#ifdef CONFIG_SMP
+#define __ipipe_move_root_irq(irq)					\
+	do {								\
+		struct irq_chip *chip = irq_desc[irq].chip;		\
+		if (irq < NR_IRQS && chip->move)			\
+			chip->move(irq);				\
+	} while (0)
+#else /* !CONFIG_SMP */
+#define __ipipe_move_root_irq(irq)	do { } while (0)
+#endif /* !CONFIG_SMP */
+
 #else /* !CONFIG_IPIPE */
 
 #define ipipe_update_tick_evtdev(evtdev)	do { } while (0)


  reply	other threads:[~2008-12-19 15:18 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-19  9:32 [Adeos-main] [RFC][PATCH] x86-64: Enable root domain IRQ migration Jan Kiszka
2008-12-19 15:18 ` Jan Kiszka [this message]
2008-12-19 15:23   ` Philippe Gerum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=494BBB5A.90805@domain.hid \
    --to=jan.kiszka@domain.hid \
    --cc=adeos-main@gna.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.