linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch 0/7] x86: Store irq descriptor in vector array
@ 2015-08-02 20:38 Thomas Gleixner
  2015-08-02 20:38 ` [patch 1/7] x86/irq: Protect smp_cleanup_move Thomas Gleixner
                   ` (6 more replies)
  0 siblings, 7 replies; 21+ messages in thread
From: Thomas Gleixner @ 2015-08-02 20:38 UTC (permalink / raw)
  To: LKML; +Cc: x86, Jiang Liu, Peter Zijlstra, Rusty Russell, Bjorn Helgaas

We store the irq number in the vector array, so we need to lookup the
descriptor at every interrupt. We can avoid that by simply storing the
interrupt descriptor itself in the vector array.

Thanks,

	tglx




^ permalink raw reply	[flat|nested] 21+ messages in thread

* [patch 1/7] x86/irq: Protect smp_cleanup_move
  2015-08-02 20:38 [patch 0/7] x86: Store irq descriptor in vector array Thomas Gleixner
@ 2015-08-02 20:38 ` Thomas Gleixner
  2015-08-05 22:19   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
  2015-08-02 20:38 ` [patch 2/7] x86/lguest: Do not setup unused irq vectors Thomas Gleixner
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2015-08-02 20:38 UTC (permalink / raw)
  To: LKML; +Cc: x86, Jiang Liu, Peter Zijlstra, Rusty Russell, Bjorn Helgaas

[-- Attachment #1: x86-irq--Protect-smp_cleanup_move --]
[-- Type: text/plain, Size: 1663 bytes --]

smp_cleanup_move fiddles without protection in the interrupt
descriptors and the vector array. A concurrent irq setup/teardown or
affinity setting can pull the rug under that operation.

Add proper locking.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/vector.c |   18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

Index: tip/arch/x86/kernel/apic/vector.c
===================================================================
--- tip.orig/arch/x86/kernel/apic/vector.c
+++ tip/arch/x86/kernel/apic/vector.c
@@ -539,6 +539,9 @@ asmlinkage __visible void smp_irq_move_c
 
 	entering_ack_irq();
 
+	/* Prevent vectors vanishing under us */
+	raw_spin_lock(&vector_lock);
+
 	me = smp_processor_id();
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
 		int irq;
@@ -546,6 +549,7 @@ asmlinkage __visible void smp_irq_move_c
 		struct irq_desc *desc;
 		struct apic_chip_data *data;
 
+	retry:
 		irq = __this_cpu_read(vector_irq[vector]);
 
 		if (irq <= VECTOR_UNDEFINED)
@@ -555,12 +559,16 @@ asmlinkage __visible void smp_irq_move_c
 		if (!desc)
 			continue;
 
+		if (!raw_spin_trylock(&desc->lock)) {
+			raw_spin_unlock(&vector_lock);
+			cpu_relax();
+			raw_spin_lock(&vector_lock);
+			goto retry;
+		}
+
 		data = apic_chip_data(&desc->irq_data);
 		if (!data)
-			continue;
-
-		raw_spin_lock(&desc->lock);
-
+			goto unlock;
 		/*
 		 * Check if the irq migration is in progress. If so, we
 		 * haven't received the cleanup request yet for this irq.
@@ -589,6 +597,8 @@ unlock:
 		raw_spin_unlock(&desc->lock);
 	}
 
+	raw_spin_unlock(&vector_lock);
+
 	exiting_irq();
 }
 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [patch 3/7] x86/irq: Replace numeric constant
  2015-08-02 20:38 [patch 0/7] x86: Store irq descriptor in vector array Thomas Gleixner
  2015-08-02 20:38 ` [patch 1/7] x86/irq: Protect smp_cleanup_move Thomas Gleixner
  2015-08-02 20:38 ` [patch 2/7] x86/lguest: Do not setup unused irq vectors Thomas Gleixner
@ 2015-08-02 20:38 ` Thomas Gleixner
  2015-08-05 22:19   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
  2015-08-02 20:38 ` [patch 5/7] x86/irq: Get rid of an indentation level Thomas Gleixner
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2015-08-02 20:38 UTC (permalink / raw)
  To: LKML; +Cc: x86, Jiang Liu, Peter Zijlstra, Rusty Russell, Bjorn Helgaas

[-- Attachment #1: x86-irq--Replace-numeric-constant --]
[-- Type: text/plain, Size: 688 bytes --]

Use the proper define instead of 0.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/irq.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: tip/arch/x86/kernel/irq.c
===================================================================
--- tip.orig/arch/x86/kernel/irq.c
+++ tip/arch/x86/kernel/irq.c
@@ -419,8 +419,8 @@ int check_irq_vectors_for_cpu_disable(vo
 		for (vector = FIRST_EXTERNAL_VECTOR;
 		     vector < first_system_vector; vector++) {
 			if (!test_bit(vector, used_vectors) &&
-			    per_cpu(vector_irq, cpu)[vector] < 0)
-					count++;
+			    per_cpu(vector_irq, cpu)[vector] <= VECTOR_UNDEFINED)
+				count++;
 		}
 	}
 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [patch 2/7] x86/lguest: Do not setup unused irq vectors
  2015-08-02 20:38 [patch 0/7] x86: Store irq descriptor in vector array Thomas Gleixner
  2015-08-02 20:38 ` [patch 1/7] x86/irq: Protect smp_cleanup_move Thomas Gleixner
@ 2015-08-02 20:38 ` Thomas Gleixner
  2015-08-03  2:47   ` Rusty Russell
  2015-08-02 20:38 ` [patch 3/7] x86/irq: Replace numeric constant Thomas Gleixner
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2015-08-02 20:38 UTC (permalink / raw)
  To: LKML; +Cc: x86, Jiang Liu, Peter Zijlstra, Rusty Russell, Bjorn Helgaas

[-- Attachment #1: x86-lguest--Do-not-setup-unused-irq-vectors --]
[-- Type: text/plain, Size: 1752 bytes --]

No point in assigning the interrupt vectors if there is no interrupt
chip installed. Move it to lguest_setup_irq().

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Rusty Russell <rusty@rustcorp.com.au>
---
 arch/x86/lguest/boot.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

Index: tip/arch/x86/lguest/boot.c
===================================================================
--- tip.orig/arch/x86/lguest/boot.c
+++ tip/arch/x86/lguest/boot.c
@@ -855,17 +855,13 @@ static void lguest_disable_irq(struct pc
 
 /*
  * This sets up the Interrupt Descriptor Table (IDT) entry for each hardware
- * interrupt (except 128, which is used for system calls), and then tells the
- * Linux infrastructure that each interrupt is controlled by our level-based
- * lguest interrupt controller.
+ * interrupt (except 128, which is used for system calls).
  */
 static void __init lguest_init_IRQ(void)
 {
 	unsigned int i;
 
 	for (i = FIRST_EXTERNAL_VECTOR; i < FIRST_SYSTEM_VECTOR; i++) {
-		/* Some systems map "vectors" to interrupts weirdly.  Not us! */
-		__this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
 		if (i != IA32_SYSCALL_VECTOR)
 			set_intr_gate(i, irq_entries_start +
 					8 * (i - FIRST_EXTERNAL_VECTOR));
@@ -893,8 +889,15 @@ int lguest_setup_irq(unsigned int irq)
 	if (err < 0 && err != -EEXIST)
 		return err;
 
+	/*
+	 * Tell the Linux infrastructure that the interrupt is
+	 * controlled by our level-based lguest interrupt controller.
+	 */
 	irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
 				      handle_level_irq, "level");
+
+	/* Some systems map "vectors" to interrupts weirdly.  Not us! */
+	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq, irq);
 	return 0;
 }
 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [patch 5/7] x86/irq: Get rid of an indentation level
  2015-08-02 20:38 [patch 0/7] x86: Store irq descriptor in vector array Thomas Gleixner
                   ` (2 preceding siblings ...)
  2015-08-02 20:38 ` [patch 3/7] x86/irq: Replace numeric constant Thomas Gleixner
@ 2015-08-02 20:38 ` Thomas Gleixner
  2015-08-05 22:20   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
  2015-08-02 20:38 ` [patch 4/7] x86/irq: Rename VECTOR_UNDEFINED to VECTOR_UNUSED Thomas Gleixner
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2015-08-02 20:38 UTC (permalink / raw)
  To: LKML; +Cc: x86, Jiang Liu, Peter Zijlstra, Rusty Russell, Bjorn Helgaas

[-- Attachment #1: x86-irq--Get-rid-of-an-indentation-level --]
[-- Type: text/plain, Size: 2971 bytes --]

Make the code simpler to read.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/irq.c |   72 ++++++++++++++++++++++++--------------------------
 1 file changed, 35 insertions(+), 37 deletions(-)

Index: tip/arch/x86/kernel/irq.c
===================================================================
--- tip.orig/arch/x86/kernel/irq.c
+++ tip/arch/x86/kernel/irq.c
@@ -360,47 +360,45 @@ int check_irq_vectors_for_cpu_disable(vo
 	this_count = 0;
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
 		irq = __this_cpu_read(vector_irq[vector]);
-		if (irq >= 0) {
-			desc = irq_to_desc(irq);
-			if (!desc)
-				continue;
+		if (irq < 0)
+			continue;
+		desc = irq_to_desc(irq);
+		if (!desc)
+			continue;
 
-			/*
-			 * Protect against concurrent action removal,
-			 * affinity changes etc.
-			 */
-			raw_spin_lock(&desc->lock);
-			data = irq_desc_get_irq_data(desc);
-			cpumask_copy(&affinity_new,
-				     irq_data_get_affinity_mask(data));
-			cpumask_clear_cpu(this_cpu, &affinity_new);
-
-			/* Do not count inactive or per-cpu irqs. */
-			if (!irq_has_action(irq) || irqd_is_per_cpu(data)) {
-				raw_spin_unlock(&desc->lock);
-				continue;
-			}
+		/*
+		 * Protect against concurrent action removal, affinity
+		 * changes etc.
+		 */
+		raw_spin_lock(&desc->lock);
+		data = irq_desc_get_irq_data(desc);
+		cpumask_copy(&affinity_new, irq_data_get_affinity_mask(data));
+		cpumask_clear_cpu(this_cpu, &affinity_new);
 
+		/* Do not count inactive or per-cpu irqs. */
+		if (!irq_has_action(irq) || irqd_is_per_cpu(data)) {
 			raw_spin_unlock(&desc->lock);
-			/*
-			 * A single irq may be mapped to multiple
-			 * cpu's vector_irq[] (for example IOAPIC cluster
-			 * mode).  In this case we have two
-			 * possibilities:
-			 *
-			 * 1) the resulting affinity mask is empty; that is
-			 * this the down'd cpu is the last cpu in the irq's
-			 * affinity mask, or
-			 *
-			 * 2) the resulting affinity mask is no longer
-			 * a subset of the online cpus but the affinity
-			 * mask is not zero; that is the down'd cpu is the
-			 * last online cpu in a user set affinity mask.
-			 */
-			if (cpumask_empty(&affinity_new) ||
-			    !cpumask_subset(&affinity_new, &online_new))
-				this_count++;
+			continue;
 		}
+
+		raw_spin_unlock(&desc->lock);
+		/*
+		 * A single irq may be mapped to multiple cpu's
+		 * vector_irq[] (for example IOAPIC cluster mode).  In
+		 * this case we have two possibilities:
+		 *
+		 * 1) the resulting affinity mask is empty; that is
+		 * this the down'd cpu is the last cpu in the irq's
+		 * affinity mask, or
+		 *
+		 * 2) the resulting affinity mask is no longer a
+		 * subset of the online cpus but the affinity mask is
+		 * not zero; that is the down'd cpu is the last online
+		 * cpu in a user set affinity mask.
+		 */
+		if (cpumask_empty(&affinity_new) ||
+		    !cpumask_subset(&affinity_new, &online_new))
+			this_count++;
 	}
 
 	count = 0;



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [patch 4/7] x86/irq: Rename VECTOR_UNDEFINED to VECTOR_UNUSED
  2015-08-02 20:38 [patch 0/7] x86: Store irq descriptor in vector array Thomas Gleixner
                   ` (3 preceding siblings ...)
  2015-08-02 20:38 ` [patch 5/7] x86/irq: Get rid of an indentation level Thomas Gleixner
@ 2015-08-02 20:38 ` Thomas Gleixner
  2015-08-05 22:20   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
  2015-08-02 20:38 ` [patch 6/7] genirq: Provide irq_desc_has_action Thomas Gleixner
  2015-08-02 20:38 ` [patch 7/7] x86/irq: Store irq descriptor in vector array Thomas Gleixner
  6 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2015-08-02 20:38 UTC (permalink / raw)
  To: LKML; +Cc: x86, Jiang Liu, Peter Zijlstra, Rusty Russell, Bjorn Helgaas

[-- Attachment #1: x86-irq--Rename-VECTOR_UNDEFINED-to-VECTOR_UNUSED --]
[-- Type: text/plain, Size: 4904 bytes --]

VECTOR_UNDEFINED is a misnomer. The vector is defined, but unused.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/hw_irq.h |    2 +-
 arch/x86/kernel/apic/vector.c |   15 +++++++--------
 arch/x86/kernel/irq.c         |    8 ++++----
 arch/x86/kernel/irqinit.c     |    4 ++--
 4 files changed, 14 insertions(+), 15 deletions(-)

Index: tip/arch/x86/include/asm/hw_irq.h
===================================================================
--- tip.orig/arch/x86/include/asm/hw_irq.h
+++ tip/arch/x86/include/asm/hw_irq.h
@@ -182,7 +182,7 @@ extern char irq_entries_start[];
 #define trace_irq_entries_start irq_entries_start
 #endif
 
-#define VECTOR_UNDEFINED	(-1)
+#define VECTOR_UNUSED		(-1)
 #define VECTOR_RETRIGGERED	(-2)
 
 typedef int vector_irq_t[NR_VECTORS];
Index: tip/arch/x86/kernel/apic/vector.c
===================================================================
--- tip.orig/arch/x86/kernel/apic/vector.c
+++ tip/arch/x86/kernel/apic/vector.c
@@ -169,8 +169,7 @@ next:
 			goto next;
 
 		for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) {
-			if (per_cpu(vector_irq, new_cpu)[vector] >
-			    VECTOR_UNDEFINED)
+			if (per_cpu(vector_irq, new_cpu)[vector] > VECTOR_UNUSED)
 				goto next;
 		}
 		/* Found one! */
@@ -232,7 +231,7 @@ static void clear_irq_vector(int irq, st
 
 	vector = data->cfg.vector;
 	for_each_cpu_and(cpu, data->domain, cpu_online_mask)
-		per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+		per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 
 	data->cfg.vector = 0;
 	cpumask_clear(data->domain);
@@ -247,7 +246,7 @@ static void clear_irq_vector(int irq, st
 		     vector++) {
 			if (per_cpu(vector_irq, cpu)[vector] != irq)
 				continue;
-			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 			break;
 		}
 	}
@@ -423,12 +422,12 @@ static void __setup_vector_irq(int cpu)
 	/* Mark the free vectors */
 	for (vector = 0; vector < NR_VECTORS; ++vector) {
 		irq = per_cpu(vector_irq, cpu)[vector];
-		if (irq <= VECTOR_UNDEFINED)
+		if (irq <= VECTOR_UNUSED)
 			continue;
 
 		data = apic_chip_data(irq_get_irq_data(irq));
 		if (!cpumask_test_cpu(cpu, data->domain))
-			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 	}
 }
 
@@ -552,7 +551,7 @@ asmlinkage __visible void smp_irq_move_c
 	retry:
 		irq = __this_cpu_read(vector_irq[vector]);
 
-		if (irq <= VECTOR_UNDEFINED)
+		if (irq <= VECTOR_UNUSED)
 			continue;
 
 		desc = irq_to_desc(irq);
@@ -592,7 +591,7 @@ asmlinkage __visible void smp_irq_move_c
 			apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
 			goto unlock;
 		}
-		__this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+		__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
 unlock:
 		raw_spin_unlock(&desc->lock);
 	}
Index: tip/arch/x86/kernel/irq.c
===================================================================
--- tip.orig/arch/x86/kernel/irq.c
+++ tip/arch/x86/kernel/irq.c
@@ -246,7 +246,7 @@ __visible unsigned int __irq_entry do_IR
 					     __func__, smp_processor_id(),
 					     vector, irq);
 		} else {
-			__this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+			__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
 		}
 	}
 
@@ -419,7 +419,7 @@ int check_irq_vectors_for_cpu_disable(vo
 		for (vector = FIRST_EXTERNAL_VECTOR;
 		     vector < first_system_vector; vector++) {
 			if (!test_bit(vector, used_vectors) &&
-			    per_cpu(vector_irq, cpu)[vector] <= VECTOR_UNDEFINED)
+			    per_cpu(vector_irq, cpu)[vector] <= VECTOR_UNUSED)
 				count++;
 		}
 	}
@@ -524,7 +524,7 @@ void fixup_irqs(void)
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
 		unsigned int irr;
 
-		if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNDEFINED)
+		if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNUSED)
 			continue;
 
 		irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
@@ -542,7 +542,7 @@ void fixup_irqs(void)
 			raw_spin_unlock(&desc->lock);
 		}
 		if (__this_cpu_read(vector_irq[vector]) != VECTOR_RETRIGGERED)
-			__this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+			__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
 	}
 }
 #endif
Index: tip/arch/x86/kernel/irqinit.c
===================================================================
--- tip.orig/arch/x86/kernel/irqinit.c
+++ tip/arch/x86/kernel/irqinit.c
@@ -52,7 +52,7 @@ static struct irqaction irq2 = {
 };
 
 DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
-	[0 ... NR_VECTORS - 1] = VECTOR_UNDEFINED,
+	[0 ... NR_VECTORS - 1] = VECTOR_UNUSED,
 };
 
 int vector_used_by_percpu_irq(unsigned int vector)
@@ -60,7 +60,7 @@ int vector_used_by_percpu_irq(unsigned i
 	int cpu;
 
 	for_each_online_cpu(cpu) {
-		if (per_cpu(vector_irq, cpu)[vector] > VECTOR_UNDEFINED)
+		if (per_cpu(vector_irq, cpu)[vector] > VECTOR_UNUSED)
 			return 1;
 	}
 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [patch 6/7] genirq: Provide irq_desc_has_action
  2015-08-02 20:38 [patch 0/7] x86: Store irq descriptor in vector array Thomas Gleixner
                   ` (4 preceding siblings ...)
  2015-08-02 20:38 ` [patch 4/7] x86/irq: Rename VECTOR_UNDEFINED to VECTOR_UNUSED Thomas Gleixner
@ 2015-08-02 20:38 ` Thomas Gleixner
  2015-08-05 22:20   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
  2015-08-02 20:38 ` [patch 7/7] x86/irq: Store irq descriptor in vector array Thomas Gleixner
  6 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2015-08-02 20:38 UTC (permalink / raw)
  To: LKML; +Cc: x86, Jiang Liu, Peter Zijlstra, Rusty Russell, Bjorn Helgaas

[-- Attachment #1: genirq--Provide-irq_desc_has_action --]
[-- Type: text/plain, Size: 1014 bytes --]

If we have a reference to irq_desc already, there is no point to do
another lookup.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irqdesc.h |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

Index: tip/include/linux/irqdesc.h
===================================================================
--- tip.orig/include/linux/irqdesc.h
+++ tip/include/linux/irqdesc.h
@@ -166,12 +166,16 @@ static inline int handle_domain_irq(stru
 #endif
 
 /* Test to see if a driver has successfully requested an irq */
-static inline int irq_has_action(unsigned int irq)
+static inline int irq_desc_has_action(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	return desc->action != NULL;
 }
 
+static inline int irq_has_action(unsigned int irq)
+{
+	return irq_desc_has_action(irq_to_desc(irq));
+}
+
 /* caller has locked the irq_desc and both params are valid */
 static inline void __irq_set_handler_locked(unsigned int irq,
 					    irq_flow_handler_t handler)



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [patch 7/7] x86/irq: Store irq descriptor in vector array
  2015-08-02 20:38 [patch 0/7] x86: Store irq descriptor in vector array Thomas Gleixner
                   ` (5 preceding siblings ...)
  2015-08-02 20:38 ` [patch 6/7] genirq: Provide irq_desc_has_action Thomas Gleixner
@ 2015-08-02 20:38 ` Thomas Gleixner
  2015-08-05 22:21   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
  6 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2015-08-02 20:38 UTC (permalink / raw)
  To: LKML; +Cc: x86, Jiang Liu, Peter Zijlstra, Rusty Russell, Bjorn Helgaas

[-- Attachment #1: x86-irq--Store-irq-descriptor-in-vector-array --]
[-- Type: text/plain, Size: 12139 bytes --]

We can spare the irq_desc lookup in the interrupt entry code if we
store the descriptor pointer in the vector array instead the interrupt
number.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/hw_irq.h |    6 ++--
 arch/x86/include/asm/irq.h    |    4 ++-
 arch/x86/kernel/apic/vector.c |   51 +++++++++++++++++++-----------------------
 arch/x86/kernel/irq.c         |   36 +++++++++++++----------------
 arch/x86/kernel/irq_32.c      |    8 ++----
 arch/x86/kernel/irq_64.c      |    9 ++-----
 arch/x86/kernel/irqinit.c     |    4 +--
 arch/x86/lguest/boot.c        |    4 ++-
 8 files changed, 57 insertions(+), 65 deletions(-)

Index: tip/arch/x86/include/asm/hw_irq.h
===================================================================
--- tip.orig/arch/x86/include/asm/hw_irq.h
+++ tip/arch/x86/include/asm/hw_irq.h
@@ -182,10 +182,10 @@ extern char irq_entries_start[];
 #define trace_irq_entries_start irq_entries_start
 #endif
 
-#define VECTOR_UNUSED		(-1)
-#define VECTOR_RETRIGGERED	(-2)
+#define VECTOR_UNUSED		NULL
+#define VECTOR_RETRIGGERED	((void *)~0UL)
 
-typedef int vector_irq_t[NR_VECTORS];
+typedef struct irq_desc* vector_irq_t[NR_VECTORS];
 DECLARE_PER_CPU(vector_irq_t, vector_irq);
 
 #endif /* !ASSEMBLY_ */
Index: tip/arch/x86/include/asm/irq.h
===================================================================
--- tip.orig/arch/x86/include/asm/irq.h
+++ tip/arch/x86/include/asm/irq.h
@@ -36,7 +36,9 @@ extern void kvm_set_posted_intr_wakeup_h
 
 extern void (*x86_platform_ipi_callback)(void);
 extern void native_init_IRQ(void);
-extern bool handle_irq(unsigned irq, struct pt_regs *regs);
+
+struct irq_desc;
+extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs);
 
 extern __visible unsigned int do_IRQ(struct pt_regs *regs);
 
Index: tip/arch/x86/kernel/apic/vector.c
===================================================================
--- tip.orig/arch/x86/kernel/apic/vector.c
+++ tip/arch/x86/kernel/apic/vector.c
@@ -169,7 +169,7 @@ next:
 			goto next;
 
 		for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) {
-			if (per_cpu(vector_irq, new_cpu)[vector] > VECTOR_UNUSED)
+			if (!IS_ERR_OR_NULL(per_cpu(vector_irq, new_cpu)[vector]))
 				goto next;
 		}
 		/* Found one! */
@@ -181,7 +181,7 @@ next:
 			   cpumask_intersects(d->old_domain, cpu_online_mask);
 		}
 		for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask)
-			per_cpu(vector_irq, new_cpu)[vector] = irq;
+			per_cpu(vector_irq, new_cpu)[vector] = irq_to_desc(irq);
 		d->cfg.vector = vector;
 		cpumask_copy(d->domain, vector_cpumask);
 		err = 0;
@@ -223,8 +223,9 @@ static int assign_irq_vector_policy(int
 
 static void clear_irq_vector(int irq, struct apic_chip_data *data)
 {
-	int cpu, vector;
+	struct irq_desc *desc;
 	unsigned long flags;
+	int cpu, vector;
 
 	raw_spin_lock_irqsave(&vector_lock, flags);
 	BUG_ON(!data->cfg.vector);
@@ -241,10 +242,11 @@ static void clear_irq_vector(int irq, st
 		return;
 	}
 
+	desc = irq_to_desc(irq);
 	for_each_cpu_and(cpu, data->old_domain, cpu_online_mask) {
 		for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
 		     vector++) {
-			if (per_cpu(vector_irq, cpu)[vector] != irq)
+			if (per_cpu(vector_irq, cpu)[vector] != desc)
 				continue;
 			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 			break;
@@ -402,30 +404,30 @@ int __init arch_early_irq_init(void)
 	return arch_early_ioapic_init();
 }
 
+/* Initialize vector_irq on a new cpu */
 static void __setup_vector_irq(int cpu)
 {
-	/* Initialize vector_irq on a new cpu */
-	int irq, vector;
 	struct apic_chip_data *data;
+	struct irq_desc *desc;
+	int irq, vector;
 
 	/* Mark the inuse vectors */
-	for_each_active_irq(irq) {
-		data = apic_chip_data(irq_get_irq_data(irq));
-		if (!data)
-			continue;
+	for_each_irq_desc(irq, desc) {
+		struct irq_data *idata = irq_desc_get_irq_data(desc);
 
-		if (!cpumask_test_cpu(cpu, data->domain))
+		data = apic_chip_data(idata);
+		if (!data || !cpumask_test_cpu(cpu, data->domain))
 			continue;
 		vector = data->cfg.vector;
-		per_cpu(vector_irq, cpu)[vector] = irq;
+		per_cpu(vector_irq, cpu)[vector] = desc;
 	}
 	/* Mark the free vectors */
 	for (vector = 0; vector < NR_VECTORS; ++vector) {
-		irq = per_cpu(vector_irq, cpu)[vector];
-		if (irq <= VECTOR_UNUSED)
+		desc = per_cpu(vector_irq, cpu)[vector];
+		if (IS_ERR_OR_NULL(desc))
 			continue;
 
-		data = apic_chip_data(irq_get_irq_data(irq));
+		data = apic_chip_data(irq_desc_get_irq_data(desc));
 		if (!cpumask_test_cpu(cpu, data->domain))
 			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 	}
@@ -447,7 +449,7 @@ void setup_vector_irq(int cpu)
 	 * legacy vector to irq mapping:
 	 */
 	for (irq = 0; irq < nr_legacy_irqs(); irq++)
-		per_cpu(vector_irq, cpu)[ISA_IRQ_VECTOR(irq)] = irq;
+		per_cpu(vector_irq, cpu)[ISA_IRQ_VECTOR(irq)] = irq_to_desc(irq);
 
 	__setup_vector_irq(cpu);
 }
@@ -543,19 +545,13 @@ asmlinkage __visible void smp_irq_move_c
 
 	me = smp_processor_id();
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
-		int irq;
-		unsigned int irr;
-		struct irq_desc *desc;
 		struct apic_chip_data *data;
+		struct irq_desc *desc;
+		unsigned int irr;
 
 	retry:
-		irq = __this_cpu_read(vector_irq[vector]);
-
-		if (irq <= VECTOR_UNUSED)
-			continue;
-
-		desc = irq_to_desc(irq);
-		if (!desc)
+		desc = __this_cpu_read(vector_irq[vector]);
+		if (IS_ERR_OR_NULL(desc))
 			continue;
 
 		if (!raw_spin_trylock(&desc->lock)) {
@@ -565,9 +561,10 @@ asmlinkage __visible void smp_irq_move_c
 			goto retry;
 		}
 
-		data = apic_chip_data(&desc->irq_data);
+		data = apic_chip_data(irq_desc_get_irq_data(desc));
 		if (!data)
 			goto unlock;
+
 		/*
 		 * Check if the irq migration is in progress. If so, we
 		 * haven't received the cleanup request yet for this irq.
Index: tip/arch/x86/kernel/irq.c
===================================================================
--- tip.orig/arch/x86/kernel/irq.c
+++ tip/arch/x86/kernel/irq.c
@@ -214,10 +214,9 @@ u64 arch_irq_stat(void)
 __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
-
+	struct irq_desc *desc;
 	/* high bit used in ret_from_ code  */
 	unsigned vector = ~regs->orig_ax;
-	unsigned irq;
 
 	/*
 	 * NB: Unlike exception entries, IRQ entries do not reliably
@@ -236,15 +235,16 @@ __visible unsigned int __irq_entry do_IR
 	/* entering_irq() tells RCU that we're not quiescent.  Check it. */
 	rcu_lockdep_assert(rcu_is_watching(), "IRQ failed to wake up RCU");
 
-	irq = __this_cpu_read(vector_irq[vector]);
+	desc = __this_cpu_read(vector_irq[vector]);
 
-	if (!handle_irq(irq, regs)) {
+	if (!handle_irq(desc, regs)) {
 		ack_APIC_irq();
 
-		if (irq != VECTOR_RETRIGGERED) {
+		if (desc != VECTOR_RETRIGGERED) {
 			pr_emerg_ratelimited("%s: %d.%d No irq handler for vector (irq %d)\n",
 					     __func__, smp_processor_id(),
-					     vector, irq);
+					     vector,
+					     desc ? irq_desc_get_irq(desc) : -1);
 		} else {
 			__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
 		}
@@ -348,10 +348,10 @@ static struct cpumask affinity_new, onli
  */
 int check_irq_vectors_for_cpu_disable(void)
 {
-	int irq, cpu;
 	unsigned int this_cpu, vector, this_count, count;
 	struct irq_desc *desc;
 	struct irq_data *data;
+	int cpu;
 
 	this_cpu = smp_processor_id();
 	cpumask_copy(&online_new, cpu_online_mask);
@@ -359,24 +359,21 @@ int check_irq_vectors_for_cpu_disable(vo
 
 	this_count = 0;
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
-		irq = __this_cpu_read(vector_irq[vector]);
-		if (irq < 0)
+		desc = __this_cpu_read(vector_irq[vector]);
+		if (IS_ERR_OR_NULL(desc))
 			continue;
-		desc = irq_to_desc(irq);
-		if (!desc)
-			continue;
-
 		/*
 		 * Protect against concurrent action removal, affinity
 		 * changes etc.
 		 */
 		raw_spin_lock(&desc->lock);
 		data = irq_desc_get_irq_data(desc);
-		cpumask_copy(&affinity_new, irq_data_get_affinity_mask(data));
+		cpumask_copy(&affinity_new,
+			     irq_data_get_affinity_mask(data));
 		cpumask_clear_cpu(this_cpu, &affinity_new);
 
 		/* Do not count inactive or per-cpu irqs. */
-		if (!irq_has_action(irq) || irqd_is_per_cpu(data)) {
+		if (!irq_desc_has_action(desc) || irqd_is_per_cpu(data)) {
 			raw_spin_unlock(&desc->lock);
 			continue;
 		}
@@ -417,8 +414,8 @@ int check_irq_vectors_for_cpu_disable(vo
 		for (vector = FIRST_EXTERNAL_VECTOR;
 		     vector < first_system_vector; vector++) {
 			if (!test_bit(vector, used_vectors) &&
-			    per_cpu(vector_irq, cpu)[vector] <= VECTOR_UNUSED)
-				count++;
+			    IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector]))
+			    count++;
 		}
 	}
 
@@ -522,14 +519,13 @@ void fixup_irqs(void)
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
 		unsigned int irr;
 
-		if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNUSED)
+		if (IS_ERR_OR_NULL(__this_cpu_read(vector_irq[vector])))
 			continue;
 
 		irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
 		if (irr  & (1 << (vector % 32))) {
-			irq = __this_cpu_read(vector_irq[vector]);
+			desc = __this_cpu_read(vector_irq[vector]);
 
-			desc = irq_to_desc(irq);
 			raw_spin_lock(&desc->lock);
 			data = irq_desc_get_irq_data(desc);
 			chip = irq_data_get_irq_chip(data);
Index: tip/arch/x86/kernel/irq_32.c
===================================================================
--- tip.orig/arch/x86/kernel/irq_32.c
+++ tip/arch/x86/kernel/irq_32.c
@@ -148,21 +148,19 @@ void do_softirq_own_stack(void)
 	call_on_stack(__do_softirq, isp);
 }
 
-bool handle_irq(unsigned irq, struct pt_regs *regs)
+bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
 {
-	struct irq_desc *desc;
 	int overflow;
 
 	overflow = check_stack_overflow();
 
-	desc = irq_to_desc(irq);
-	if (unlikely(!desc))
+	if (IS_ERR_OR_NULL(desc))
 		return false;
 
 	if (user_mode(regs) || !execute_on_irq_stack(overflow, desc, irq)) {
 		if (unlikely(overflow))
 			print_stack_overflow();
-		desc->handle_irq(irq, desc);
+		generic_handle_irq_desc(irq_desc_get_irq(desc), desc);
 	}
 
 	return true;
Index: tip/arch/x86/kernel/irq_64.c
===================================================================
--- tip.orig/arch/x86/kernel/irq_64.c
+++ tip/arch/x86/kernel/irq_64.c
@@ -68,16 +68,13 @@ static inline void stack_overflow_check(
 #endif
 }
 
-bool handle_irq(unsigned irq, struct pt_regs *regs)
+bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
 {
-	struct irq_desc *desc;
-
 	stack_overflow_check(regs);
 
-	desc = irq_to_desc(irq);
-	if (unlikely(!desc))
+	if (unlikely(IS_ERR_OR_NULL(desc)))
 		return false;
 
-	generic_handle_irq_desc(irq, desc);
+	generic_handle_irq_desc(irq_desc_get_irq(desc), desc);
 	return true;
 }
Index: tip/arch/x86/kernel/irqinit.c
===================================================================
--- tip.orig/arch/x86/kernel/irqinit.c
+++ tip/arch/x86/kernel/irqinit.c
@@ -60,7 +60,7 @@ int vector_used_by_percpu_irq(unsigned i
 	int cpu;
 
 	for_each_online_cpu(cpu) {
-		if (per_cpu(vector_irq, cpu)[vector] > VECTOR_UNUSED)
+		if (!IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector]))
 			return 1;
 	}
 
@@ -94,7 +94,7 @@ void __init init_IRQ(void)
 	 * irq's migrate etc.
 	 */
 	for (i = 0; i < nr_legacy_irqs(); i++)
-		per_cpu(vector_irq, 0)[ISA_IRQ_VECTOR(i)] = i;
+		per_cpu(vector_irq, 0)[ISA_IRQ_VECTOR(i)] = irq_to_desc(i);
 
 	x86_init.irqs.intr_init();
 }
Index: tip/arch/x86/lguest/boot.c
===================================================================
--- tip.orig/arch/x86/lguest/boot.c
+++ tip/arch/x86/lguest/boot.c
@@ -882,6 +882,7 @@ static void __init lguest_init_IRQ(void)
  */
 int lguest_setup_irq(unsigned int irq)
 {
+	struct irq_desc *desc;
 	int err;
 
 	/* Returns -ve error or vector number. */
@@ -897,7 +898,8 @@ int lguest_setup_irq(unsigned int irq)
 				      handle_level_irq, "level");
 
 	/* Some systems map "vectors" to interrupts weirdly.  Not us! */
-	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq, irq);
+	desc = irq_to_desc(irq);
+	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq], desc);
 	return 0;
 }
 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [patch 2/7] x86/lguest: Do not setup unused irq vectors
  2015-08-02 20:38 ` [patch 2/7] x86/lguest: Do not setup unused irq vectors Thomas Gleixner
@ 2015-08-03  2:47   ` Rusty Russell
  2015-08-03  9:40     ` Thomas Gleixner
  0 siblings, 1 reply; 21+ messages in thread
From: Rusty Russell @ 2015-08-03  2:47 UTC (permalink / raw)
  To: Thomas Gleixner, LKML; +Cc: x86, Jiang Liu, Peter Zijlstra, Bjorn Helgaas

Thomas Gleixner <tglx@linutronix.de> writes:
> No point in assigning the interrupt vectors if there is no interrupt
> chip installed. Move it to lguest_setup_irq().
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> ---
>  arch/x86/lguest/boot.c |   13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
>
> Index: tip/arch/x86/lguest/boot.c
> ===================================================================
> --- tip.orig/arch/x86/lguest/boot.c
> +++ tip/arch/x86/lguest/boot.c
> @@ -855,17 +855,13 @@ static void lguest_disable_irq(struct pc
>  
>  /*
>   * This sets up the Interrupt Descriptor Table (IDT) entry for each hardware
> - * interrupt (except 128, which is used for system calls), and then tells the
> - * Linux infrastructure that each interrupt is controlled by our level-based
> - * lguest interrupt controller.
> + * interrupt (except 128, which is used for system calls).
>   */
>  static void __init lguest_init_IRQ(void)
>  {
>  	unsigned int i;
>  
>  	for (i = FIRST_EXTERNAL_VECTOR; i < FIRST_SYSTEM_VECTOR; i++) {
> -		/* Some systems map "vectors" to interrupts weirdly.  Not us! */
> -		__this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
>  		if (i != IA32_SYSCALL_VECTOR)
>  			set_intr_gate(i, irq_entries_start +
>  					8 * (i - FIRST_EXTERNAL_VECTOR));
> @@ -893,8 +889,15 @@ int lguest_setup_irq(unsigned int irq)
>  	if (err < 0 && err != -EEXIST)
>  		return err;
>  
> +	/*
> +	 * Tell the Linux infrastructure that the interrupt is
> +	 * controlled by our level-based lguest interrupt controller.
> +	 */
>  	irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
>  				      handle_level_irq, "level");
> +
> +	/* Some systems map "vectors" to interrupts weirdly.  Not us! */
> +	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq, irq);

Missing ].

Then it doesn't work:

[    3.832028] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    3.832028] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    3.832028] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    3.839983] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    3.840026] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    3.840026] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    3.840026] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    3.848349] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    3.848349] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    3.848349] do_IRQ: 0.33 No irq handler for vector (irq -1)
[    4.056027] brd: module loaded
[    4.156025] loop: module loaded

<hit return>

[   17.712169] do_IRQ: 4 callbacks suppressed
[   17.712169] do_IRQ: 0.33 No irq handler for vector (irq -1)
[   17.720462] do_IRQ: 0.33 No irq handler for vector (irq -1)
[   17.720462] do_IRQ: 0.33 No irq handler for vector (irq -1)
[   17.729129] do_IRQ: 0.33 No irq handler for vector (irq -1)
[   17.729129] do_IRQ: 0.33 No irq handler for vector (irq -1)
[   17.736523] do_IRQ: 0.33 No irq handler for vector (irq -1)
[   17.736523] do_IRQ: 0.33 No irq handler for vector (irq -1)
[   17.744288] do_IRQ: 0.33 No irq handler for vector (irq -1)
[   17.744288] do_IRQ: 0.33 No irq handler for vector (irq -1)
[   17.751889] do_IRQ: 0.33 No irq handler for vector (irq -1)

You broke interrupts :(

Cheers,
Rusty.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [patch 2/7] x86/lguest: Do not setup unused irq vectors
  2015-08-03  2:47   ` Rusty Russell
@ 2015-08-03  9:40     ` Thomas Gleixner
  2015-08-04  4:27       ` Rusty Russell
  0 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2015-08-03  9:40 UTC (permalink / raw)
  To: Rusty Russell; +Cc: LKML, x86, Jiang Liu, Peter Zijlstra, Bjorn Helgaas

On Mon, 3 Aug 2015, Rusty Russell wrote:
> Thomas Gleixner <tglx@linutronix.de> writes:
> > +
> > +	/* Some systems map "vectors" to interrupts weirdly.  Not us! */
> > +	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq, irq);
> 
> Missing ].

Doh.

> [   17.751889] do_IRQ: 0.33 No irq handler for vector (irq -1)
> 
> You broke interrupts :(

Right, because I missed the other place which fiddles with
interrupts. Does the patch below fix the issue?

Thanks,

	tglx
---------------->
Index: tip/arch/x86/lguest/boot.c
===================================================================
--- tip.orig/arch/x86/lguest/boot.c
+++ tip/arch/x86/lguest/boot.c
@@ -841,8 +841,7 @@ static int lguest_enable_irq(struct pci_
 
 	/* We literally use the PCI interrupt line as the irq number. */
 	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
-	irq_set_chip_and_handler_name(line, &lguest_irq_controller,
-				      handle_level_irq, "level");
+	lguest_setup_irq(line);
 	dev->irq = line;
 	return 0;
 }





^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [patch 2/7] x86/lguest: Do not setup unused irq vectors
  2015-08-03  9:40     ` Thomas Gleixner
@ 2015-08-04  4:27       ` Rusty Russell
  2015-08-04  4:32         ` [PATCH 1/2] x86/lguest: clean up lguest_setup_irq Rusty Russell
  0 siblings, 1 reply; 21+ messages in thread
From: Rusty Russell @ 2015-08-04  4:27 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: LKML, x86, Jiang Liu, Peter Zijlstra, Bjorn Helgaas

Thomas Gleixner <tglx@linutronix.de> writes:
> On Mon, 3 Aug 2015, Rusty Russell wrote:
>> Thomas Gleixner <tglx@linutronix.de> writes:
>> > +
>> > +	/* Some systems map "vectors" to interrupts weirdly.  Not us! */
>> > +	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq, irq);
>> 
>> Missing ].
>
> Doh.
>
>> [   17.751889] do_IRQ: 0.33 No irq handler for vector (irq -1)
>> 
>> You broke interrupts :(
>
> Right, because I missed the other place which fiddles with
> interrupts. Does the patch below fix the issue?

Yep.  I added error handling.

I reworked it into two patches: one which staticizes lguest_setup_irq()
and moves it up, the other of which applies your changes.

Will post, you can take them...

Thanks,
Rusty.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/2] x86/lguest: clean up lguest_setup_irq.
  2015-08-04  4:27       ` Rusty Russell
@ 2015-08-04  4:32         ` Rusty Russell
  2015-08-04  4:32           ` [PATCH 2/2] x86/lguest: Do not setup unused irq vectors Rusty Russell
  2015-08-05 22:18           ` [tip:x86/apic] x86/lguest: Clean up lguest_setup_irq tip-bot for Rusty Russell
  0 siblings, 2 replies; 21+ messages in thread
From: Rusty Russell @ 2015-08-04  4:32 UTC (permalink / raw)
  To: Thomas Gleixner, LKML, x86; +Cc: Rusty Russell

We make it static and hoist it higher in the file for the next patch.
We also give a nice panic if it fails during boot.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 arch/x86/lguest/boot.c | 43 ++++++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 433e5a7dd37f..f38b7e8a88d2 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -835,6 +835,26 @@ static struct irq_chip lguest_irq_controller = {
 	.irq_unmask	= enable_lguest_irq,
 };
 
+/*
+ * Interrupt descriptors are allocated as-needed, but low-numbered ones are
+ * reserved by the generic x86 code.  So we ignore irq_alloc_desc_at if it
+ * tells us the irq is already used: other errors (ie. ENOMEM) we take
+ * seriously.
+ */
+static int lguest_setup_irq(unsigned int irq)
+{
+	int err;
+
+	/* Returns -ve error or vector number. */
+	err = irq_alloc_desc_at(irq, 0);
+	if (err < 0 && err != -EEXIST)
+		return err;
+
+	irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
+				      handle_level_irq, "level");
+	return 0;
+}
+
 static int lguest_enable_irq(struct pci_dev *dev)
 {
 	u8 line = 0;
@@ -879,26 +899,6 @@ static void __init lguest_init_IRQ(void)
 }
 
 /*
- * Interrupt descriptors are allocated as-needed, but low-numbered ones are
- * reserved by the generic x86 code.  So we ignore irq_alloc_desc_at if it
- * tells us the irq is already used: other errors (ie. ENOMEM) we take
- * seriously.
- */
-int lguest_setup_irq(unsigned int irq)
-{
-	int err;
-
-	/* Returns -ve error or vector number. */
-	err = irq_alloc_desc_at(irq, 0);
-	if (err < 0 && err != -EEXIST)
-		return err;
-
-	irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
-				      handle_level_irq, "level");
-	return 0;
-}
-
-/*
  * Time.
  *
  * It would be far better for everyone if the Guest had its own clock, but
@@ -1028,7 +1028,8 @@ static void lguest_time_irq(unsigned int irq, struct irq_desc *desc)
 static void lguest_time_init(void)
 {
 	/* Set up the timer interrupt (0) to go to our simple timer routine */
-	lguest_setup_irq(0);
+	if (lguest_setup_irq(0) != 0)
+		panic("Could not set up timer irq");
 	irq_set_handler(0, lguest_time_irq);
 
 	clocksource_register_hz(&lguest_clock, NSEC_PER_SEC);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/2] x86/lguest: Do not setup unused irq vectors
  2015-08-04  4:32         ` [PATCH 1/2] x86/lguest: clean up lguest_setup_irq Rusty Russell
@ 2015-08-04  4:32           ` Rusty Russell
  2015-08-05 22:19             ` [tip:x86/apic] " tip-bot for Thomas Gleixner
  2015-08-05 22:18           ` [tip:x86/apic] x86/lguest: Clean up lguest_setup_irq tip-bot for Rusty Russell
  1 sibling, 1 reply; 21+ messages in thread
From: Rusty Russell @ 2015-08-04  4:32 UTC (permalink / raw)
  To: Thomas Gleixner, LKML, x86; +Cc: Rusty Russell

From: Thomas Gleixner <tglx@linutronix.de>

No point in assigning the interrupt vectors if there is no interrupt
chip installed. Move it to lguest_setup_irq().

(And call it from lguest_enable_irq).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (fixed typo)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 arch/x86/lguest/boot.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index f38b7e8a88d2..2566c97c01c8 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -850,21 +850,29 @@ static int lguest_setup_irq(unsigned int irq)
 	if (err < 0 && err != -EEXIST)
 		return err;
 
+	/*
+	 * Tell the Linux infrastructure that the interrupt is
+	 * controlled by our level-based lguest interrupt controller.
+	 */
 	irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
 				      handle_level_irq, "level");
+
+	/* Some systems map "vectors" to interrupts weirdly.  Not us! */
+	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq], irq);
 	return 0;
 }
 
 static int lguest_enable_irq(struct pci_dev *dev)
 {
+	int err;
 	u8 line = 0;
 
 	/* We literally use the PCI interrupt line as the irq number. */
 	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
-	irq_set_chip_and_handler_name(line, &lguest_irq_controller,
-				      handle_level_irq, "level");
-	dev->irq = line;
-	return 0;
+	err = lguest_setup_irq(line);
+	if (!err)
+		dev->irq = line;
+	return err;
 }
 
 /* We don't do hotplug PCI, so this shouldn't be called. */
@@ -875,17 +883,13 @@ static void lguest_disable_irq(struct pci_dev *dev)
 
 /*
  * This sets up the Interrupt Descriptor Table (IDT) entry for each hardware
- * interrupt (except 128, which is used for system calls), and then tells the
- * Linux infrastructure that each interrupt is controlled by our level-based
- * lguest interrupt controller.
+ * interrupt (except 128, which is used for system calls).
  */
 static void __init lguest_init_IRQ(void)
 {
 	unsigned int i;
 
 	for (i = FIRST_EXTERNAL_VECTOR; i < FIRST_SYSTEM_VECTOR; i++) {
-		/* Some systems map "vectors" to interrupts weirdly.  Not us! */
-		__this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
 		if (i != IA32_SYSCALL_VECTOR)
 			set_intr_gate(i, irq_entries_start +
 					8 * (i - FIRST_EXTERNAL_VECTOR));
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [tip:x86/apic] x86/lguest: Clean up lguest_setup_irq
  2015-08-04  4:32         ` [PATCH 1/2] x86/lguest: clean up lguest_setup_irq Rusty Russell
  2015-08-04  4:32           ` [PATCH 2/2] x86/lguest: Do not setup unused irq vectors Rusty Russell
@ 2015-08-05 22:18           ` tip-bot for Rusty Russell
  1 sibling, 0 replies; 21+ messages in thread
From: tip-bot for Rusty Russell @ 2015-08-05 22:18 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: rusty, tglx, linux-kernel, hpa, mingo

Commit-ID:  27a6f41c1a20a3339f456647a21e45fca5b82b62
Gitweb:     http://git.kernel.org/tip/27a6f41c1a20a3339f456647a21e45fca5b82b62
Author:     Rusty Russell <rusty@rustcorp.com.au>
AuthorDate: Tue, 4 Aug 2015 14:02:55 +0930
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 6 Aug 2015 00:14:58 +0200

x86/lguest: Clean up lguest_setup_irq

We make it static and hoist it higher in the file for the next patch.
We also give a nice panic if it fails during boot.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Link: http://lkml.kernel.org/r/1438662776-4823-1-git-send-email-rusty@rustcorp.com.au
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/lguest/boot.c | 43 ++++++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index f2dc08c..d933a11 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -835,6 +835,26 @@ static struct irq_chip lguest_irq_controller = {
 	.irq_unmask	= enable_lguest_irq,
 };
 
+/*
+ * Interrupt descriptors are allocated as-needed, but low-numbered ones are
+ * reserved by the generic x86 code.  So we ignore irq_alloc_desc_at if it
+ * tells us the irq is already used: other errors (ie. ENOMEM) we take
+ * seriously.
+ */
+static int lguest_setup_irq(unsigned int irq)
+{
+	int err;
+
+	/* Returns -ve error or vector number. */
+	err = irq_alloc_desc_at(irq, 0);
+	if (err < 0 && err != -EEXIST)
+		return err;
+
+	irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
+				      handle_level_irq, "level");
+	return 0;
+}
+
 static int lguest_enable_irq(struct pci_dev *dev)
 {
 	u8 line = 0;
@@ -879,26 +899,6 @@ static void __init lguest_init_IRQ(void)
 }
 
 /*
- * Interrupt descriptors are allocated as-needed, but low-numbered ones are
- * reserved by the generic x86 code.  So we ignore irq_alloc_desc_at if it
- * tells us the irq is already used: other errors (ie. ENOMEM) we take
- * seriously.
- */
-int lguest_setup_irq(unsigned int irq)
-{
-	int err;
-
-	/* Returns -ve error or vector number. */
-	err = irq_alloc_desc_at(irq, 0);
-	if (err < 0 && err != -EEXIST)
-		return err;
-
-	irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
-				      handle_level_irq, "level");
-	return 0;
-}
-
-/*
  * Time.
  *
  * It would be far better for everyone if the Guest had its own clock, but
@@ -1040,7 +1040,8 @@ static void lguest_time_irq(unsigned int irq, struct irq_desc *desc)
 static void lguest_time_init(void)
 {
 	/* Set up the timer interrupt (0) to go to our simple timer routine */
-	lguest_setup_irq(0);
+	if (lguest_setup_irq(0) != 0)
+		panic("Could not set up timer irq");
 	irq_set_handler(0, lguest_time_irq);
 
 	clocksource_register_hz(&lguest_clock, NSEC_PER_SEC);

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [tip:x86/apic] x86/lguest: Do not setup unused irq vectors
  2015-08-04  4:32           ` [PATCH 2/2] x86/lguest: Do not setup unused irq vectors Rusty Russell
@ 2015-08-05 22:19             ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-08-05 22:19 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, mingo, tglx, hpa, rusty

Commit-ID:  ad3f8d5afe503faa78d61a50a1f6eec3afa7c787
Gitweb:     http://git.kernel.org/tip/ad3f8d5afe503faa78d61a50a1f6eec3afa7c787
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 4 Aug 2015 14:02:56 +0930
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 6 Aug 2015 00:14:58 +0200

x86/lguest: Do not setup unused irq vectors

No point in assigning the interrupt vectors if there is no interrupt
chip installed. Move it to lguest_setup_irq() and call it from
lguest_enable_irq.

[ rusty: Typo fix and error handling ]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Link: http://lkml.kernel.org/r/1438662776-4823-2-git-send-email-rusty@rustcorp.com.au
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/lguest/boot.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index d933a11..2165f45 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -850,21 +850,29 @@ static int lguest_setup_irq(unsigned int irq)
 	if (err < 0 && err != -EEXIST)
 		return err;
 
+	/*
+	 * Tell the Linux infrastructure that the interrupt is
+	 * controlled by our level-based lguest interrupt controller.
+	 */
 	irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
 				      handle_level_irq, "level");
+
+	/* Some systems map "vectors" to interrupts weirdly.  Not us! */
+	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq], irq);
 	return 0;
 }
 
 static int lguest_enable_irq(struct pci_dev *dev)
 {
+	int err;
 	u8 line = 0;
 
 	/* We literally use the PCI interrupt line as the irq number. */
 	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
-	irq_set_chip_and_handler_name(line, &lguest_irq_controller,
-				      handle_level_irq, "level");
-	dev->irq = line;
-	return 0;
+	err = lguest_setup_irq(line);
+	if (!err)
+		dev->irq = line;
+	return err;
 }
 
 /* We don't do hotplug PCI, so this shouldn't be called. */
@@ -875,17 +883,13 @@ static void lguest_disable_irq(struct pci_dev *dev)
 
 /*
  * This sets up the Interrupt Descriptor Table (IDT) entry for each hardware
- * interrupt (except 128, which is used for system calls), and then tells the
- * Linux infrastructure that each interrupt is controlled by our level-based
- * lguest interrupt controller.
+ * interrupt (except 128, which is used for system calls).
  */
 static void __init lguest_init_IRQ(void)
 {
 	unsigned int i;
 
 	for (i = FIRST_EXTERNAL_VECTOR; i < FIRST_SYSTEM_VECTOR; i++) {
-		/* Some systems map "vectors" to interrupts weirdly.  Not us! */
-		__this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
 		if (i != IA32_SYSCALL_VECTOR)
 			set_intr_gate(i, irq_entries_start +
 					8 * (i - FIRST_EXTERNAL_VECTOR));

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [tip:x86/apic] x86/irq: Protect smp_cleanup_move
  2015-08-02 20:38 ` [patch 1/7] x86/irq: Protect smp_cleanup_move Thomas Gleixner
@ 2015-08-05 22:19   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-08-05 22:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: bhelgaas, hpa, linux-kernel, tglx, mingo, rusty, peterz, jiang.liu

Commit-ID:  df54c4934e030e73cb6a7bd6713f697350dabd0b
Gitweb:     http://git.kernel.org/tip/df54c4934e030e73cb6a7bd6713f697350dabd0b
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Sun, 2 Aug 2015 20:38:23 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 6 Aug 2015 00:14:58 +0200

x86/irq: Protect smp_cleanup_move

smp_cleanup_move fiddles without protection in the interrupt
descriptors and the vector array. A concurrent irq setup/teardown or
affinity setting can pull the rug under that operation.

Add proper locking.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Link: http://lkml.kernel.org/r/20150802203609.222975294@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/vector.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index f47069e..63d58b0 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -539,6 +539,9 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
 
 	entering_ack_irq();
 
+	/* Prevent vectors vanishing under us */
+	raw_spin_lock(&vector_lock);
+
 	me = smp_processor_id();
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
 		int irq;
@@ -546,6 +549,7 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
 		struct irq_desc *desc;
 		struct apic_chip_data *data;
 
+	retry:
 		irq = __this_cpu_read(vector_irq[vector]);
 
 		if (irq <= VECTOR_UNDEFINED)
@@ -555,12 +559,16 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
 		if (!desc)
 			continue;
 
+		if (!raw_spin_trylock(&desc->lock)) {
+			raw_spin_unlock(&vector_lock);
+			cpu_relax();
+			raw_spin_lock(&vector_lock);
+			goto retry;
+		}
+
 		data = apic_chip_data(&desc->irq_data);
 		if (!data)
-			continue;
-
-		raw_spin_lock(&desc->lock);
-
+			goto unlock;
 		/*
 		 * Check if the irq migration is in progress. If so, we
 		 * haven't received the cleanup request yet for this irq.
@@ -589,6 +597,8 @@ unlock:
 		raw_spin_unlock(&desc->lock);
 	}
 
+	raw_spin_unlock(&vector_lock);
+
 	exiting_irq();
 }
 

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [tip:x86/apic] x86/irq: Replace numeric constant
  2015-08-02 20:38 ` [patch 3/7] x86/irq: Replace numeric constant Thomas Gleixner
@ 2015-08-05 22:19   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-08-05 22:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: rusty, tglx, hpa, jiang.liu, bhelgaas, mingo, linux-kernel, peterz

Commit-ID:  24c70e07a0311a98dbb5e7a7472fa96a22b789d3
Gitweb:     http://git.kernel.org/tip/24c70e07a0311a98dbb5e7a7472fa96a22b789d3
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Sun, 2 Aug 2015 20:38:24 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 6 Aug 2015 00:14:58 +0200

x86/irq: Replace numeric constant

Use the proper define instead of 0.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Link: http://lkml.kernel.org/r/20150802203609.385495420@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/irq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index bc28496..35d4cb2 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -401,8 +401,8 @@ int check_irq_vectors_for_cpu_disable(void)
 		for (vector = FIRST_EXTERNAL_VECTOR;
 		     vector < first_system_vector; vector++) {
 			if (!test_bit(vector, used_vectors) &&
-			    per_cpu(vector_irq, cpu)[vector] < 0)
-					count++;
+			    per_cpu(vector_irq, cpu)[vector] <= VECTOR_UNDEFINED)
+				count++;
 		}
 	}
 

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [tip:x86/apic] x86/irq: Rename VECTOR_UNDEFINED to VECTOR_UNUSED
  2015-08-02 20:38 ` [patch 4/7] x86/irq: Rename VECTOR_UNDEFINED to VECTOR_UNUSED Thomas Gleixner
@ 2015-08-05 22:20   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-08-05 22:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, linux-kernel, jiang.liu, mingo, rusty, hpa, bhelgaas, peterz

Commit-ID:  7276c6a2cb5f7ae46fd0c9539af02dbcb7c4f3f5
Gitweb:     http://git.kernel.org/tip/7276c6a2cb5f7ae46fd0c9539af02dbcb7c4f3f5
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Sun, 2 Aug 2015 20:38:25 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 6 Aug 2015 00:14:58 +0200

x86/irq: Rename VECTOR_UNDEFINED to VECTOR_UNUSED

VECTOR_UNDEFINED is a misnomer. The vector is defined, but unused.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Link: http://lkml.kernel.org/r/20150802203609.477282494@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/hw_irq.h |  2 +-
 arch/x86/kernel/apic/vector.c | 15 +++++++--------
 arch/x86/kernel/irq.c         |  8 ++++----
 arch/x86/kernel/irqinit.c     |  4 ++--
 4 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 6615032..62bb8d2 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -182,7 +182,7 @@ extern char irq_entries_start[];
 #define trace_irq_entries_start irq_entries_start
 #endif
 
-#define VECTOR_UNDEFINED	(-1)
+#define VECTOR_UNUSED		(-1)
 #define VECTOR_RETRIGGERED	(-2)
 
 typedef int vector_irq_t[NR_VECTORS];
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 63d58b0..9a6d112 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -169,8 +169,7 @@ next:
 			goto next;
 
 		for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) {
-			if (per_cpu(vector_irq, new_cpu)[vector] >
-			    VECTOR_UNDEFINED)
+			if (per_cpu(vector_irq, new_cpu)[vector] > VECTOR_UNUSED)
 				goto next;
 		}
 		/* Found one! */
@@ -232,7 +231,7 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data)
 
 	vector = data->cfg.vector;
 	for_each_cpu_and(cpu, data->domain, cpu_online_mask)
-		per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+		per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 
 	data->cfg.vector = 0;
 	cpumask_clear(data->domain);
@@ -247,7 +246,7 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data)
 		     vector++) {
 			if (per_cpu(vector_irq, cpu)[vector] != irq)
 				continue;
-			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 			break;
 		}
 	}
@@ -423,12 +422,12 @@ static void __setup_vector_irq(int cpu)
 	/* Mark the free vectors */
 	for (vector = 0; vector < NR_VECTORS; ++vector) {
 		irq = per_cpu(vector_irq, cpu)[vector];
-		if (irq <= VECTOR_UNDEFINED)
+		if (irq <= VECTOR_UNUSED)
 			continue;
 
 		data = apic_chip_data(irq_get_irq_data(irq));
 		if (!cpumask_test_cpu(cpu, data->domain))
-			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 	}
 }
 
@@ -552,7 +551,7 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
 	retry:
 		irq = __this_cpu_read(vector_irq[vector]);
 
-		if (irq <= VECTOR_UNDEFINED)
+		if (irq <= VECTOR_UNUSED)
 			continue;
 
 		desc = irq_to_desc(irq);
@@ -592,7 +591,7 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
 			apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
 			goto unlock;
 		}
-		__this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+		__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
 unlock:
 		raw_spin_unlock(&desc->lock);
 	}
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 35d4cb2..931bdd2 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -228,7 +228,7 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
 					     __func__, smp_processor_id(),
 					     vector, irq);
 		} else {
-			__this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+			__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
 		}
 	}
 
@@ -401,7 +401,7 @@ int check_irq_vectors_for_cpu_disable(void)
 		for (vector = FIRST_EXTERNAL_VECTOR;
 		     vector < first_system_vector; vector++) {
 			if (!test_bit(vector, used_vectors) &&
-			    per_cpu(vector_irq, cpu)[vector] <= VECTOR_UNDEFINED)
+			    per_cpu(vector_irq, cpu)[vector] <= VECTOR_UNUSED)
 				count++;
 		}
 	}
@@ -506,7 +506,7 @@ void fixup_irqs(void)
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
 		unsigned int irr;
 
-		if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNDEFINED)
+		if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNUSED)
 			continue;
 
 		irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
@@ -524,7 +524,7 @@ void fixup_irqs(void)
 			raw_spin_unlock(&desc->lock);
 		}
 		if (__this_cpu_read(vector_irq[vector]) != VECTOR_RETRIGGERED)
-			__this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+			__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
 	}
 }
 #endif
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index a3a5e15..32a637f 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -52,7 +52,7 @@ static struct irqaction irq2 = {
 };
 
 DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
-	[0 ... NR_VECTORS - 1] = VECTOR_UNDEFINED,
+	[0 ... NR_VECTORS - 1] = VECTOR_UNUSED,
 };
 
 int vector_used_by_percpu_irq(unsigned int vector)
@@ -60,7 +60,7 @@ int vector_used_by_percpu_irq(unsigned int vector)
 	int cpu;
 
 	for_each_online_cpu(cpu) {
-		if (per_cpu(vector_irq, cpu)[vector] > VECTOR_UNDEFINED)
+		if (per_cpu(vector_irq, cpu)[vector] > VECTOR_UNUSED)
 			return 1;
 	}
 

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [tip:x86/apic] x86/irq: Get rid of an indentation level
  2015-08-02 20:38 ` [patch 5/7] x86/irq: Get rid of an indentation level Thomas Gleixner
@ 2015-08-05 22:20   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-08-05 22:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jiang.liu, peterz, rusty, hpa, mingo, bhelgaas, tglx, linux-kernel

Commit-ID:  44825757a3ee37c030165a94d6b4dd79c564f661
Gitweb:     http://git.kernel.org/tip/44825757a3ee37c030165a94d6b4dd79c564f661
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Sun, 2 Aug 2015 20:38:25 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 6 Aug 2015 00:14:59 +0200

x86/irq: Get rid of an indentation level

Make the code simpler to read.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Link: http://lkml.kernel.org/r/20150802203609.555253675@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/irq.c | 72 +++++++++++++++++++++++++--------------------------
 1 file changed, 35 insertions(+), 37 deletions(-)

diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 931bdd2..140950f 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -342,47 +342,45 @@ int check_irq_vectors_for_cpu_disable(void)
 	this_count = 0;
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
 		irq = __this_cpu_read(vector_irq[vector]);
-		if (irq >= 0) {
-			desc = irq_to_desc(irq);
-			if (!desc)
-				continue;
+		if (irq < 0)
+			continue;
+		desc = irq_to_desc(irq);
+		if (!desc)
+			continue;
 
-			/*
-			 * Protect against concurrent action removal,
-			 * affinity changes etc.
-			 */
-			raw_spin_lock(&desc->lock);
-			data = irq_desc_get_irq_data(desc);
-			cpumask_copy(&affinity_new,
-				     irq_data_get_affinity_mask(data));
-			cpumask_clear_cpu(this_cpu, &affinity_new);
-
-			/* Do not count inactive or per-cpu irqs. */
-			if (!irq_has_action(irq) || irqd_is_per_cpu(data)) {
-				raw_spin_unlock(&desc->lock);
-				continue;
-			}
+		/*
+		 * Protect against concurrent action removal, affinity
+		 * changes etc.
+		 */
+		raw_spin_lock(&desc->lock);
+		data = irq_desc_get_irq_data(desc);
+		cpumask_copy(&affinity_new, irq_data_get_affinity_mask(data));
+		cpumask_clear_cpu(this_cpu, &affinity_new);
 
+		/* Do not count inactive or per-cpu irqs. */
+		if (!irq_has_action(irq) || irqd_is_per_cpu(data)) {
 			raw_spin_unlock(&desc->lock);
-			/*
-			 * A single irq may be mapped to multiple
-			 * cpu's vector_irq[] (for example IOAPIC cluster
-			 * mode).  In this case we have two
-			 * possibilities:
-			 *
-			 * 1) the resulting affinity mask is empty; that is
-			 * this the down'd cpu is the last cpu in the irq's
-			 * affinity mask, or
-			 *
-			 * 2) the resulting affinity mask is no longer
-			 * a subset of the online cpus but the affinity
-			 * mask is not zero; that is the down'd cpu is the
-			 * last online cpu in a user set affinity mask.
-			 */
-			if (cpumask_empty(&affinity_new) ||
-			    !cpumask_subset(&affinity_new, &online_new))
-				this_count++;
+			continue;
 		}
+
+		raw_spin_unlock(&desc->lock);
+		/*
+		 * A single irq may be mapped to multiple cpu's
+		 * vector_irq[] (for example IOAPIC cluster mode).  In
+		 * this case we have two possibilities:
+		 *
+		 * 1) the resulting affinity mask is empty; that is
+		 * this the down'd cpu is the last cpu in the irq's
+		 * affinity mask, or
+		 *
+		 * 2) the resulting affinity mask is no longer a
+		 * subset of the online cpus but the affinity mask is
+		 * not zero; that is the down'd cpu is the last online
+		 * cpu in a user set affinity mask.
+		 */
+		if (cpumask_empty(&affinity_new) ||
+		    !cpumask_subset(&affinity_new, &online_new))
+			this_count++;
 	}
 
 	count = 0;

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [tip:x86/apic] genirq: Provide irq_desc_has_action
  2015-08-02 20:38 ` [patch 6/7] genirq: Provide irq_desc_has_action Thomas Gleixner
@ 2015-08-05 22:20   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-08-05 22:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, rusty, jiang.liu, linux-kernel, bhelgaas, hpa, peterz, mingo

Commit-ID:  f61ae4fb66a4f7ae49e3456003fc4328d6db09c9
Gitweb:     http://git.kernel.org/tip/f61ae4fb66a4f7ae49e3456003fc4328d6db09c9
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Sun, 2 Aug 2015 20:38:26 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 6 Aug 2015 00:14:59 +0200

genirq: Provide irq_desc_has_action

If we have a reference to irq_desc already, there is no point to do
another lookup.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Link: http://lkml.kernel.org/r/20150802203609.638130301@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irqdesc.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index fcea4e4..5acfa26 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -166,12 +166,16 @@ static inline int handle_domain_irq(struct irq_domain *domain,
 #endif
 
 /* Test to see if a driver has successfully requested an irq */
-static inline int irq_has_action(unsigned int irq)
+static inline int irq_desc_has_action(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	return desc->action != NULL;
 }
 
+static inline int irq_has_action(unsigned int irq)
+{
+	return irq_desc_has_action(irq_to_desc(irq));
+}
+
 /* caller has locked the irq_desc and both params are valid */
 static inline void __irq_set_handler_locked(unsigned int irq,
 					    irq_flow_handler_t handler)

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [tip:x86/apic] x86/irq: Store irq descriptor in vector array
  2015-08-02 20:38 ` [patch 7/7] x86/irq: Store irq descriptor in vector array Thomas Gleixner
@ 2015-08-05 22:21   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-08-05 22:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, peterz, bhelgaas, hpa, linux-kernel, tglx, jiang.liu, rusty

Commit-ID:  a782a7e46bb50822fabfeb7271605762a59c86df
Gitweb:     http://git.kernel.org/tip/a782a7e46bb50822fabfeb7271605762a59c86df
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Sun, 2 Aug 2015 20:38:27 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 6 Aug 2015 00:14:59 +0200

x86/irq: Store irq descriptor in vector array

We can spare the irq_desc lookup in the interrupt entry code if we
store the descriptor pointer in the vector array instead the interrupt
number.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Link: http://lkml.kernel.org/r/20150802203609.717724106@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/hw_irq.h |  6 ++---
 arch/x86/include/asm/irq.h    |  4 +++-
 arch/x86/kernel/apic/vector.c | 51 ++++++++++++++++++++-----------------------
 arch/x86/kernel/irq.c         | 37 ++++++++++++++-----------------
 arch/x86/kernel/irq_32.c      |  9 ++++----
 arch/x86/kernel/irq_64.c      |  9 +++-----
 arch/x86/kernel/irqinit.c     |  4 ++--
 arch/x86/lguest/boot.c        |  4 +++-
 8 files changed, 58 insertions(+), 66 deletions(-)

diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 62bb8d2..1e3408e 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -182,10 +182,10 @@ extern char irq_entries_start[];
 #define trace_irq_entries_start irq_entries_start
 #endif
 
-#define VECTOR_UNUSED		(-1)
-#define VECTOR_RETRIGGERED	(-2)
+#define VECTOR_UNUSED		NULL
+#define VECTOR_RETRIGGERED	((void *)~0UL)
 
-typedef int vector_irq_t[NR_VECTORS];
+typedef struct irq_desc* vector_irq_t[NR_VECTORS];
 DECLARE_PER_CPU(vector_irq_t, vector_irq);
 
 #endif /* !ASSEMBLY_ */
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 8008d06..881b476 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -36,7 +36,9 @@ extern void kvm_set_posted_intr_wakeup_handler(void (*handler)(void));
 
 extern void (*x86_platform_ipi_callback)(void);
 extern void native_init_IRQ(void);
-extern bool handle_irq(unsigned irq, struct pt_regs *regs);
+
+struct irq_desc;
+extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs);
 
 extern __visible unsigned int do_IRQ(struct pt_regs *regs);
 
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 9a6d112..200b5a5 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -169,7 +169,7 @@ next:
 			goto next;
 
 		for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) {
-			if (per_cpu(vector_irq, new_cpu)[vector] > VECTOR_UNUSED)
+			if (!IS_ERR_OR_NULL(per_cpu(vector_irq, new_cpu)[vector]))
 				goto next;
 		}
 		/* Found one! */
@@ -181,7 +181,7 @@ next:
 			   cpumask_intersects(d->old_domain, cpu_online_mask);
 		}
 		for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask)
-			per_cpu(vector_irq, new_cpu)[vector] = irq;
+			per_cpu(vector_irq, new_cpu)[vector] = irq_to_desc(irq);
 		d->cfg.vector = vector;
 		cpumask_copy(d->domain, vector_cpumask);
 		err = 0;
@@ -223,8 +223,9 @@ static int assign_irq_vector_policy(int irq, int node,
 
 static void clear_irq_vector(int irq, struct apic_chip_data *data)
 {
-	int cpu, vector;
+	struct irq_desc *desc;
 	unsigned long flags;
+	int cpu, vector;
 
 	raw_spin_lock_irqsave(&vector_lock, flags);
 	BUG_ON(!data->cfg.vector);
@@ -241,10 +242,11 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data)
 		return;
 	}
 
+	desc = irq_to_desc(irq);
 	for_each_cpu_and(cpu, data->old_domain, cpu_online_mask) {
 		for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
 		     vector++) {
-			if (per_cpu(vector_irq, cpu)[vector] != irq)
+			if (per_cpu(vector_irq, cpu)[vector] != desc)
 				continue;
 			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 			break;
@@ -402,30 +404,30 @@ int __init arch_early_irq_init(void)
 	return arch_early_ioapic_init();
 }
 
+/* Initialize vector_irq on a new cpu */
 static void __setup_vector_irq(int cpu)
 {
-	/* Initialize vector_irq on a new cpu */
-	int irq, vector;
 	struct apic_chip_data *data;
+	struct irq_desc *desc;
+	int irq, vector;
 
 	/* Mark the inuse vectors */
-	for_each_active_irq(irq) {
-		data = apic_chip_data(irq_get_irq_data(irq));
-		if (!data)
-			continue;
+	for_each_irq_desc(irq, desc) {
+		struct irq_data *idata = irq_desc_get_irq_data(desc);
 
-		if (!cpumask_test_cpu(cpu, data->domain))
+		data = apic_chip_data(idata);
+		if (!data || !cpumask_test_cpu(cpu, data->domain))
 			continue;
 		vector = data->cfg.vector;
-		per_cpu(vector_irq, cpu)[vector] = irq;
+		per_cpu(vector_irq, cpu)[vector] = desc;
 	}
 	/* Mark the free vectors */
 	for (vector = 0; vector < NR_VECTORS; ++vector) {
-		irq = per_cpu(vector_irq, cpu)[vector];
-		if (irq <= VECTOR_UNUSED)
+		desc = per_cpu(vector_irq, cpu)[vector];
+		if (IS_ERR_OR_NULL(desc))
 			continue;
 
-		data = apic_chip_data(irq_get_irq_data(irq));
+		data = apic_chip_data(irq_desc_get_irq_data(desc));
 		if (!cpumask_test_cpu(cpu, data->domain))
 			per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
 	}
@@ -447,7 +449,7 @@ void setup_vector_irq(int cpu)
 	 * legacy vector to irq mapping:
 	 */
 	for (irq = 0; irq < nr_legacy_irqs(); irq++)
-		per_cpu(vector_irq, cpu)[ISA_IRQ_VECTOR(irq)] = irq;
+		per_cpu(vector_irq, cpu)[ISA_IRQ_VECTOR(irq)] = irq_to_desc(irq);
 
 	__setup_vector_irq(cpu);
 }
@@ -543,19 +545,13 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
 
 	me = smp_processor_id();
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
-		int irq;
-		unsigned int irr;
-		struct irq_desc *desc;
 		struct apic_chip_data *data;
+		struct irq_desc *desc;
+		unsigned int irr;
 
 	retry:
-		irq = __this_cpu_read(vector_irq[vector]);
-
-		if (irq <= VECTOR_UNUSED)
-			continue;
-
-		desc = irq_to_desc(irq);
-		if (!desc)
+		desc = __this_cpu_read(vector_irq[vector]);
+		if (IS_ERR_OR_NULL(desc))
 			continue;
 
 		if (!raw_spin_trylock(&desc->lock)) {
@@ -565,9 +561,10 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
 			goto retry;
 		}
 
-		data = apic_chip_data(&desc->irq_data);
+		data = apic_chip_data(irq_desc_get_irq_data(desc));
 		if (!data)
 			goto unlock;
+
 		/*
 		 * Check if the irq migration is in progress. If so, we
 		 * haven't received the cleanup request yet for this irq.
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 140950f..e010847 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -211,22 +211,21 @@ u64 arch_irq_stat(void)
 __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
-
+	struct irq_desc * desc;
 	/* high bit used in ret_from_ code  */
 	unsigned vector = ~regs->orig_ax;
-	unsigned irq;
 
 	entering_irq();
 
-	irq = __this_cpu_read(vector_irq[vector]);
+	desc = __this_cpu_read(vector_irq[vector]);
 
-	if (!handle_irq(irq, regs)) {
+	if (!handle_irq(desc, regs)) {
 		ack_APIC_irq();
 
-		if (irq != VECTOR_RETRIGGERED) {
-			pr_emerg_ratelimited("%s: %d.%d No irq handler for vector (irq %d)\n",
+		if (desc != VECTOR_RETRIGGERED) {
+			pr_emerg_ratelimited("%s: %d.%d No irq handler for vector\n",
 					     __func__, smp_processor_id(),
-					     vector, irq);
+					     vector);
 		} else {
 			__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
 		}
@@ -330,10 +329,10 @@ static struct cpumask affinity_new, online_new;
  */
 int check_irq_vectors_for_cpu_disable(void)
 {
-	int irq, cpu;
 	unsigned int this_cpu, vector, this_count, count;
 	struct irq_desc *desc;
 	struct irq_data *data;
+	int cpu;
 
 	this_cpu = smp_processor_id();
 	cpumask_copy(&online_new, cpu_online_mask);
@@ -341,24 +340,21 @@ int check_irq_vectors_for_cpu_disable(void)
 
 	this_count = 0;
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
-		irq = __this_cpu_read(vector_irq[vector]);
-		if (irq < 0)
-			continue;
-		desc = irq_to_desc(irq);
-		if (!desc)
+		desc = __this_cpu_read(vector_irq[vector]);
+		if (IS_ERR_OR_NULL(desc))
 			continue;
-
 		/*
 		 * Protect against concurrent action removal, affinity
 		 * changes etc.
 		 */
 		raw_spin_lock(&desc->lock);
 		data = irq_desc_get_irq_data(desc);
-		cpumask_copy(&affinity_new, irq_data_get_affinity_mask(data));
+		cpumask_copy(&affinity_new,
+			     irq_data_get_affinity_mask(data));
 		cpumask_clear_cpu(this_cpu, &affinity_new);
 
 		/* Do not count inactive or per-cpu irqs. */
-		if (!irq_has_action(irq) || irqd_is_per_cpu(data)) {
+		if (!irq_desc_has_action(desc) || irqd_is_per_cpu(data)) {
 			raw_spin_unlock(&desc->lock);
 			continue;
 		}
@@ -399,8 +395,8 @@ int check_irq_vectors_for_cpu_disable(void)
 		for (vector = FIRST_EXTERNAL_VECTOR;
 		     vector < first_system_vector; vector++) {
 			if (!test_bit(vector, used_vectors) &&
-			    per_cpu(vector_irq, cpu)[vector] <= VECTOR_UNUSED)
-				count++;
+			    IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector]))
+			    count++;
 		}
 	}
 
@@ -504,14 +500,13 @@ void fixup_irqs(void)
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
 		unsigned int irr;
 
-		if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNUSED)
+		if (IS_ERR_OR_NULL(__this_cpu_read(vector_irq[vector])))
 			continue;
 
 		irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
 		if (irr  & (1 << (vector % 32))) {
-			irq = __this_cpu_read(vector_irq[vector]);
+			desc = __this_cpu_read(vector_irq[vector]);
 
-			desc = irq_to_desc(irq);
 			raw_spin_lock(&desc->lock);
 			data = irq_desc_get_irq_data(desc);
 			chip = irq_data_get_irq_chip(data);
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index cd74f59..217b013 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -148,21 +148,20 @@ void do_softirq_own_stack(void)
 	call_on_stack(__do_softirq, isp);
 }
 
-bool handle_irq(unsigned irq, struct pt_regs *regs)
+bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
 {
-	struct irq_desc *desc;
+	unsigned int irq = irq_desc_get_irq(desc);
 	int overflow;
 
 	overflow = check_stack_overflow();
 
-	desc = irq_to_desc(irq);
-	if (unlikely(!desc))
+	if (IS_ERR_OR_NULL(desc))
 		return false;
 
 	if (user_mode(regs) || !execute_on_irq_stack(overflow, desc, irq)) {
 		if (unlikely(overflow))
 			print_stack_overflow();
-		desc->handle_irq(irq, desc);
+		generic_handle_irq_desc(irq, desc);
 	}
 
 	return true;
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index bc4604e..ff16ccb 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -68,16 +68,13 @@ static inline void stack_overflow_check(struct pt_regs *regs)
 #endif
 }
 
-bool handle_irq(unsigned irq, struct pt_regs *regs)
+bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
 {
-	struct irq_desc *desc;
-
 	stack_overflow_check(regs);
 
-	desc = irq_to_desc(irq);
-	if (unlikely(!desc))
+	if (unlikely(IS_ERR_OR_NULL(desc)))
 		return false;
 
-	generic_handle_irq_desc(irq, desc);
+	generic_handle_irq_desc(irq_desc_get_irq(desc), desc);
 	return true;
 }
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 32a637f..1423ab1 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -60,7 +60,7 @@ int vector_used_by_percpu_irq(unsigned int vector)
 	int cpu;
 
 	for_each_online_cpu(cpu) {
-		if (per_cpu(vector_irq, cpu)[vector] > VECTOR_UNUSED)
+		if (!IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector]))
 			return 1;
 	}
 
@@ -94,7 +94,7 @@ void __init init_IRQ(void)
 	 * irq's migrate etc.
 	 */
 	for (i = 0; i < nr_legacy_irqs(); i++)
-		per_cpu(vector_irq, 0)[ISA_IRQ_VECTOR(i)] = i;
+		per_cpu(vector_irq, 0)[ISA_IRQ_VECTOR(i)] = irq_to_desc(i);
 
 	x86_init.irqs.intr_init();
 }
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 2165f45..47071a0 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -843,6 +843,7 @@ static struct irq_chip lguest_irq_controller = {
  */
 static int lguest_setup_irq(unsigned int irq)
 {
+	struct irq_desc *desc;
 	int err;
 
 	/* Returns -ve error or vector number. */
@@ -858,7 +859,8 @@ static int lguest_setup_irq(unsigned int irq)
 				      handle_level_irq, "level");
 
 	/* Some systems map "vectors" to interrupts weirdly.  Not us! */
-	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq], irq);
+	desc = irq_to_desc(irq);
+	__this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq], desc);
 	return 0;
 }
 

^ permalink raw reply related	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2015-08-05 22:21 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-02 20:38 [patch 0/7] x86: Store irq descriptor in vector array Thomas Gleixner
2015-08-02 20:38 ` [patch 1/7] x86/irq: Protect smp_cleanup_move Thomas Gleixner
2015-08-05 22:19   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2015-08-02 20:38 ` [patch 2/7] x86/lguest: Do not setup unused irq vectors Thomas Gleixner
2015-08-03  2:47   ` Rusty Russell
2015-08-03  9:40     ` Thomas Gleixner
2015-08-04  4:27       ` Rusty Russell
2015-08-04  4:32         ` [PATCH 1/2] x86/lguest: clean up lguest_setup_irq Rusty Russell
2015-08-04  4:32           ` [PATCH 2/2] x86/lguest: Do not setup unused irq vectors Rusty Russell
2015-08-05 22:19             ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2015-08-05 22:18           ` [tip:x86/apic] x86/lguest: Clean up lguest_setup_irq tip-bot for Rusty Russell
2015-08-02 20:38 ` [patch 3/7] x86/irq: Replace numeric constant Thomas Gleixner
2015-08-05 22:19   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2015-08-02 20:38 ` [patch 5/7] x86/irq: Get rid of an indentation level Thomas Gleixner
2015-08-05 22:20   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2015-08-02 20:38 ` [patch 4/7] x86/irq: Rename VECTOR_UNDEFINED to VECTOR_UNUSED Thomas Gleixner
2015-08-05 22:20   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2015-08-02 20:38 ` [patch 6/7] genirq: Provide irq_desc_has_action Thomas Gleixner
2015-08-05 22:20   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2015-08-02 20:38 ` [patch 7/7] x86/irq: Store irq descriptor in vector array Thomas Gleixner
2015-08-05 22:21   ` [tip:x86/apic] " tip-bot for Thomas Gleixner

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).