linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch 00/47] Sparse irq rework
@ 2010-09-30 23:14 Thomas Gleixner
  2010-09-30 23:14 ` [patch 01/47] x86: Plug memory leak in sparse irq Thomas Gleixner
                   ` (50 more replies)
  0 siblings, 51 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

The following patch series cleans up and mostly reimplements the core
sparse irq implementation and sanitizes the most complex (ab)user:
arch/x86

The series is based on the previous rework of irq chip functions which
is available at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core

A combined throwaway git repository with all the following patches on top of
tip/irq/core is available at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git

The overall changes are (full changelog below):
    56 files changed, 1229 insertions(+), 1682 deletions(-)

The series consists of 3 parts:

    - cleanup of kernel/irq code and implementation of new allocator
    - conversion of x86 to new irq_chip functions and new allocator
    - trivial cleanup of the remaining users and removal of the old stuff

It's fully bisectable and survived a night of testing in my testfarm.

There are two bugfix patches (1/47, 2/47), which resulted of staring
at that maze for way too long. They are targeted for mainline urgent,
but I left them in the queue to avoid further churn.


Rationale:
----------

The current sparse_irq allocator has several short comings due to
failures in the design or the lack of it:

 - Requires iteration over the number of active irqs to find a free slot
   Some architectures have grown their own workarounds for this.

 - Freeing of irq descriptors is not possible

 - Racy between create_irq_nr and destroy_irq plugged by horrible
   callbacks

 - Migration of active irq descriptors is not possible

 - No bulk allocation of irq ranges

Aside of that the sparse irq design failure caused that we sprinkled
irq_desc references all over the place outside of kernel/irq/. That
makes it extremly hard to do the core changes which are necessary to
do further cleanups and improvements like he migration of active irq
descriptors. The arch code needs only to know about the irq chip and
the data associated with the irq. The irq descriptor itself is solely
a core code data structure.

The reason is that with the non sparse code access to the irq data was
just array pointer math and most code (aside of the old __do_IRQ()
users) used the provided accessor functions.

With sparse it requires a radix tree lookup, which casued performance
problems. Instead of tackling the problem at the chip function level
and handing down a pointer to the associated data instead of an irq
number, the low level code acquired a reference to irq_desc and
populated that all over the place. Yeah, it's easier than doing a full
cleanup and a sensible migration path, but the resulting mess is just
disgusting.

The previous chip functions series on which this series is based is
addressing this issue on the chip level side by handing down the
associated interrupt data instead of the interruut number. The x86
cleanup is making use of it.


New implementation:
-------------------

I've implemented a sane allocator which fixes the above short comings
(though migration of active descriptors still needs a full tree wide
cleanup of the direct and mostly unlocked access to irq_desc).

The new allocator still uses a radix_tree, but uses a bitmap for
keeping track of allocated irq numbers. That results in:

 - Fast lookup of a free slot

 - The removal of disposed descriptors (destroy_irq())

 - Prevents the create/destroy race

 - Bulk (de)allocation of consecutive irq ranges

 - Migration of life descriptors after further cleanups

The bitmap is also used in the SPARSE_IRQ=n case for lookup and
raceless (de)allocation of irq numbers. So it removes the requirement
for looping through the descriptor array to find slots.

Right now it uses sparse_irq_lock to protect the bitmap and the radix
tree, but after cleaning up all users we should be able to convert
that to a mutex and switch the radix_tree and descriptor allocations
to GFP_KERNEL.

Note, that I wanted to use lib/idr.c code for it, but idr/ida lacks
bulk allocation and a bitmap based iterator function, so I decided to
open code it for now. That's definitely something which could be
useful for others as well, but I have only a limited coding power.

There are some trivial preparatory patches as well, which touch places
all over the tree to make the conversion and cleanup simpler.


Full conversion and clean up of x86:
------------------------------------

I spent quite a time to come up with a sane and splitable concept,
which does not reach out into drivers/pci/[msi|ht|dmar] and whatever.

But that's simply impossible because everything is twisted together
mainly by optimization hacks done over time. (i.e. handing down
irq_desc to low level msi functions instead of irq_desc.msi_desc would
have kept the mess confined to x86).

So I went there and started to convert stuff piece by piece in x86 and
added the drivers/pci/* fixes as separate patches along the way. Not
nice, but it turned out to be the only way which avoided even more
churn.


Cleanup of leftovers:
---------------------

The leftovers (powerpc, arm, sh) have been converted with minimal
effort to allow the removal of the core code gunk. Not urgent stuff

There are more things which might be cleaned up, but that's not the
scope of this work.


Further work:
-------------

 - Cleanup the irq_desc references all over the tree, which should become
   easier after the remaining __do_IRQ() users are gone.

 - Implement migration of active irq descriptors

 - Implement node bound late allocation of low level irq vectors which
   solves an existing (SGI) problem on large machines.


How to merge:
-------------

It needs:

   - ack to the new allocator design

   - ack to merge the whole arch/!x86 and driver related cleanups
     along with the core changes and the x86 cleanup


Thoughts ?

Thanks,

	tglx
---

 b/Documentation/DocBook/genericirq.tmpl  |   82 +--
 b/arch/arm/include/asm/hw_irq.h          |    2 
 b/arch/arm/kernel/irq.c                  |   30 -
 b/arch/arm/mach-davinci/gpio.c           |    2 
 b/arch/arm/mach-iop13xx/msi.c            |    8 
 b/arch/ia64/kernel/msi_ia64.c            |    8 
 b/arch/ia64/sn/kernel/msi_sn.c           |    4 
 b/arch/powerpc/include/asm/hw_irq.h      |    2 
 b/arch/powerpc/kernel/irq.c              |   32 -
 b/arch/powerpc/platforms/cell/axon_msi.c |    6 
 b/arch/powerpc/platforms/pseries/xics.c  |    2 
 b/arch/powerpc/sysdev/fsl_msi.c          |    4 
 b/arch/powerpc/sysdev/mpic_pasemi_msi.c  |   22 
 b/arch/powerpc/sysdev/mpic_u3msi.c       |   16 
 b/arch/sh/kernel/cpu/irq/ipr.c           |    6 
 b/arch/sh/kernel/irq.c                   |    2 
 b/arch/sparc/kernel/pci_msi.c            |    8 
 b/arch/x86/Kconfig                       |    1 
 b/arch/x86/include/asm/hpet.h            |   10 
 b/arch/x86/include/asm/hw_irq.h          |    7 
 b/arch/x86/include/asm/i8259.h           |    2 
 b/arch/x86/kernel/apb_timer.c            |   54 --
 b/arch/x86/kernel/apic/io_apic.c         |  812 +++++++++++--------------------
 b/arch/x86/kernel/apic/nmi.c             |    2 
 b/arch/x86/kernel/hpet.c                 |   18 
 b/arch/x86/kernel/i8259.c                |   63 +-
 b/arch/x86/kernel/irqinit.c              |   17 
 b/arch/x86/kernel/smpboot.c              |    4 
 b/arch/x86/kernel/uv_irq.c               |   55 --
 b/arch/x86/kernel/visws_quirks.c         |  140 +----
 b/arch/x86/lguest/boot.c                 |   18 
 b/drivers/isdn/hisax/config.c            |   18 
 b/drivers/isdn/hisax/hisax.h             |    1 
 b/drivers/pci/dmar.c                     |    8 
 b/drivers/pci/htirq.c                    |   22 
 b/drivers/pci/msi.c                      |   38 -
 b/drivers/sh/intc.c                      |   37 -
 b/drivers/xen/events.c                   |   23 
 b/include/linux/dmar.h                   |    5 
 b/include/linux/htirq.h                  |    5 
 b/include/linux/interrupt.h              |    3 
 b/include/linux/irq.h                    |  195 +++----
 b/include/linux/irqnr.h                  |    5 
 b/include/linux/lockdep.h                |    8 
 b/include/linux/msi.h                    |   13 
 b/init/main.c                            |    1 
 b/kernel/irq/Kconfig                     |    5 
 b/kernel/irq/Makefile                    |    3 
 b/kernel/irq/chip.c                      |  138 -----
 b/kernel/irq/dummychip.c                 |   67 ++
 b/kernel/irq/handle.c                    |  344 -------------
 b/kernel/irq/internals.h                 |   11 
 b/kernel/irq/irqdesc.c                   |  377 ++++++++++++++
 b/kernel/irq/proc.c                      |   18 
 b/kernel/softirq.c                       |    7 
 kernel/irq/numa_migrate.c                |  120 ----
 56 files changed, 1229 insertions(+), 1682 deletions(-)

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

* [patch 01/47] x86: Plug memory leak in sparse irq
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
@ 2010-09-30 23:14 ` Thomas Gleixner
  2010-09-30 23:14 ` [patch 02/47] x86: Hpet: Fix bogus error check in hpet_assign_irq() Thomas Gleixner
                   ` (49 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman,
	Yinghai Lu, stable

[-- Attachment #1: x86-plug-memory-leak-in-sparse-irq.patch --]
[-- Type: text/plain, Size: 1477 bytes --]

free_irq_cfg() is not freeing the cpumask_vars in irq_cfg. Fixing this
triggers a use after free caused by the fact that copying struct
irq_cfg is done with memcpy, which copies the pointer not the cpumask.

Fix both places.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Yinghai Lu <yhlu.kernel@gmail.com>
LKML-Reference: <alpine.LFD.2.00.1009282052570.2416@localhost6.localdomain6>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@kernel.org
---
 arch/x86/kernel/apic/io_apic.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -307,14 +307,19 @@ void arch_init_copy_chip_data(struct irq
 
 	old_cfg = get_irq_desc_chip_data(old_desc);
 
-	memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
+	cfg->vector = old_cfg->vector;
+	cfg->move_in_progress = old_cfg->move_in_progress;
+	cpumask_copy(cfg->domain, old_cfg->domain);
+	cpumask_copy(cfg->old_domain, old_cfg->old_domain);
 
 	init_copy_irq_2_pin(old_cfg, cfg, node);
 }
 
-static void free_irq_cfg(struct irq_cfg *old_cfg)
+static void free_irq_cfg(struct irq_cfg *cfg)
 {
-	kfree(old_cfg);
+	free_cpumask_var(cfg->domain);
+	free_cpumask_var(cfg->old_domain);
+	kfree(cfg);
 }
 
 void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)

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

* [patch 02/47] x86: Hpet: Fix bogus error check in hpet_assign_irq()
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
  2010-09-30 23:14 ` [patch 01/47] x86: Plug memory leak in sparse irq Thomas Gleixner
@ 2010-09-30 23:14 ` Thomas Gleixner
  2010-09-30 23:14   ` Thomas Gleixner
  2010-09-30 23:14 ` [patch 03/47] genirq: Provide status modifier Thomas Gleixner
                   ` (48 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman,
	Venkatesh Pallipadi, stable

[-- Attachment #1: x86-hpet-fix-bogus-error-check-in-hpet_assign_irq.patch --]
[-- Type: text/plain, Size: 775 bytes --]

create_irq() returns -1 if the interrupt allocation failed, but the
code checks for irq == 0.

Use create_irq_nr() instead.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Venkatesh Pallipadi <venki@google.com>
LKML-Reference: <alpine.LFD.2.00.1009282310360.2416@localhost6.localdomain6>
Cc: stable@kernel.org
---
 arch/x86/kernel/hpet.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6-tip/arch/x86/kernel/hpet.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/hpet.c
+++ linux-2.6-tip/arch/x86/kernel/hpet.c
@@ -506,7 +506,7 @@ static int hpet_assign_irq(struct hpet_d
 {
 	unsigned int irq;
 
-	irq = create_irq();
+	irq = create_irq_nr(0, -1);
 	if (!irq)
 		return -EINVAL;
 

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

* [patch 02/47] x86: Hpet: Fix bogus error check in hpet_assign_irq()
  2010-09-30 23:14 ` [patch 02/47] x86: Hpet: Fix bogus error check in hpet_assign_irq() Thomas Gleixner
@ 2010-09-30 23:14   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman,
	Venkatesh Pallipadi, stable

[-- Attachment #1: x86-hpet-fix-bogus-error-check-in-hpet_assign_irq.patch --]
[-- Type: text/plain, Size: 777 bytes --]

create_irq() returns -1 if the interrupt allocation failed, but the
code checks for irq == 0.

Use create_irq_nr() instead.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Venkatesh Pallipadi <venki@google.com>
LKML-Reference: <alpine.LFD.2.00.1009282310360.2416@localhost6.localdomain6>
Cc: stable@kernel.org
---
 arch/x86/kernel/hpet.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6-tip/arch/x86/kernel/hpet.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/hpet.c
+++ linux-2.6-tip/arch/x86/kernel/hpet.c
@@ -506,7 +506,7 @@ static int hpet_assign_irq(struct hpet_d
 {
 	unsigned int irq;
 
-	irq = create_irq();
+	irq = create_irq_nr(0, -1);
 	if (!irq)
 		return -EINVAL;
 



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

* [patch 03/47] genirq: Provide status modifier
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
  2010-09-30 23:14 ` [patch 01/47] x86: Plug memory leak in sparse irq Thomas Gleixner
  2010-09-30 23:14 ` [patch 02/47] x86: Hpet: Fix bogus error check in hpet_assign_irq() Thomas Gleixner
@ 2010-09-30 23:14 ` Thomas Gleixner
  2010-09-30 23:14   ` Thomas Gleixner
  2010-09-30 23:14 ` [patch 04/47] arm: Use irq " Thomas Gleixner
                   ` (47 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-provide-status-modifier.patch --]
[-- Type: text/plain, Size: 3091 bytes --]

Provide a irq_desc.status modifier function to cleanup the direct
access to irq_desc in arch and driver code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h |   27 +++++++++++++++++++++++++--
 kernel/irq/chip.c   |   26 +++++++-------------------
 2 files changed, 32 insertions(+), 21 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -72,6 +72,10 @@ typedef	void (*irq_flow_handler_t)(unsig
 #define IRQ_ONESHOT		0x08000000	/* IRQ is not unmasked after hardirq */
 #define IRQ_NESTED_THREAD	0x10000000	/* IRQ is nested into another, no own handler thread */
 
+#define IRQF_MODIFY_MASK	\
+	(IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
+	 IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL)
+
 #ifdef CONFIG_IRQ_PER_CPU
 # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
 # define IRQ_NO_BALANCING_MASK	(IRQ_PER_CPU | IRQ_NO_BALANCING)
@@ -428,8 +432,27 @@ set_irq_chained_handler(unsigned int irq
 
 extern void set_irq_nested_thread(unsigned int irq, int nest);
 
-extern void set_irq_noprobe(unsigned int irq);
-extern void set_irq_probe(unsigned int irq);
+void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
+
+static inline void irq_set_status_flags(unsigned int irq, unsigned long set)
+{
+	irq_modify_status(irq, 0, set);
+}
+
+static inline void irq_clear_status_flags(unsigned int irq, unsigned long clr)
+{
+	irq_modify_status(irq, clr, 0);
+}
+
+static inline void set_irq_noprobe(unsigned int irq)
+{
+	irq_modify_status(irq, 0, IRQ_NOPROBE);
+}
+
+static inline void set_irq_probe(unsigned int irq)
+{
+	irq_modify_status(irq, IRQ_NOPROBE, 0);
+}
 
 /* Handle dynamic irq creation and destruction */
 extern unsigned int create_irq_nr(unsigned int irq_want, int node);
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -849,32 +849,20 @@ set_irq_chip_and_handler_name(unsigned i
 	__set_irq_handler(irq, handle, 0, name);
 }
 
-void set_irq_noprobe(unsigned int irq)
+void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned long flags;
 
-	if (!desc) {
-		printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
+	if (!desc)
 		return;
-	}
 
-	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status |= IRQ_NOPROBE;
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-void set_irq_probe(unsigned int irq)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	unsigned long flags;
-
-	if (!desc) {
-		printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
-		return;
-	}
+	/* Sanitize flags */
+	set &= IRQF_MODIFY_MASK;
+	clr &= IRQF_MODIFY_MASK;
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status &= ~IRQ_NOPROBE;
+	desc->status &= ~clr;
+	desc->status |= set;
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }

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

* [patch 03/47] genirq: Provide status modifier
  2010-09-30 23:14 ` [patch 03/47] genirq: Provide status modifier Thomas Gleixner
@ 2010-09-30 23:14   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-provide-status-modifier.patch --]
[-- Type: text/plain, Size: 3093 bytes --]

Provide a irq_desc.status modifier function to cleanup the direct
access to irq_desc in arch and driver code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h |   27 +++++++++++++++++++++++++--
 kernel/irq/chip.c   |   26 +++++++-------------------
 2 files changed, 32 insertions(+), 21 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -72,6 +72,10 @@ typedef	void (*irq_flow_handler_t)(unsig
 #define IRQ_ONESHOT		0x08000000	/* IRQ is not unmasked after hardirq */
 #define IRQ_NESTED_THREAD	0x10000000	/* IRQ is nested into another, no own handler thread */
 
+#define IRQF_MODIFY_MASK	\
+	(IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
+	 IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL)
+
 #ifdef CONFIG_IRQ_PER_CPU
 # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
 # define IRQ_NO_BALANCING_MASK	(IRQ_PER_CPU | IRQ_NO_BALANCING)
@@ -428,8 +432,27 @@ set_irq_chained_handler(unsigned int irq
 
 extern void set_irq_nested_thread(unsigned int irq, int nest);
 
-extern void set_irq_noprobe(unsigned int irq);
-extern void set_irq_probe(unsigned int irq);
+void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
+
+static inline void irq_set_status_flags(unsigned int irq, unsigned long set)
+{
+	irq_modify_status(irq, 0, set);
+}
+
+static inline void irq_clear_status_flags(unsigned int irq, unsigned long clr)
+{
+	irq_modify_status(irq, clr, 0);
+}
+
+static inline void set_irq_noprobe(unsigned int irq)
+{
+	irq_modify_status(irq, 0, IRQ_NOPROBE);
+}
+
+static inline void set_irq_probe(unsigned int irq)
+{
+	irq_modify_status(irq, IRQ_NOPROBE, 0);
+}
 
 /* Handle dynamic irq creation and destruction */
 extern unsigned int create_irq_nr(unsigned int irq_want, int node);
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -849,32 +849,20 @@ set_irq_chip_and_handler_name(unsigned i
 	__set_irq_handler(irq, handle, 0, name);
 }
 
-void set_irq_noprobe(unsigned int irq)
+void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned long flags;
 
-	if (!desc) {
-		printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
+	if (!desc)
 		return;
-	}
 
-	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status |= IRQ_NOPROBE;
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-void set_irq_probe(unsigned int irq)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	unsigned long flags;
-
-	if (!desc) {
-		printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
-		return;
-	}
+	/* Sanitize flags */
+	set &= IRQF_MODIFY_MASK;
+	clr &= IRQF_MODIFY_MASK;
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status &= ~IRQ_NOPROBE;
+	desc->status &= ~clr;
+	desc->status |= set;
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }



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

* [patch 04/47] arm: Use irq status modifier
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (2 preceding siblings ...)
  2010-09-30 23:14 ` [patch 03/47] genirq: Provide status modifier Thomas Gleixner
@ 2010-09-30 23:14 ` Thomas Gleixner
  2010-09-30 23:14   ` Thomas Gleixner
  2010-09-30 23:14 ` [patch 05/47] genirq-sanitize-irq-data-accessors.patch Thomas Gleixner
                   ` (46 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: arm-use-status-modifier.patch --]
[-- Type: text/plain, Size: 1309 bytes --]

Replace the open coded unlocked access to irq_desc.status

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

Index: linux-2.6-tip/arch/arm/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/kernel/irq.c
+++ linux-2.6-tip/arch/arm/kernel/irq.c
@@ -132,24 +132,18 @@ asmlinkage void __exception asm_do_IRQ(u
 
 void set_irq_flags(unsigned int irq, unsigned int iflags)
 {
-	struct irq_desc *desc;
-	unsigned long flags;
+	unsigned long clr = 0;
 
-	if (irq >= nr_irqs) {
-		printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
-		return;
-	}
+	irq_set_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN);
 
-	desc = irq_to_desc(irq);
-	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
 	if (iflags & IRQF_VALID)
-		desc->status &= ~IRQ_NOREQUEST;
+		clr |= IRQ_NOREQUEST;
 	if (iflags & IRQF_PROBE)
-		desc->status &= ~IRQ_NOPROBE;
+		clr |= IRQ_NOPROBE;
 	if (!(iflags & IRQF_NOAUTOEN))
-		desc->status &= ~IRQ_NOAUTOEN;
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
+		clr |= IRQ_NOAUTOEN;
+
+	irq_clear_status_flags(irq, clr);
 }
 
 void __init init_IRQ(void)

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

* [patch 04/47] arm: Use irq status modifier
  2010-09-30 23:14 ` [patch 04/47] arm: Use irq " Thomas Gleixner
@ 2010-09-30 23:14   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: arm-use-status-modifier.patch --]
[-- Type: text/plain, Size: 1311 bytes --]

Replace the open coded unlocked access to irq_desc.status

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

Index: linux-2.6-tip/arch/arm/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/kernel/irq.c
+++ linux-2.6-tip/arch/arm/kernel/irq.c
@@ -132,24 +132,18 @@ asmlinkage void __exception asm_do_IRQ(u
 
 void set_irq_flags(unsigned int irq, unsigned int iflags)
 {
-	struct irq_desc *desc;
-	unsigned long flags;
+	unsigned long clr = 0;
 
-	if (irq >= nr_irqs) {
-		printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
-		return;
-	}
+	irq_set_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN);
 
-	desc = irq_to_desc(irq);
-	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
 	if (iflags & IRQF_VALID)
-		desc->status &= ~IRQ_NOREQUEST;
+		clr |= IRQ_NOREQUEST;
 	if (iflags & IRQF_PROBE)
-		desc->status &= ~IRQ_NOPROBE;
+		clr |= IRQ_NOPROBE;
 	if (!(iflags & IRQF_NOAUTOEN))
-		desc->status &= ~IRQ_NOAUTOEN;
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
+		clr |= IRQ_NOAUTOEN;
+
+	irq_clear_status_flags(irq, clr);
 }
 
 void __init init_IRQ(void)



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

* [patch 05/47] genirq-sanitize-irq-data-accessors.patch
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (3 preceding siblings ...)
  2010-09-30 23:14 ` [patch 04/47] arm: Use irq " Thomas Gleixner
@ 2010-09-30 23:14 ` Thomas Gleixner
  2010-09-30 23:14   ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 06/47] genirq: Distangle kernel/irq/handle.c Thomas Gleixner
                   ` (45 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-sanitize-irq-data-accessors.patch --]
[-- Type: text/plain, Size: 2442 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h |   31 ++++++++++++++++++++++++++-----
 kernel/irq/chip.c   |    8 ++++++++
 2 files changed, 34 insertions(+), 5 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -478,17 +478,38 @@ extern int set_irq_data(unsigned int irq
 extern int set_irq_chip_data(unsigned int irq, void *data);
 extern int set_irq_type(unsigned int irq, unsigned int type);
 extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
+extern struct irq_data *irq_get_irq_data(unsigned int irq);
 
+static inline struct irq_chip *get_irq_chip(unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	return d ? d->chip : NULL;
+}
+
+static inline void *get_irq_chip_data(unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	return d ? d->chip_data : NULL;
+}
+
+static inline void *get_irq_data(unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	return d ? d->handler_data : NULL;
+}
+
+static inline struct msi_desc *get_irq_msi(unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	return d ? d->msi_desc : NULL;
+}
+
+/* Needs to die ! */
 static inline void set_irq_desc_chip_data(struct irq_desc *desc, void *data)
 {
 	desc->irq_data.chip_data = data;
 }
 
-#define get_irq_chip(irq)	(irq_to_desc(irq)->chip)
-#define get_irq_chip_data(irq)	(irq_to_desc(irq)->irq_data.chip_data)
-#define get_irq_data(irq)	(irq_to_desc(irq)->irq_data.handler_data)
-#define get_irq_msi(irq)	(irq_to_desc(irq)->irq_data.msi_desc)
-
 #define get_irq_desc_chip(desc)		((desc)->irq_data.chip)
 #define get_irq_desc_chip_data(desc)	((desc)->irq_data.chip_data)
 #define get_irq_desc_data(desc)		((desc)->irq_data.handler_data)
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -259,6 +259,14 @@ int set_irq_chip_data(unsigned int irq, 
 }
 EXPORT_SYMBOL(set_irq_chip_data);
 
+struct irq_data *irq_get_irq_data(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	return desc ? &desc->irq_data : NULL;
+}
+EXPORT_SYMBOL_GPL(irq_get_irq_data);
+
 /**
  *	set_irq_nested_thread - Set/Reset the IRQ_NESTED_THREAD flag of an irq
  *

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

* [patch 05/47] genirq-sanitize-irq-data-accessors.patch
  2010-09-30 23:14 ` [patch 05/47] genirq-sanitize-irq-data-accessors.patch Thomas Gleixner
@ 2010-09-30 23:14   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:14 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-sanitize-irq-data-accessors.patch --]
[-- Type: text/plain, Size: 2444 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h |   31 ++++++++++++++++++++++++++-----
 kernel/irq/chip.c   |    8 ++++++++
 2 files changed, 34 insertions(+), 5 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -478,17 +478,38 @@ extern int set_irq_data(unsigned int irq
 extern int set_irq_chip_data(unsigned int irq, void *data);
 extern int set_irq_type(unsigned int irq, unsigned int type);
 extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
+extern struct irq_data *irq_get_irq_data(unsigned int irq);
 
+static inline struct irq_chip *get_irq_chip(unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	return d ? d->chip : NULL;
+}
+
+static inline void *get_irq_chip_data(unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	return d ? d->chip_data : NULL;
+}
+
+static inline void *get_irq_data(unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	return d ? d->handler_data : NULL;
+}
+
+static inline struct msi_desc *get_irq_msi(unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	return d ? d->msi_desc : NULL;
+}
+
+/* Needs to die ! */
 static inline void set_irq_desc_chip_data(struct irq_desc *desc, void *data)
 {
 	desc->irq_data.chip_data = data;
 }
 
-#define get_irq_chip(irq)	(irq_to_desc(irq)->chip)
-#define get_irq_chip_data(irq)	(irq_to_desc(irq)->irq_data.chip_data)
-#define get_irq_data(irq)	(irq_to_desc(irq)->irq_data.handler_data)
-#define get_irq_msi(irq)	(irq_to_desc(irq)->irq_data.msi_desc)
-
 #define get_irq_desc_chip(desc)		((desc)->irq_data.chip)
 #define get_irq_desc_chip_data(desc)	((desc)->irq_data.chip_data)
 #define get_irq_desc_data(desc)		((desc)->irq_data.handler_data)
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -259,6 +259,14 @@ int set_irq_chip_data(unsigned int irq, 
 }
 EXPORT_SYMBOL(set_irq_chip_data);
 
+struct irq_data *irq_get_irq_data(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	return desc ? &desc->irq_data : NULL;
+}
+EXPORT_SYMBOL_GPL(irq_get_irq_data);
+
 /**
  *	set_irq_nested_thread - Set/Reset the IRQ_NESTED_THREAD flag of an irq
  *



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

* [patch 06/47] genirq: Distangle kernel/irq/handle.c
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (4 preceding siblings ...)
  2010-09-30 23:14 ` [patch 05/47] genirq-sanitize-irq-data-accessors.patch Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 07/47] genirq: Remove early_init_irq_lock_class() Thomas Gleixner
                   ` (44 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-move-irqdesc-management-to-separate-file.patch --]
[-- Type: text/plain, Size: 18307 bytes --]

kernel/irq/handle.c has become a dumpground for random code in random
order. Split out the irq descriptor management and the dummy irq_chip
implementation into separate files. Cleanup the include maze while at
it.

No code change.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/Makefile    |    2 
 kernel/irq/dummychip.c |   67 +++++++++
 kernel/irq/handle.c    |  344 -------------------------------------------------
 kernel/irq/irqdesc.c   |  281 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 351 insertions(+), 343 deletions(-)

Index: linux-2.6-tip/kernel/irq/Makefile
===================================================================
--- linux-2.6-tip.orig/kernel/irq/Makefile
+++ linux-2.6-tip/kernel/irq/Makefile
@@ -1,5 +1,5 @@
 
-obj-y := handle.o manage.o spurious.o resend.o chip.o devres.o
+obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o
 obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
Index: linux-2.6-tip/kernel/irq/dummychip.c
===================================================================
--- /dev/null
+++ linux-2.6-tip/kernel/irq/dummychip.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
+ *
+ * This file contains the dummy interrupt chip implementation
+ */
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include "internals.h"
+
+/*
+ * What should we do if we get a hw irq event on an illegal vector?
+ * Each architecture has to answer this themself.
+ */
+static void ack_bad(struct irq_data *data)
+{
+	struct irq_desc *desc = irq_data_to_desc(data);
+
+	print_irq_desc(data->irq, desc);
+	ack_bad_irq(data->irq);
+}
+
+/*
+ * NOP functions
+ */
+static void noop(struct irq_data *data)
+{
+}
+
+static unsigned int noop_ret(struct irq_data *data)
+{
+	return 0;
+}
+
+static void compat_noop(unsigned int irq)
+{
+}
+
+/*
+ * Generic no controller implementation
+ */
+struct irq_chip no_irq_chip = {
+	.name		= "none",
+	.irq_startup	= noop_ret,
+	.irq_shutdown	= noop,
+	.irq_enable	= noop,
+	.irq_disable	= noop,
+	.irq_ack	= ack_bad,
+	.end		= compat_noop,
+};
+
+/*
+ * Generic dummy implementation which can be used for
+ * real dumb interrupt sources
+ */
+struct irq_chip dummy_irq_chip = {
+	.name		= "dummy",
+	.irq_startup	= noop_ret,
+	.irq_shutdown	= noop,
+	.irq_enable	= noop,
+	.irq_disable	= noop,
+	.irq_ack	= noop,
+	.irq_mask	= noop,
+	.irq_unmask	= noop,
+	.end		= compat_noop,
+};
Index: linux-2.6-tip/kernel/irq/handle.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/handle.c
+++ linux-2.6-tip/kernel/irq/handle.c
@@ -11,24 +11,15 @@
  */
 
 #include <linux/irq.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/module.h>
 #include <linux/random.h>
+#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
-#include <linux/rculist.h>
-#include <linux/hash.h>
-#include <linux/radix-tree.h>
+
 #include <trace/events/irq.h>
 
 #include "internals.h"
 
-/*
- * lockdep: we want to handle all irq_desc locks as a single lock-class:
- */
-struct lock_class_key irq_desc_lock_class;
-
 /**
  * handle_bad_irq - handle spurious and unhandled irqs
  * @irq:       the interrupt number
@@ -43,319 +34,6 @@ void handle_bad_irq(unsigned int irq, st
 	ack_bad_irq(irq);
 }
 
-#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
-static void __init init_irq_default_affinity(void)
-{
-	alloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
-	cpumask_setall(irq_default_affinity);
-}
-#else
-static void __init init_irq_default_affinity(void)
-{
-}
-#endif
-
-/*
- * Linux has a controller-independent interrupt architecture.
- * Every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the appropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * The code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic or
- * having to touch the generic code.
- *
- * Controller mappings for all interrupt sources:
- */
-int nr_irqs = NR_IRQS;
-EXPORT_SYMBOL_GPL(nr_irqs);
-
-#ifdef CONFIG_SPARSE_IRQ
-
-static struct irq_desc irq_desc_init = {
-	.irq	    = -1,
-	.status	    = IRQ_DISABLED,
-	.chip	    = &no_irq_chip,
-	.handle_irq = handle_bad_irq,
-	.depth      = 1,
-	.lock       = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-};
-
-void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
-{
-	void *ptr;
-
-	ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
-			   GFP_ATOMIC, node);
-
-	/*
-	 * don't overwite if can not get new one
-	 * init_copy_kstat_irqs() could still use old one
-	 */
-	if (ptr) {
-		printk(KERN_DEBUG "  alloc kstat_irqs on node %d\n", node);
-		desc->kstat_irqs = ptr;
-	}
-}
-
-static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
-{
-	memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
-
-	raw_spin_lock_init(&desc->lock);
-	desc->irq = irq;
-	desc->irq_data.irq = irq;
-	desc->irq_data.chip = desc->chip;
-#ifdef CONFIG_SMP
-	desc->node = node;
-	desc->irq_data.affinity = &desc->affinity;
-#endif
-	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	init_kstat_irqs(desc, node, nr_cpu_ids);
-	if (!desc->kstat_irqs) {
-		printk(KERN_ERR "can not alloc kstat_irqs\n");
-		BUG_ON(1);
-	}
-	if (!alloc_desc_masks(desc, node, false)) {
-		printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
-		BUG_ON(1);
-	}
-	init_desc_masks(desc);
-	arch_init_chip_data(desc, node);
-}
-
-/*
- * Protect the sparse_irqs:
- */
-DEFINE_RAW_SPINLOCK(sparse_irq_lock);
-
-static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
-
-static void set_irq_desc(unsigned int irq, struct irq_desc *desc)
-{
-	radix_tree_insert(&irq_desc_tree, irq, desc);
-}
-
-struct irq_desc *irq_to_desc(unsigned int irq)
-{
-	return radix_tree_lookup(&irq_desc_tree, irq);
-}
-
-void replace_irq_desc(unsigned int irq, struct irq_desc *desc)
-{
-	void **ptr;
-
-	ptr = radix_tree_lookup_slot(&irq_desc_tree, irq);
-	if (ptr)
-		radix_tree_replace_slot(ptr, desc);
-}
-
-static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
-	[0 ... NR_IRQS_LEGACY-1] = {
-		.irq	    = -1,
-		.status	    = IRQ_DISABLED,
-		.chip	    = &no_irq_chip,
-		.handle_irq = handle_bad_irq,
-		.depth	    = 1,
-		.lock	    = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-	}
-};
-
-static unsigned int *kstat_irqs_legacy;
-
-int __init early_irq_init(void)
-{
-	struct irq_desc *desc;
-	int legacy_count;
-	int node;
-	int i;
-
-	init_irq_default_affinity();
-
-	 /* initialize nr_irqs based on nr_cpu_ids */
-	arch_probe_nr_irqs();
-	printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
-
-	desc = irq_desc_legacy;
-	legacy_count = ARRAY_SIZE(irq_desc_legacy);
-	node = first_online_node;
-
-	/* allocate based on nr_cpu_ids */
-	kstat_irqs_legacy = kzalloc_node(NR_IRQS_LEGACY * nr_cpu_ids *
-					  sizeof(int), GFP_NOWAIT, node);
-
-	for (i = 0; i < legacy_count; i++) {
-		desc[i].irq = i;
-		desc[i].irq_data.irq = i;
-		desc[i].irq_data.chip = desc[i].chip;
-#ifdef CONFIG_SMP
-		desc[i].node = node;
-		desc[i].irq_data.affinity = &desc[i].affinity;
-#endif
-		desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
-		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
-		alloc_desc_masks(&desc[i], node, true);
-		init_desc_masks(&desc[i]);
-		set_irq_desc(i, &desc[i]);
-	}
-
-	return arch_early_irq_init();
-}
-
-struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
-{
-	struct irq_desc *desc;
-	unsigned long flags;
-
-	if (irq >= nr_irqs) {
-		WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
-			irq, nr_irqs);
-		return NULL;
-	}
-
-	desc = irq_to_desc(irq);
-	if (desc)
-		return desc;
-
-	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
-
-	/* We have to check it to avoid races with another CPU */
-	desc = irq_to_desc(irq);
-	if (desc)
-		goto out_unlock;
-
-	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
-
-	printk(KERN_DEBUG "  alloc irq_desc for %d on node %d\n", irq, node);
-	if (!desc) {
-		printk(KERN_ERR "can not alloc irq_desc\n");
-		BUG_ON(1);
-	}
-	init_one_irq_desc(irq, desc, node);
-
-	set_irq_desc(irq, desc);
-
-out_unlock:
-	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
-
-	return desc;
-}
-
-#else /* !CONFIG_SPARSE_IRQ */
-
-struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
-	[0 ... NR_IRQS-1] = {
-		.status = IRQ_DISABLED,
-		.chip = &no_irq_chip,
-		.handle_irq = handle_bad_irq,
-		.depth = 1,
-		.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
-	}
-};
-
-static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
-int __init early_irq_init(void)
-{
-	struct irq_desc *desc;
-	int count;
-	int i;
-
-	init_irq_default_affinity();
-
-	printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);
-
-	desc = irq_desc;
-	count = ARRAY_SIZE(irq_desc);
-
-	for (i = 0; i < count; i++) {
-		desc[i].irq = i;
-		desc[i].irq_data.irq = i;
-		desc[i].irq_data.chip = desc[i].chip;
-#ifdef CONFIG_SMP
-		desc[i].irq_data.affinity = &desc[i].affinity;
-#endif
-		alloc_desc_masks(&desc[i], 0, true);
-		init_desc_masks(&desc[i]);
-		desc[i].kstat_irqs = kstat_irqs_all[i];
-	}
-	return arch_early_irq_init();
-}
-
-struct irq_desc *irq_to_desc(unsigned int irq)
-{
-	return (irq < NR_IRQS) ? irq_desc + irq : NULL;
-}
-
-struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
-{
-	return irq_to_desc(irq);
-}
-#endif /* !CONFIG_SPARSE_IRQ */
-
-void clear_kstat_irqs(struct irq_desc *desc)
-{
-	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
-}
-
-/*
- * What should we do if we get a hw irq event on an illegal vector?
- * Each architecture has to answer this themself.
- */
-static void ack_bad(struct irq_data *data)
-{
-	struct irq_desc *desc = irq_data_to_desc(data);
-
-	print_irq_desc(data->irq, desc);
-	ack_bad_irq(data->irq);
-}
-
-/*
- * NOP functions
- */
-static void noop(struct irq_data *data)
-{
-}
-
-static unsigned int noop_ret(struct irq_data *data)
-{
-	return 0;
-}
-
-static void compat_noop(unsigned int irq)
-{
-}
-
-/*
- * Generic no controller implementation
- */
-struct irq_chip no_irq_chip = {
-	.name		= "none",
-	.irq_startup	= noop_ret,
-	.irq_shutdown	= noop,
-	.irq_enable	= noop,
-	.irq_disable	= noop,
-	.irq_ack	= ack_bad,
-	.end		= compat_noop,
-};
-
-/*
- * Generic dummy implementation which can be used for
- * real dumb interrupt sources
- */
-struct irq_chip dummy_irq_chip = {
-	.name		= "dummy",
-	.irq_startup	= noop_ret,
-	.irq_shutdown	= noop,
-	.irq_enable	= noop,
-	.irq_disable	= noop,
-	.irq_ack	= noop,
-	.irq_mask	= noop,
-	.irq_unmask	= noop,
-	.end		= compat_noop,
-};
-
 /*
  * Special, empty irq handler:
  */
@@ -551,21 +229,3 @@ out:
 	return 1;
 }
 #endif
-
-void early_init_irq_lock_class(void)
-{
-	struct irq_desc *desc;
-	int i;
-
-	for_each_irq_desc(i, desc) {
-		lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	}
-}
-
-unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	return desc ? desc->kstat_irqs[cpu] : 0;
-}
-EXPORT_SYMBOL(kstat_irqs_cpu);
-
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- /dev/null
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
+ *
+ * This file contains the interrupt descriptor management code
+ *
+ * Detailed information is available in Documentation/DocBook/genericirq
+ *
+ */
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/radix-tree.h>
+
+#include "internals.h"
+
+/*
+ * lockdep: we want to handle all irq_desc locks as a single lock-class:
+ */
+struct lock_class_key irq_desc_lock_class;
+
+#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
+static void __init init_irq_default_affinity(void)
+{
+	alloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
+	cpumask_setall(irq_default_affinity);
+}
+#else
+static void __init init_irq_default_affinity(void)
+{
+}
+#endif
+
+int nr_irqs = NR_IRQS;
+EXPORT_SYMBOL_GPL(nr_irqs);
+
+#ifdef CONFIG_SPARSE_IRQ
+
+static struct irq_desc irq_desc_init = {
+	.irq	    = -1,
+	.status	    = IRQ_DISABLED,
+	.chip	    = &no_irq_chip,
+	.handle_irq = handle_bad_irq,
+	.depth      = 1,
+	.lock       = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
+};
+
+void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
+{
+	void *ptr;
+
+	ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
+			   GFP_ATOMIC, node);
+
+	/*
+	 * don't overwite if can not get new one
+	 * init_copy_kstat_irqs() could still use old one
+	 */
+	if (ptr) {
+		printk(KERN_DEBUG "  alloc kstat_irqs on node %d\n", node);
+		desc->kstat_irqs = ptr;
+	}
+}
+
+static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
+{
+	memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
+
+	raw_spin_lock_init(&desc->lock);
+	desc->irq = irq;
+	desc->irq_data.irq = irq;
+	desc->irq_data.chip = desc->chip;
+#ifdef CONFIG_SMP
+	desc->node = node;
+	desc->irq_data.affinity = &desc->affinity;
+#endif
+	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
+	init_kstat_irqs(desc, node, nr_cpu_ids);
+	if (!desc->kstat_irqs) {
+		printk(KERN_ERR "can not alloc kstat_irqs\n");
+		BUG_ON(1);
+	}
+	if (!alloc_desc_masks(desc, node, false)) {
+		printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
+		BUG_ON(1);
+	}
+	init_desc_masks(desc);
+	arch_init_chip_data(desc, node);
+}
+
+/*
+ * Protect the sparse_irqs:
+ */
+DEFINE_RAW_SPINLOCK(sparse_irq_lock);
+
+static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
+
+static void set_irq_desc(unsigned int irq, struct irq_desc *desc)
+{
+	radix_tree_insert(&irq_desc_tree, irq, desc);
+}
+
+struct irq_desc *irq_to_desc(unsigned int irq)
+{
+	return radix_tree_lookup(&irq_desc_tree, irq);
+}
+
+void replace_irq_desc(unsigned int irq, struct irq_desc *desc)
+{
+	void **ptr;
+
+	ptr = radix_tree_lookup_slot(&irq_desc_tree, irq);
+	if (ptr)
+		radix_tree_replace_slot(ptr, desc);
+}
+
+static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
+	[0 ... NR_IRQS_LEGACY-1] = {
+		.irq	    = -1,
+		.status	    = IRQ_DISABLED,
+		.chip	    = &no_irq_chip,
+		.handle_irq = handle_bad_irq,
+		.depth	    = 1,
+		.lock	    = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
+	}
+};
+
+static unsigned int *kstat_irqs_legacy;
+
+int __init early_irq_init(void)
+{
+	struct irq_desc *desc;
+	int legacy_count;
+	int node;
+	int i;
+
+	init_irq_default_affinity();
+
+	 /* initialize nr_irqs based on nr_cpu_ids */
+	arch_probe_nr_irqs();
+	printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
+
+	desc = irq_desc_legacy;
+	legacy_count = ARRAY_SIZE(irq_desc_legacy);
+	node = first_online_node;
+
+	/* allocate based on nr_cpu_ids */
+	kstat_irqs_legacy = kzalloc_node(NR_IRQS_LEGACY * nr_cpu_ids *
+					  sizeof(int), GFP_NOWAIT, node);
+
+	for (i = 0; i < legacy_count; i++) {
+		desc[i].irq = i;
+		desc[i].irq_data.irq = i;
+		desc[i].irq_data.chip = desc[i].chip;
+#ifdef CONFIG_SMP
+		desc[i].node = node;
+		desc[i].irq_data.affinity = &desc[i].affinity;
+#endif
+		desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
+		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
+		alloc_desc_masks(&desc[i], node, true);
+		init_desc_masks(&desc[i]);
+		set_irq_desc(i, &desc[i]);
+	}
+
+	return arch_early_irq_init();
+}
+
+struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+
+	if (irq >= nr_irqs) {
+		WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
+			irq, nr_irqs);
+		return NULL;
+	}
+
+	desc = irq_to_desc(irq);
+	if (desc)
+		return desc;
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+
+	/* We have to check it to avoid races with another CPU */
+	desc = irq_to_desc(irq);
+	if (desc)
+		goto out_unlock;
+
+	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
+
+	printk(KERN_DEBUG "  alloc irq_desc for %d on node %d\n", irq, node);
+	if (!desc) {
+		printk(KERN_ERR "can not alloc irq_desc\n");
+		BUG_ON(1);
+	}
+	init_one_irq_desc(irq, desc, node);
+
+	set_irq_desc(irq, desc);
+
+out_unlock:
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+
+	return desc;
+}
+
+#else /* !CONFIG_SPARSE_IRQ */
+
+struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
+	[0 ... NR_IRQS-1] = {
+		.status = IRQ_DISABLED,
+		.chip = &no_irq_chip,
+		.handle_irq = handle_bad_irq,
+		.depth = 1,
+		.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
+	}
+};
+
+static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
+int __init early_irq_init(void)
+{
+	struct irq_desc *desc;
+	int count;
+	int i;
+
+	init_irq_default_affinity();
+
+	printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);
+
+	desc = irq_desc;
+	count = ARRAY_SIZE(irq_desc);
+
+	for (i = 0; i < count; i++) {
+		desc[i].irq = i;
+		desc[i].irq_data.irq = i;
+		desc[i].irq_data.chip = desc[i].chip;
+#ifdef CONFIG_SMP
+		desc[i].irq_data.affinity = &desc[i].affinity;
+#endif
+		alloc_desc_masks(&desc[i], 0, true);
+		init_desc_masks(&desc[i]);
+		desc[i].kstat_irqs = kstat_irqs_all[i];
+	}
+	return arch_early_irq_init();
+}
+
+struct irq_desc *irq_to_desc(unsigned int irq)
+{
+	return (irq < NR_IRQS) ? irq_desc + irq : NULL;
+}
+
+struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
+{
+	return irq_to_desc(irq);
+}
+#endif /* !CONFIG_SPARSE_IRQ */
+
+void clear_kstat_irqs(struct irq_desc *desc)
+{
+	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
+}
+
+void early_init_irq_lock_class(void)
+{
+	struct irq_desc *desc;
+	int i;
+
+	for_each_irq_desc(i, desc) {
+		lockdep_set_class(&desc->lock, &irq_desc_lock_class);
+	}
+}
+
+unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	return desc ? desc->kstat_irqs[cpu] : 0;
+}
+EXPORT_SYMBOL(kstat_irqs_cpu);

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

* [patch 06/47] genirq: Distangle kernel/irq/handle.c
  2010-09-30 23:15 ` [patch 06/47] genirq: Distangle kernel/irq/handle.c Thomas Gleixner
@ 2010-09-30 23:15   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-move-irqdesc-management-to-separate-file.patch --]
[-- Type: text/plain, Size: 18309 bytes --]

kernel/irq/handle.c has become a dumpground for random code in random
order. Split out the irq descriptor management and the dummy irq_chip
implementation into separate files. Cleanup the include maze while at
it.

No code change.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/Makefile    |    2 
 kernel/irq/dummychip.c |   67 +++++++++
 kernel/irq/handle.c    |  344 -------------------------------------------------
 kernel/irq/irqdesc.c   |  281 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 351 insertions(+), 343 deletions(-)

Index: linux-2.6-tip/kernel/irq/Makefile
===================================================================
--- linux-2.6-tip.orig/kernel/irq/Makefile
+++ linux-2.6-tip/kernel/irq/Makefile
@@ -1,5 +1,5 @@
 
-obj-y := handle.o manage.o spurious.o resend.o chip.o devres.o
+obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o
 obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
Index: linux-2.6-tip/kernel/irq/dummychip.c
===================================================================
--- /dev/null
+++ linux-2.6-tip/kernel/irq/dummychip.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
+ *
+ * This file contains the dummy interrupt chip implementation
+ */
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include "internals.h"
+
+/*
+ * What should we do if we get a hw irq event on an illegal vector?
+ * Each architecture has to answer this themself.
+ */
+static void ack_bad(struct irq_data *data)
+{
+	struct irq_desc *desc = irq_data_to_desc(data);
+
+	print_irq_desc(data->irq, desc);
+	ack_bad_irq(data->irq);
+}
+
+/*
+ * NOP functions
+ */
+static void noop(struct irq_data *data)
+{
+}
+
+static unsigned int noop_ret(struct irq_data *data)
+{
+	return 0;
+}
+
+static void compat_noop(unsigned int irq)
+{
+}
+
+/*
+ * Generic no controller implementation
+ */
+struct irq_chip no_irq_chip = {
+	.name		= "none",
+	.irq_startup	= noop_ret,
+	.irq_shutdown	= noop,
+	.irq_enable	= noop,
+	.irq_disable	= noop,
+	.irq_ack	= ack_bad,
+	.end		= compat_noop,
+};
+
+/*
+ * Generic dummy implementation which can be used for
+ * real dumb interrupt sources
+ */
+struct irq_chip dummy_irq_chip = {
+	.name		= "dummy",
+	.irq_startup	= noop_ret,
+	.irq_shutdown	= noop,
+	.irq_enable	= noop,
+	.irq_disable	= noop,
+	.irq_ack	= noop,
+	.irq_mask	= noop,
+	.irq_unmask	= noop,
+	.end		= compat_noop,
+};
Index: linux-2.6-tip/kernel/irq/handle.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/handle.c
+++ linux-2.6-tip/kernel/irq/handle.c
@@ -11,24 +11,15 @@
  */
 
 #include <linux/irq.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/module.h>
 #include <linux/random.h>
+#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
-#include <linux/rculist.h>
-#include <linux/hash.h>
-#include <linux/radix-tree.h>
+
 #include <trace/events/irq.h>
 
 #include "internals.h"
 
-/*
- * lockdep: we want to handle all irq_desc locks as a single lock-class:
- */
-struct lock_class_key irq_desc_lock_class;
-
 /**
  * handle_bad_irq - handle spurious and unhandled irqs
  * @irq:       the interrupt number
@@ -43,319 +34,6 @@ void handle_bad_irq(unsigned int irq, st
 	ack_bad_irq(irq);
 }
 
-#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
-static void __init init_irq_default_affinity(void)
-{
-	alloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
-	cpumask_setall(irq_default_affinity);
-}
-#else
-static void __init init_irq_default_affinity(void)
-{
-}
-#endif
-
-/*
- * Linux has a controller-independent interrupt architecture.
- * Every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the appropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * The code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic or
- * having to touch the generic code.
- *
- * Controller mappings for all interrupt sources:
- */
-int nr_irqs = NR_IRQS;
-EXPORT_SYMBOL_GPL(nr_irqs);
-
-#ifdef CONFIG_SPARSE_IRQ
-
-static struct irq_desc irq_desc_init = {
-	.irq	    = -1,
-	.status	    = IRQ_DISABLED,
-	.chip	    = &no_irq_chip,
-	.handle_irq = handle_bad_irq,
-	.depth      = 1,
-	.lock       = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-};
-
-void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
-{
-	void *ptr;
-
-	ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
-			   GFP_ATOMIC, node);
-
-	/*
-	 * don't overwite if can not get new one
-	 * init_copy_kstat_irqs() could still use old one
-	 */
-	if (ptr) {
-		printk(KERN_DEBUG "  alloc kstat_irqs on node %d\n", node);
-		desc->kstat_irqs = ptr;
-	}
-}
-
-static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
-{
-	memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
-
-	raw_spin_lock_init(&desc->lock);
-	desc->irq = irq;
-	desc->irq_data.irq = irq;
-	desc->irq_data.chip = desc->chip;
-#ifdef CONFIG_SMP
-	desc->node = node;
-	desc->irq_data.affinity = &desc->affinity;
-#endif
-	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	init_kstat_irqs(desc, node, nr_cpu_ids);
-	if (!desc->kstat_irqs) {
-		printk(KERN_ERR "can not alloc kstat_irqs\n");
-		BUG_ON(1);
-	}
-	if (!alloc_desc_masks(desc, node, false)) {
-		printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
-		BUG_ON(1);
-	}
-	init_desc_masks(desc);
-	arch_init_chip_data(desc, node);
-}
-
-/*
- * Protect the sparse_irqs:
- */
-DEFINE_RAW_SPINLOCK(sparse_irq_lock);
-
-static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
-
-static void set_irq_desc(unsigned int irq, struct irq_desc *desc)
-{
-	radix_tree_insert(&irq_desc_tree, irq, desc);
-}
-
-struct irq_desc *irq_to_desc(unsigned int irq)
-{
-	return radix_tree_lookup(&irq_desc_tree, irq);
-}
-
-void replace_irq_desc(unsigned int irq, struct irq_desc *desc)
-{
-	void **ptr;
-
-	ptr = radix_tree_lookup_slot(&irq_desc_tree, irq);
-	if (ptr)
-		radix_tree_replace_slot(ptr, desc);
-}
-
-static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
-	[0 ... NR_IRQS_LEGACY-1] = {
-		.irq	    = -1,
-		.status	    = IRQ_DISABLED,
-		.chip	    = &no_irq_chip,
-		.handle_irq = handle_bad_irq,
-		.depth	    = 1,
-		.lock	    = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-	}
-};
-
-static unsigned int *kstat_irqs_legacy;
-
-int __init early_irq_init(void)
-{
-	struct irq_desc *desc;
-	int legacy_count;
-	int node;
-	int i;
-
-	init_irq_default_affinity();
-
-	 /* initialize nr_irqs based on nr_cpu_ids */
-	arch_probe_nr_irqs();
-	printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
-
-	desc = irq_desc_legacy;
-	legacy_count = ARRAY_SIZE(irq_desc_legacy);
-	node = first_online_node;
-
-	/* allocate based on nr_cpu_ids */
-	kstat_irqs_legacy = kzalloc_node(NR_IRQS_LEGACY * nr_cpu_ids *
-					  sizeof(int), GFP_NOWAIT, node);
-
-	for (i = 0; i < legacy_count; i++) {
-		desc[i].irq = i;
-		desc[i].irq_data.irq = i;
-		desc[i].irq_data.chip = desc[i].chip;
-#ifdef CONFIG_SMP
-		desc[i].node = node;
-		desc[i].irq_data.affinity = &desc[i].affinity;
-#endif
-		desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
-		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
-		alloc_desc_masks(&desc[i], node, true);
-		init_desc_masks(&desc[i]);
-		set_irq_desc(i, &desc[i]);
-	}
-
-	return arch_early_irq_init();
-}
-
-struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
-{
-	struct irq_desc *desc;
-	unsigned long flags;
-
-	if (irq >= nr_irqs) {
-		WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
-			irq, nr_irqs);
-		return NULL;
-	}
-
-	desc = irq_to_desc(irq);
-	if (desc)
-		return desc;
-
-	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
-
-	/* We have to check it to avoid races with another CPU */
-	desc = irq_to_desc(irq);
-	if (desc)
-		goto out_unlock;
-
-	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
-
-	printk(KERN_DEBUG "  alloc irq_desc for %d on node %d\n", irq, node);
-	if (!desc) {
-		printk(KERN_ERR "can not alloc irq_desc\n");
-		BUG_ON(1);
-	}
-	init_one_irq_desc(irq, desc, node);
-
-	set_irq_desc(irq, desc);
-
-out_unlock:
-	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
-
-	return desc;
-}
-
-#else /* !CONFIG_SPARSE_IRQ */
-
-struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
-	[0 ... NR_IRQS-1] = {
-		.status = IRQ_DISABLED,
-		.chip = &no_irq_chip,
-		.handle_irq = handle_bad_irq,
-		.depth = 1,
-		.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
-	}
-};
-
-static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
-int __init early_irq_init(void)
-{
-	struct irq_desc *desc;
-	int count;
-	int i;
-
-	init_irq_default_affinity();
-
-	printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);
-
-	desc = irq_desc;
-	count = ARRAY_SIZE(irq_desc);
-
-	for (i = 0; i < count; i++) {
-		desc[i].irq = i;
-		desc[i].irq_data.irq = i;
-		desc[i].irq_data.chip = desc[i].chip;
-#ifdef CONFIG_SMP
-		desc[i].irq_data.affinity = &desc[i].affinity;
-#endif
-		alloc_desc_masks(&desc[i], 0, true);
-		init_desc_masks(&desc[i]);
-		desc[i].kstat_irqs = kstat_irqs_all[i];
-	}
-	return arch_early_irq_init();
-}
-
-struct irq_desc *irq_to_desc(unsigned int irq)
-{
-	return (irq < NR_IRQS) ? irq_desc + irq : NULL;
-}
-
-struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
-{
-	return irq_to_desc(irq);
-}
-#endif /* !CONFIG_SPARSE_IRQ */
-
-void clear_kstat_irqs(struct irq_desc *desc)
-{
-	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
-}
-
-/*
- * What should we do if we get a hw irq event on an illegal vector?
- * Each architecture has to answer this themself.
- */
-static void ack_bad(struct irq_data *data)
-{
-	struct irq_desc *desc = irq_data_to_desc(data);
-
-	print_irq_desc(data->irq, desc);
-	ack_bad_irq(data->irq);
-}
-
-/*
- * NOP functions
- */
-static void noop(struct irq_data *data)
-{
-}
-
-static unsigned int noop_ret(struct irq_data *data)
-{
-	return 0;
-}
-
-static void compat_noop(unsigned int irq)
-{
-}
-
-/*
- * Generic no controller implementation
- */
-struct irq_chip no_irq_chip = {
-	.name		= "none",
-	.irq_startup	= noop_ret,
-	.irq_shutdown	= noop,
-	.irq_enable	= noop,
-	.irq_disable	= noop,
-	.irq_ack	= ack_bad,
-	.end		= compat_noop,
-};
-
-/*
- * Generic dummy implementation which can be used for
- * real dumb interrupt sources
- */
-struct irq_chip dummy_irq_chip = {
-	.name		= "dummy",
-	.irq_startup	= noop_ret,
-	.irq_shutdown	= noop,
-	.irq_enable	= noop,
-	.irq_disable	= noop,
-	.irq_ack	= noop,
-	.irq_mask	= noop,
-	.irq_unmask	= noop,
-	.end		= compat_noop,
-};
-
 /*
  * Special, empty irq handler:
  */
@@ -551,21 +229,3 @@ out:
 	return 1;
 }
 #endif
-
-void early_init_irq_lock_class(void)
-{
-	struct irq_desc *desc;
-	int i;
-
-	for_each_irq_desc(i, desc) {
-		lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	}
-}
-
-unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	return desc ? desc->kstat_irqs[cpu] : 0;
-}
-EXPORT_SYMBOL(kstat_irqs_cpu);
-
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- /dev/null
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
+ *
+ * This file contains the interrupt descriptor management code
+ *
+ * Detailed information is available in Documentation/DocBook/genericirq
+ *
+ */
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/radix-tree.h>
+
+#include "internals.h"
+
+/*
+ * lockdep: we want to handle all irq_desc locks as a single lock-class:
+ */
+struct lock_class_key irq_desc_lock_class;
+
+#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
+static void __init init_irq_default_affinity(void)
+{
+	alloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
+	cpumask_setall(irq_default_affinity);
+}
+#else
+static void __init init_irq_default_affinity(void)
+{
+}
+#endif
+
+int nr_irqs = NR_IRQS;
+EXPORT_SYMBOL_GPL(nr_irqs);
+
+#ifdef CONFIG_SPARSE_IRQ
+
+static struct irq_desc irq_desc_init = {
+	.irq	    = -1,
+	.status	    = IRQ_DISABLED,
+	.chip	    = &no_irq_chip,
+	.handle_irq = handle_bad_irq,
+	.depth      = 1,
+	.lock       = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
+};
+
+void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
+{
+	void *ptr;
+
+	ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
+			   GFP_ATOMIC, node);
+
+	/*
+	 * don't overwite if can not get new one
+	 * init_copy_kstat_irqs() could still use old one
+	 */
+	if (ptr) {
+		printk(KERN_DEBUG "  alloc kstat_irqs on node %d\n", node);
+		desc->kstat_irqs = ptr;
+	}
+}
+
+static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
+{
+	memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
+
+	raw_spin_lock_init(&desc->lock);
+	desc->irq = irq;
+	desc->irq_data.irq = irq;
+	desc->irq_data.chip = desc->chip;
+#ifdef CONFIG_SMP
+	desc->node = node;
+	desc->irq_data.affinity = &desc->affinity;
+#endif
+	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
+	init_kstat_irqs(desc, node, nr_cpu_ids);
+	if (!desc->kstat_irqs) {
+		printk(KERN_ERR "can not alloc kstat_irqs\n");
+		BUG_ON(1);
+	}
+	if (!alloc_desc_masks(desc, node, false)) {
+		printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
+		BUG_ON(1);
+	}
+	init_desc_masks(desc);
+	arch_init_chip_data(desc, node);
+}
+
+/*
+ * Protect the sparse_irqs:
+ */
+DEFINE_RAW_SPINLOCK(sparse_irq_lock);
+
+static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
+
+static void set_irq_desc(unsigned int irq, struct irq_desc *desc)
+{
+	radix_tree_insert(&irq_desc_tree, irq, desc);
+}
+
+struct irq_desc *irq_to_desc(unsigned int irq)
+{
+	return radix_tree_lookup(&irq_desc_tree, irq);
+}
+
+void replace_irq_desc(unsigned int irq, struct irq_desc *desc)
+{
+	void **ptr;
+
+	ptr = radix_tree_lookup_slot(&irq_desc_tree, irq);
+	if (ptr)
+		radix_tree_replace_slot(ptr, desc);
+}
+
+static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
+	[0 ... NR_IRQS_LEGACY-1] = {
+		.irq	    = -1,
+		.status	    = IRQ_DISABLED,
+		.chip	    = &no_irq_chip,
+		.handle_irq = handle_bad_irq,
+		.depth	    = 1,
+		.lock	    = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
+	}
+};
+
+static unsigned int *kstat_irqs_legacy;
+
+int __init early_irq_init(void)
+{
+	struct irq_desc *desc;
+	int legacy_count;
+	int node;
+	int i;
+
+	init_irq_default_affinity();
+
+	 /* initialize nr_irqs based on nr_cpu_ids */
+	arch_probe_nr_irqs();
+	printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
+
+	desc = irq_desc_legacy;
+	legacy_count = ARRAY_SIZE(irq_desc_legacy);
+	node = first_online_node;
+
+	/* allocate based on nr_cpu_ids */
+	kstat_irqs_legacy = kzalloc_node(NR_IRQS_LEGACY * nr_cpu_ids *
+					  sizeof(int), GFP_NOWAIT, node);
+
+	for (i = 0; i < legacy_count; i++) {
+		desc[i].irq = i;
+		desc[i].irq_data.irq = i;
+		desc[i].irq_data.chip = desc[i].chip;
+#ifdef CONFIG_SMP
+		desc[i].node = node;
+		desc[i].irq_data.affinity = &desc[i].affinity;
+#endif
+		desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
+		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
+		alloc_desc_masks(&desc[i], node, true);
+		init_desc_masks(&desc[i]);
+		set_irq_desc(i, &desc[i]);
+	}
+
+	return arch_early_irq_init();
+}
+
+struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+
+	if (irq >= nr_irqs) {
+		WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
+			irq, nr_irqs);
+		return NULL;
+	}
+
+	desc = irq_to_desc(irq);
+	if (desc)
+		return desc;
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+
+	/* We have to check it to avoid races with another CPU */
+	desc = irq_to_desc(irq);
+	if (desc)
+		goto out_unlock;
+
+	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
+
+	printk(KERN_DEBUG "  alloc irq_desc for %d on node %d\n", irq, node);
+	if (!desc) {
+		printk(KERN_ERR "can not alloc irq_desc\n");
+		BUG_ON(1);
+	}
+	init_one_irq_desc(irq, desc, node);
+
+	set_irq_desc(irq, desc);
+
+out_unlock:
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+
+	return desc;
+}
+
+#else /* !CONFIG_SPARSE_IRQ */
+
+struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
+	[0 ... NR_IRQS-1] = {
+		.status = IRQ_DISABLED,
+		.chip = &no_irq_chip,
+		.handle_irq = handle_bad_irq,
+		.depth = 1,
+		.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
+	}
+};
+
+static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
+int __init early_irq_init(void)
+{
+	struct irq_desc *desc;
+	int count;
+	int i;
+
+	init_irq_default_affinity();
+
+	printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);
+
+	desc = irq_desc;
+	count = ARRAY_SIZE(irq_desc);
+
+	for (i = 0; i < count; i++) {
+		desc[i].irq = i;
+		desc[i].irq_data.irq = i;
+		desc[i].irq_data.chip = desc[i].chip;
+#ifdef CONFIG_SMP
+		desc[i].irq_data.affinity = &desc[i].affinity;
+#endif
+		alloc_desc_masks(&desc[i], 0, true);
+		init_desc_masks(&desc[i]);
+		desc[i].kstat_irqs = kstat_irqs_all[i];
+	}
+	return arch_early_irq_init();
+}
+
+struct irq_desc *irq_to_desc(unsigned int irq)
+{
+	return (irq < NR_IRQS) ? irq_desc + irq : NULL;
+}
+
+struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
+{
+	return irq_to_desc(irq);
+}
+#endif /* !CONFIG_SPARSE_IRQ */
+
+void clear_kstat_irqs(struct irq_desc *desc)
+{
+	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
+}
+
+void early_init_irq_lock_class(void)
+{
+	struct irq_desc *desc;
+	int i;
+
+	for_each_irq_desc(i, desc) {
+		lockdep_set_class(&desc->lock, &irq_desc_lock_class);
+	}
+}
+
+unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	return desc ? desc->kstat_irqs[cpu] : 0;
+}
+EXPORT_SYMBOL(kstat_irqs_cpu);



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

* [patch 07/47] genirq: Remove early_init_irq_lock_class()
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (5 preceding siblings ...)
  2010-09-30 23:15 ` [patch 06/47] genirq: Distangle kernel/irq/handle.c Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 08/47] genirq: Move core only inlines to kernel/irq Thomas Gleixner
                   ` (43 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-remove-early-init-irq-lock-class.patch --]
[-- Type: text/plain, Size: 2275 bytes --]

early_init_irq_lock_class() is called way before anything touches the
irq descriptors. In case of SPARSE_IRQ=y this is a NOP operation
because the radix tree is empty at this point. For the SPARSE_IRQ=n
case it's sufficient to set the lock class in early_init_irq(). 

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/lockdep.h |    8 --------
 init/main.c             |    1 -
 kernel/irq/irqdesc.c    |   11 +----------
 3 files changed, 1 insertion(+), 19 deletions(-)

Index: linux-2.6-tip/include/linux/lockdep.h
===================================================================
--- linux-2.6-tip.orig/include/linux/lockdep.h
+++ linux-2.6-tip/include/linux/lockdep.h
@@ -424,14 +424,6 @@ do {								\
 
 #endif /* CONFIG_LOCKDEP */
 
-#ifdef CONFIG_GENERIC_HARDIRQS
-extern void early_init_irq_lock_class(void);
-#else
-static inline void early_init_irq_lock_class(void)
-{
-}
-#endif
-
 #ifdef CONFIG_TRACE_IRQFLAGS
 extern void early_boot_irqs_off(void);
 extern void early_boot_irqs_on(void);
Index: linux-2.6-tip/init/main.c
===================================================================
--- linux-2.6-tip.orig/init/main.c
+++ linux-2.6-tip/init/main.c
@@ -556,7 +556,6 @@ asmlinkage void __init start_kernel(void
 
 	local_irq_disable();
 	early_boot_irqs_off();
-	early_init_irq_lock_class();
 
 /*
  * Interrupts are still disabled. Do necessary setups, then
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -243,6 +243,7 @@ int __init early_irq_init(void)
 		alloc_desc_masks(&desc[i], 0, true);
 		init_desc_masks(&desc[i]);
 		desc[i].kstat_irqs = kstat_irqs_all[i];
+		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
 	}
 	return arch_early_irq_init();
 }
@@ -263,16 +264,6 @@ void clear_kstat_irqs(struct irq_desc *d
 	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
 }
 
-void early_init_irq_lock_class(void)
-{
-	struct irq_desc *desc;
-	int i;
-
-	for_each_irq_desc(i, desc) {
-		lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	}
-}
-
 unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
 {
 	struct irq_desc *desc = irq_to_desc(irq);

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

* [patch 07/47] genirq: Remove early_init_irq_lock_class()
  2010-09-30 23:15 ` [patch 07/47] genirq: Remove early_init_irq_lock_class() Thomas Gleixner
@ 2010-09-30 23:15   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-remove-early-init-irq-lock-class.patch --]
[-- Type: text/plain, Size: 2277 bytes --]

early_init_irq_lock_class() is called way before anything touches the
irq descriptors. In case of SPARSE_IRQ=y this is a NOP operation
because the radix tree is empty at this point. For the SPARSE_IRQ=n
case it's sufficient to set the lock class in early_init_irq(). 

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/lockdep.h |    8 --------
 init/main.c             |    1 -
 kernel/irq/irqdesc.c    |   11 +----------
 3 files changed, 1 insertion(+), 19 deletions(-)

Index: linux-2.6-tip/include/linux/lockdep.h
===================================================================
--- linux-2.6-tip.orig/include/linux/lockdep.h
+++ linux-2.6-tip/include/linux/lockdep.h
@@ -424,14 +424,6 @@ do {								\
 
 #endif /* CONFIG_LOCKDEP */
 
-#ifdef CONFIG_GENERIC_HARDIRQS
-extern void early_init_irq_lock_class(void);
-#else
-static inline void early_init_irq_lock_class(void)
-{
-}
-#endif
-
 #ifdef CONFIG_TRACE_IRQFLAGS
 extern void early_boot_irqs_off(void);
 extern void early_boot_irqs_on(void);
Index: linux-2.6-tip/init/main.c
===================================================================
--- linux-2.6-tip.orig/init/main.c
+++ linux-2.6-tip/init/main.c
@@ -556,7 +556,6 @@ asmlinkage void __init start_kernel(void
 
 	local_irq_disable();
 	early_boot_irqs_off();
-	early_init_irq_lock_class();
 
 /*
  * Interrupts are still disabled. Do necessary setups, then
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -243,6 +243,7 @@ int __init early_irq_init(void)
 		alloc_desc_masks(&desc[i], 0, true);
 		init_desc_masks(&desc[i]);
 		desc[i].kstat_irqs = kstat_irqs_all[i];
+		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
 	}
 	return arch_early_irq_init();
 }
@@ -263,16 +264,6 @@ void clear_kstat_irqs(struct irq_desc *d
 	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
 }
 
-void early_init_irq_lock_class(void)
-{
-	struct irq_desc *desc;
-	int i;
-
-	for_each_irq_desc(i, desc) {
-		lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	}
-}
-
 unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
 {
 	struct irq_desc *desc = irq_to_desc(irq);



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

* [patch 08/47] genirq: Move core only inlines to kernel/irq
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (6 preceding siblings ...)
  2010-09-30 23:15 ` [patch 07/47] genirq: Remove early_init_irq_lock_class() Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 09/47] isdn: hisax: Replace the bogus access to irq stats Thomas Gleixner
                   ` (42 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-move-core-private-inlines.patch --]
[-- Type: text/plain, Size: 5488 bytes --]

Only used by core code. No need to publish those.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h    |   95 -------------------------------------------------
 kernel/irq/internals.h |   78 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 95 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -519,99 +519,4 @@ static inline void set_irq_desc_chip_dat
 
 #endif /* !CONFIG_S390 */
 
-#ifdef CONFIG_SMP
-/**
- * alloc_desc_masks - allocate cpumasks for irq_desc
- * @desc:	pointer to irq_desc struct
- * @node:	node which will be handling the cpumasks
- * @boot:	true if need bootmem
- *
- * Allocates affinity and pending_mask cpumask if required.
- * Returns true if successful (or not required).
- */
-static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
-							bool boot)
-{
-	gfp_t gfp = GFP_ATOMIC;
-
-	if (boot)
-		gfp = GFP_NOWAIT;
-
-#ifdef CONFIG_CPUMASK_OFFSTACK
-	if (!alloc_cpumask_var_node(&desc->affinity, gfp, node))
-		return false;
-
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	if (!alloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
-		free_cpumask_var(desc->affinity);
-		return false;
-	}
-#endif
-#endif
-	return true;
-}
-
-static inline void init_desc_masks(struct irq_desc *desc)
-{
-	cpumask_setall(desc->affinity);
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	cpumask_clear(desc->pending_mask);
-#endif
-}
-
-/**
- * init_copy_desc_masks - copy cpumasks for irq_desc
- * @old_desc:	pointer to old irq_desc struct
- * @new_desc:	pointer to new irq_desc struct
- *
- * Insures affinity and pending_masks are copied to new irq_desc.
- * If !CONFIG_CPUMASKS_OFFSTACK the cpumasks are embedded in the
- * irq_desc struct so the copy is redundant.
- */
-
-static inline void init_copy_desc_masks(struct irq_desc *old_desc,
-					struct irq_desc *new_desc)
-{
-#ifdef CONFIG_CPUMASK_OFFSTACK
-	cpumask_copy(new_desc->affinity, old_desc->affinity);
-
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	cpumask_copy(new_desc->pending_mask, old_desc->pending_mask);
-#endif
-#endif
-}
-
-static inline void free_desc_masks(struct irq_desc *old_desc,
-				   struct irq_desc *new_desc)
-{
-	free_cpumask_var(old_desc->affinity);
-
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	free_cpumask_var(old_desc->pending_mask);
-#endif
-}
-
-#else /* !CONFIG_SMP */
-
-static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
-								bool boot)
-{
-	return true;
-}
-
-static inline void init_desc_masks(struct irq_desc *desc)
-{
-}
-
-static inline void init_copy_desc_masks(struct irq_desc *old_desc,
-					struct irq_desc *new_desc)
-{
-}
-
-static inline void free_desc_masks(struct irq_desc *old_desc,
-				   struct irq_desc *new_desc)
-{
-}
-#endif	/* CONFIG_SMP */
-
 #endif /* _LINUX_IRQ_H */
Index: linux-2.6-tip/kernel/irq/internals.h
===================================================================
--- linux-2.6-tip.orig/kernel/irq/internals.h
+++ linux-2.6-tip/kernel/irq/internals.h
@@ -58,6 +58,84 @@ static inline struct irq_desc *irq_data_
 	return container_of(data, struct irq_desc, irq_data);
 }
 
+#ifdef CONFIG_SMP
+/**
+ * alloc_desc_masks - allocate cpumasks for irq_desc
+ * @desc:	pointer to irq_desc struct
+ * @node:	node which will be handling the cpumasks
+ * @boot:	true if need bootmem
+ *
+ * Allocates affinity and pending_mask cpumask if required.
+ * Returns true if successful (or not required).
+ */
+static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
+							bool boot)
+{
+#ifdef CONFIG_CPUMASK_OFFSTACK
+	gfp_t gfp = boot ? GFP_NOWAIT : GFP_ATOMIC;
+
+	if (!alloc_cpumask_var_node(&desc->affinity, gfp, node))
+		return false;
+
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	if (!alloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
+		free_cpumask_var(desc->affinity);
+		return false;
+	}
+#endif
+#endif
+	return true;
+}
+
+static inline void init_desc_masks(struct irq_desc *desc)
+{
+	cpumask_setall(desc->affinity);
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	cpumask_clear(desc->pending_mask);
+#endif
+}
+
+/**
+ * init_copy_desc_masks - copy cpumasks for irq_desc
+ * @old_desc:	pointer to old irq_desc struct
+ * @new_desc:	pointer to new irq_desc struct
+ *
+ * Insures affinity and pending_masks are copied to new irq_desc.
+ * If !CONFIG_CPUMASKS_OFFSTACK the cpumasks are embedded in the
+ * irq_desc struct so the copy is redundant.
+ */
+
+static inline void init_copy_desc_masks(struct irq_desc *old_desc,
+					struct irq_desc *new_desc)
+{
+#ifdef CONFIG_CPUMASK_OFFSTACK
+	cpumask_copy(new_desc->affinity, old_desc->affinity);
+
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	cpumask_copy(new_desc->pending_mask, old_desc->pending_mask);
+#endif
+#endif
+}
+
+static inline void free_desc_masks(struct irq_desc *old_desc,
+				   struct irq_desc *new_desc)
+{
+	free_cpumask_var(old_desc->affinity);
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	free_cpumask_var(old_desc->pending_mask);
+#endif
+}
+
+#else /* !CONFIG_SMP */
+static inline bool alloc_desc_masks(struct irq_desc *desc, int node, bool boot)
+{
+	return true;
+}
+static inline void init_desc_masks(struct irq_desc *desc) { }
+static inline void init_copy_desc_masks(struct irq_desc *o, struct irq_desc *n) { }
+static inline void free_desc_masks(struct irq_desc *o, struct irq_desc *n) { }
+#endif	/* CONFIG_SMP */
+
 /*
  * Debugging printout:
  */

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

* [patch 09/47] isdn: hisax: Replace the bogus access to irq stats
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (7 preceding siblings ...)
  2010-09-30 23:15 ` [patch 08/47] genirq: Move core only inlines to kernel/irq Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 10/47] genirq: Remove export of kstat_irqs_cpu Thomas Gleixner
                   ` (41 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: drivers-isdn-hisax-fix-madness.patch --]
[-- Type: text/plain, Size: 2378 bytes --]

Abusing irq stats in a driver for counting interrupts is a horrible
idea and not safe with shared interrupts. Replace it by a local
interrupt counter.

Noticed by the attempt to remove the irq stats export.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/isdn/hisax/config.c |   18 ++++++++++++++----
 drivers/isdn/hisax/hisax.h  |    1 +
 2 files changed, 15 insertions(+), 4 deletions(-)

Index: linux-2.6-tip/drivers/isdn/hisax/config.c
===================================================================
--- linux-2.6-tip.orig/drivers/isdn/hisax/config.c
+++ linux-2.6-tip/drivers/isdn/hisax/config.c
@@ -801,6 +801,16 @@ static void closecard(int cardnr)
 	ll_unload(csta);
 }
 
+static irqreturn_t card_irq(int intno, void *dev_id)
+{
+	struct IsdnCardState *cs = dev_id;
+	irqreturn_t ret = cs->irq_func(intno, cs);
+
+	if (ret == IRQ_HANDLED)
+		cs->irq_cnt++;
+	return ret;
+}
+
 static int init_card(struct IsdnCardState *cs)
 {
 	int 	irq_cnt, cnt = 3, ret;
@@ -809,10 +819,10 @@ static int init_card(struct IsdnCardStat
 		ret = cs->cardmsg(cs, CARD_INIT, NULL);
 		return(ret);
 	}
-	irq_cnt = kstat_irqs(cs->irq);
+	irq_cnt = cs->irq_cnt = 0;
 	printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ],
 	       cs->irq, irq_cnt);
-	if (request_irq(cs->irq, cs->irq_func, cs->irq_flags, "HiSax", cs)) {
+	if (request_irq(cs->irq, card_irq, cs->irq_flags, "HiSax", cs)) {
 		printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n",
 		       cs->irq);
 		return 1;
@@ -822,8 +832,8 @@ static int init_card(struct IsdnCardStat
 		/* Timeout 10ms */
 		msleep(10);
 		printk(KERN_INFO "%s: IRQ %d count %d\n",
-		       CardType[cs->typ], cs->irq, kstat_irqs(cs->irq));
-		if (kstat_irqs(cs->irq) == irq_cnt) {
+		       CardType[cs->typ], cs->irq, cs->irq_cnt);
+		if (cs->irq_cnt == irq_cnt) {
 			printk(KERN_WARNING
 			       "%s: IRQ(%d) getting no interrupts during init %d\n",
 			       CardType[cs->typ], cs->irq, 4 - cnt);
Index: linux-2.6-tip/drivers/isdn/hisax/hisax.h
===================================================================
--- linux-2.6-tip.orig/drivers/isdn/hisax/hisax.h
+++ linux-2.6-tip/drivers/isdn/hisax/hisax.h
@@ -959,6 +959,7 @@ struct IsdnCardState {
 	u_long		event;
 	struct work_struct tqueue;
 	struct timer_list dbusytimer;
+	unsigned int	irq_cnt;
 #ifdef ERROR_STATISTIC
 	int		err_crc;
 	int		err_tx;

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

* [patch 09/47] isdn: hisax: Replace the bogus access to irq stats
  2010-09-30 23:15 ` [patch 09/47] isdn: hisax: Replace the bogus access to irq stats Thomas Gleixner
@ 2010-09-30 23:15   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: drivers-isdn-hisax-fix-madness.patch --]
[-- Type: text/plain, Size: 2380 bytes --]

Abusing irq stats in a driver for counting interrupts is a horrible
idea and not safe with shared interrupts. Replace it by a local
interrupt counter.

Noticed by the attempt to remove the irq stats export.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/isdn/hisax/config.c |   18 ++++++++++++++----
 drivers/isdn/hisax/hisax.h  |    1 +
 2 files changed, 15 insertions(+), 4 deletions(-)

Index: linux-2.6-tip/drivers/isdn/hisax/config.c
===================================================================
--- linux-2.6-tip.orig/drivers/isdn/hisax/config.c
+++ linux-2.6-tip/drivers/isdn/hisax/config.c
@@ -801,6 +801,16 @@ static void closecard(int cardnr)
 	ll_unload(csta);
 }
 
+static irqreturn_t card_irq(int intno, void *dev_id)
+{
+	struct IsdnCardState *cs = dev_id;
+	irqreturn_t ret = cs->irq_func(intno, cs);
+
+	if (ret == IRQ_HANDLED)
+		cs->irq_cnt++;
+	return ret;
+}
+
 static int init_card(struct IsdnCardState *cs)
 {
 	int 	irq_cnt, cnt = 3, ret;
@@ -809,10 +819,10 @@ static int init_card(struct IsdnCardStat
 		ret = cs->cardmsg(cs, CARD_INIT, NULL);
 		return(ret);
 	}
-	irq_cnt = kstat_irqs(cs->irq);
+	irq_cnt = cs->irq_cnt = 0;
 	printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ],
 	       cs->irq, irq_cnt);
-	if (request_irq(cs->irq, cs->irq_func, cs->irq_flags, "HiSax", cs)) {
+	if (request_irq(cs->irq, card_irq, cs->irq_flags, "HiSax", cs)) {
 		printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n",
 		       cs->irq);
 		return 1;
@@ -822,8 +832,8 @@ static int init_card(struct IsdnCardStat
 		/* Timeout 10ms */
 		msleep(10);
 		printk(KERN_INFO "%s: IRQ %d count %d\n",
-		       CardType[cs->typ], cs->irq, kstat_irqs(cs->irq));
-		if (kstat_irqs(cs->irq) == irq_cnt) {
+		       CardType[cs->typ], cs->irq, cs->irq_cnt);
+		if (cs->irq_cnt == irq_cnt) {
 			printk(KERN_WARNING
 			       "%s: IRQ(%d) getting no interrupts during init %d\n",
 			       CardType[cs->typ], cs->irq, 4 - cnt);
Index: linux-2.6-tip/drivers/isdn/hisax/hisax.h
===================================================================
--- linux-2.6-tip.orig/drivers/isdn/hisax/hisax.h
+++ linux-2.6-tip/drivers/isdn/hisax/hisax.h
@@ -959,6 +959,7 @@ struct IsdnCardState {
 	u_long		event;
 	struct work_struct tqueue;
 	struct timer_list dbusytimer;
+	unsigned int	irq_cnt;
 #ifdef ERROR_STATISTIC
 	int		err_crc;
 	int		err_tx;



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

* [patch 10/47] genirq: Remove export of kstat_irqs_cpu
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (8 preceding siblings ...)
  2010-09-30 23:15 ` [patch 09/47] isdn: hisax: Replace the bogus access to irq stats Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 11/47] genirq: Provide default irq init flags Thomas Gleixner
                   ` (40 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-remove-export-of-kstat_irqs.patch --]
[-- Type: text/plain, Size: 592 bytes --]

The statistics accessor is only used by proc/stats and
show_interrupts(). Both are compiled in.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/irqdesc.c |    1 -
 1 file changed, 1 deletion(-)

Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -269,4 +269,3 @@ unsigned int kstat_irqs_cpu(unsigned int
 	struct irq_desc *desc = irq_to_desc(irq);
 	return desc ? desc->kstat_irqs[cpu] : 0;
 }
-EXPORT_SYMBOL(kstat_irqs_cpu);

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

* [patch 11/47] genirq: Provide default irq init flags
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (9 preceding siblings ...)
  2010-09-30 23:15 ` [patch 10/47] genirq: Remove export of kstat_irqs_cpu Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 12/47] arm: Use ARCH_IRQ_INIT_FLAGS Thomas Gleixner
                   ` (39 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-provide-default-irq-init-flags.patch --]
[-- Type: text/plain, Size: 2621 bytes --]

Arch code sets it's own irq_desc.status flags right after boot and for
dynamically allocated interrupts. That might involve iterating over a
huge array.

Allow ARCH_IRQ_INIT_FLAGS to set separate flags aside of IRQ_DISABLED
which is the default.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h  |    6 ++++++
 kernel/irq/chip.c    |    2 +-
 kernel/irq/irqdesc.c |    6 +++---
 3 files changed, 10 insertions(+), 4 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -281,6 +281,12 @@ extern struct irq_desc *irq_to_desc_allo
  */
 #include <asm/hw_irq.h>
 
+#ifndef ARCH_IRQ_INIT_FLAGS
+# define ARCH_IRQ_INIT_FLAGS	0
+#endif
+
+#define IRQ_DEFAULT_INIT_FLAGS	(IRQ_DISABLED | ARCH_IRQ_INIT_FLAGS)
+
 extern int setup_irq(unsigned int irq, struct irqaction *new);
 extern void remove_irq(unsigned int irq, struct irqaction *act);
 
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -31,7 +31,7 @@ static void dynamic_irq_init_x(unsigned 
 
 	/* Ensure we don't have left over values from a previous use of this irq */
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status = IRQ_DISABLED;
+	desc->status = IRQ_DEFAULT_INIT_FLAGS;
 	desc->chip = &no_irq_chip;
 	desc->irq_data.chip = &no_irq_chip;
 	desc->handle_irq = handle_bad_irq;
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -40,7 +40,7 @@ EXPORT_SYMBOL_GPL(nr_irqs);
 
 static struct irq_desc irq_desc_init = {
 	.irq	    = -1,
-	.status	    = IRQ_DISABLED,
+	.status	    = IRQ_DEFAULT_INIT_FLAGS,
 	.chip	    = &no_irq_chip,
 	.handle_irq = handle_bad_irq,
 	.depth      = 1,
@@ -119,7 +119,7 @@ void replace_irq_desc(unsigned int irq, 
 static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
 	[0 ... NR_IRQS_LEGACY-1] = {
 		.irq	    = -1,
-		.status	    = IRQ_DISABLED,
+		.status	    = IRQ_DEFAULT_INIT_FLAGS,
 		.chip	    = &no_irq_chip,
 		.handle_irq = handle_bad_irq,
 		.depth	    = 1,
@@ -211,7 +211,7 @@ out_unlock:
 
 struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
 	[0 ... NR_IRQS-1] = {
-		.status = IRQ_DISABLED,
+		.status	= IRQ_DEFAULT_INIT_FLAGS,
 		.chip = &no_irq_chip,
 		.handle_irq = handle_bad_irq,
 		.depth = 1,

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

* [patch 11/47] genirq: Provide default irq init flags
  2010-09-30 23:15 ` [patch 11/47] genirq: Provide default irq init flags Thomas Gleixner
@ 2010-09-30 23:15   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-provide-default-irq-init-flags.patch --]
[-- Type: text/plain, Size: 2623 bytes --]

Arch code sets it's own irq_desc.status flags right after boot and for
dynamically allocated interrupts. That might involve iterating over a
huge array.

Allow ARCH_IRQ_INIT_FLAGS to set separate flags aside of IRQ_DISABLED
which is the default.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h  |    6 ++++++
 kernel/irq/chip.c    |    2 +-
 kernel/irq/irqdesc.c |    6 +++---
 3 files changed, 10 insertions(+), 4 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -281,6 +281,12 @@ extern struct irq_desc *irq_to_desc_allo
  */
 #include <asm/hw_irq.h>
 
+#ifndef ARCH_IRQ_INIT_FLAGS
+# define ARCH_IRQ_INIT_FLAGS	0
+#endif
+
+#define IRQ_DEFAULT_INIT_FLAGS	(IRQ_DISABLED | ARCH_IRQ_INIT_FLAGS)
+
 extern int setup_irq(unsigned int irq, struct irqaction *new);
 extern void remove_irq(unsigned int irq, struct irqaction *act);
 
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -31,7 +31,7 @@ static void dynamic_irq_init_x(unsigned 
 
 	/* Ensure we don't have left over values from a previous use of this irq */
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status = IRQ_DISABLED;
+	desc->status = IRQ_DEFAULT_INIT_FLAGS;
 	desc->chip = &no_irq_chip;
 	desc->irq_data.chip = &no_irq_chip;
 	desc->handle_irq = handle_bad_irq;
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -40,7 +40,7 @@ EXPORT_SYMBOL_GPL(nr_irqs);
 
 static struct irq_desc irq_desc_init = {
 	.irq	    = -1,
-	.status	    = IRQ_DISABLED,
+	.status	    = IRQ_DEFAULT_INIT_FLAGS,
 	.chip	    = &no_irq_chip,
 	.handle_irq = handle_bad_irq,
 	.depth      = 1,
@@ -119,7 +119,7 @@ void replace_irq_desc(unsigned int irq, 
 static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
 	[0 ... NR_IRQS_LEGACY-1] = {
 		.irq	    = -1,
-		.status	    = IRQ_DISABLED,
+		.status	    = IRQ_DEFAULT_INIT_FLAGS,
 		.chip	    = &no_irq_chip,
 		.handle_irq = handle_bad_irq,
 		.depth	    = 1,
@@ -211,7 +211,7 @@ out_unlock:
 
 struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
 	[0 ... NR_IRQS-1] = {
-		.status = IRQ_DISABLED,
+		.status	= IRQ_DEFAULT_INIT_FLAGS,
 		.chip = &no_irq_chip,
 		.handle_irq = handle_bad_irq,
 		.depth = 1,



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

* [patch 12/47] arm: Use ARCH_IRQ_INIT_FLAGS
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (10 preceding siblings ...)
  2010-09-30 23:15 ` [patch 11/47] genirq: Provide default irq init flags Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 13/47] powerpc: " Thomas Gleixner
                   ` (38 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: arm-use-genirq-default-init-flags.patch --]
[-- Type: text/plain, Size: 1147 bytes --]

Define the ARCH_IRQ_INIT_FLAGS instead of fixing it up in a loop.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/include/asm/hw_irq.h |    2 ++
 arch/arm/kernel/irq.c         |    4 +---
 2 files changed, 3 insertions(+), 3 deletions(-)

Index: linux-2.6-tip/arch/arm/include/asm/hw_irq.h
===================================================================
--- linux-2.6-tip.orig/arch/arm/include/asm/hw_irq.h
+++ linux-2.6-tip/arch/arm/include/asm/hw_irq.h
@@ -24,4 +24,6 @@ void set_irq_flags(unsigned int irq, uns
 #define IRQF_PROBE	(1 << 1)
 #define IRQF_NOAUTOEN	(1 << 2)
 
+#define ARCH_IRQ_INIT_FLAGS	(IRQ_NOREQUEST | IRQ_NOPROBE)
+
 #endif
Index: linux-2.6-tip/arch/arm/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/kernel/irq.c
+++ linux-2.6-tip/arch/arm/kernel/irq.c
@@ -151,10 +151,8 @@ void __init init_IRQ(void)
 	struct irq_desc *desc;
 	int irq;
 
-	for (irq = 0; irq < nr_irqs; irq++) {
+	for (irq = 0; irq < nr_irqs; irq++)
 		desc = irq_to_desc_alloc_node(irq, 0);
-		desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
-	}
 
 	init_arch_irq();
 }

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

* [patch 13/47] powerpc: Use ARCH_IRQ_INIT_FLAGS
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (11 preceding siblings ...)
  2010-09-30 23:15 ` [patch 12/47] arm: Use ARCH_IRQ_INIT_FLAGS Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 14/47] genirq: Implement a sane sparse_irq allocator Thomas Gleixner
                   ` (37 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: powerpc-use-generic-default-init-flags.patch --]
[-- Type: text/plain, Size: 1364 bytes --]

Define the ARCH_IRQ_INIT_FLAGS instead of fixing it up in a loop.

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

Index: linux-2.6-tip/arch/powerpc/include/asm/hw_irq.h
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/include/asm/hw_irq.h
+++ linux-2.6-tip/arch/powerpc/include/asm/hw_irq.h
@@ -124,6 +124,8 @@ static inline int irqs_disabled_flags(un
 
 #endif /* CONFIG_PPC64 */
 
+#define ARCH_IRQ_INIT_FLAGS	IRQ_NOREQUEST
+
 /*
  * interrupt-retrigger: should we handle this via lost interrupts and IPIs
  * or should we not care like we do now ? --BenH.
Index: linux-2.6-tip/arch/powerpc/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/kernel/irq.c
+++ linux-2.6-tip/arch/powerpc/kernel/irq.c
@@ -1072,21 +1072,6 @@ void irq_free_virt(unsigned int virq, un
 
 int arch_early_irq_init(void)
 {
-	struct irq_desc *desc;
-	int i;
-
-	for (i = 0; i < NR_IRQS; i++) {
-		desc = irq_to_desc(i);
-		if (desc)
-			desc->status |= IRQ_NOREQUEST;
-	}
-
-	return 0;
-}
-
-int arch_init_chip_data(struct irq_desc *desc, int node)
-{
-	desc->status |= IRQ_NOREQUEST;
 	return 0;
 }
 

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

* [patch 13/47] powerpc: Use ARCH_IRQ_INIT_FLAGS
  2010-09-30 23:15 ` [patch 13/47] powerpc: " Thomas Gleixner
@ 2010-09-30 23:15   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: powerpc-use-generic-default-init-flags.patch --]
[-- Type: text/plain, Size: 1366 bytes --]

Define the ARCH_IRQ_INIT_FLAGS instead of fixing it up in a loop.

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

Index: linux-2.6-tip/arch/powerpc/include/asm/hw_irq.h
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/include/asm/hw_irq.h
+++ linux-2.6-tip/arch/powerpc/include/asm/hw_irq.h
@@ -124,6 +124,8 @@ static inline int irqs_disabled_flags(un
 
 #endif /* CONFIG_PPC64 */
 
+#define ARCH_IRQ_INIT_FLAGS	IRQ_NOREQUEST
+
 /*
  * interrupt-retrigger: should we handle this via lost interrupts and IPIs
  * or should we not care like we do now ? --BenH.
Index: linux-2.6-tip/arch/powerpc/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/kernel/irq.c
+++ linux-2.6-tip/arch/powerpc/kernel/irq.c
@@ -1072,21 +1072,6 @@ void irq_free_virt(unsigned int virq, un
 
 int arch_early_irq_init(void)
 {
-	struct irq_desc *desc;
-	int i;
-
-	for (i = 0; i < NR_IRQS; i++) {
-		desc = irq_to_desc(i);
-		if (desc)
-			desc->status |= IRQ_NOREQUEST;
-	}
-
-	return 0;
-}
-
-int arch_init_chip_data(struct irq_desc *desc, int node)
-{
-	desc->status |= IRQ_NOREQUEST;
 	return 0;
 }
 



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

* [patch 14/47] genirq: Implement a sane sparse_irq allocator
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (12 preceding siblings ...)
  2010-09-30 23:15 ` [patch 13/47] powerpc: " Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
  2010-10-01  5:28   ` Yinghai Lu
  2010-09-30 23:15 ` [patch 15/47] genirq: Prepare proc for real sparse irq support Thomas Gleixner
                   ` (36 subsequent siblings)
  50 siblings, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-sparse-implement-sane-allocation-function.patch --]
[-- Type: text/plain, Size: 9905 bytes --]

The current sparse_irq allocator has several short comings due to
failures in the design or the lack of it:

 - Requires iteration over the number of active irqs to find a free slot
   (Some architectures have grown their own workarounds for this)
 - Removal of entries is not possible
 - Racy between create_irq_nr and destroy_irq (plugged by horrible
   callbacks)
 - Migration of active irq descriptors is not possible
 - No bulk allocation of irq ranges
 - Sprinkeled irq_desc references all over the place outside of kernel/irq/
   (The previous chip functions series is addressing this issue)

Implement a sane allocator which fixes the above short comings (though
migration of active descriptors needs a full tree wide cleanup of the
direct and mostly unlocked access to irq_desc).

The new allocator still uses a radix_tree, but uses a bitmap for
keeping track of allocated irq numbers. That allows:

 - Fast lookup of a free slot
 - Allows the removal of descriptors
 - Prevents the create/destroy race
 - Bulk allocation of consecutive irq ranges
 - Basic design is ready for migration of life descriptors after
   further cleanups

The bitmap is also used in the SPARSE_IRQ=n case for lookup and
raceless (de)allocation of irq numbers. So it removes the requirement
for looping through the descriptor array to find slots.

Right now it uses sparse_irq_lock to protect the bitmap and the radix
tree, but after cleaning up all users we should be able convert that
to a mutex and to switch the radix_tree and decriptor allocations to
GFP_KERNEL.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h  |   25 +++++
 kernel/irq/irqdesc.c |  226 +++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 243 insertions(+), 8 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -276,6 +276,31 @@ static inline struct irq_desc *move_irq_
 
 extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
 
+int irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node);
+
+static inline int irq_alloc_desc(int node)
+{
+	return irq_alloc_descs(0, 0, 1, node);
+}
+
+static inline int
+irq_alloc_desc_at(unsigned int at, int node)
+{
+	return irq_alloc_descs(at, 0, 1, node);
+}
+
+static inline int
+irq_alloc_desc_from(unsigned int from, int node)
+{
+	return irq_alloc_descs(0, from, 1, node);
+}
+
+void irq_free_descs(unsigned int irq, unsigned int cnt);
+static inline void irq_free_desc(unsigned int irq)
+{
+	irq_free_descs(irq, 1);
+}
+
 /*
  * Pick up the arch-dependent methods:
  */
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/radix-tree.h>
+#include <linux/bitmap.h>
 
 #include "internals.h"
 
@@ -33,9 +34,55 @@ static void __init init_irq_default_affi
 }
 #endif
 
+#ifdef CONFIG_SMP
+static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)
+{
+	if (!zalloc_cpumask_var_node(&desc->affinity, gfp, node))
+		return -ENOMEM;
+
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	if (!zalloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
+		free_cpumask_var(desc->affinity);
+		return -ENOMEM;
+	}
+#endif
+	return 0;
+}
+
+static void desc_smp_init(struct irq_desc *desc, int node)
+{
+	desc->node = node;
+	desc->irq_data.affinity = &desc->affinity;
+	cpumask_copy(desc->affinity, irq_default_affinity);
+}
+
+#else
+static inline int
+alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
+static inline void desc_smp_init(struct irq_desc *desc, int node) { }
+#endif
+
+static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
+{
+	memset(&desc->irq_data, 0 , sizeof(desc->irq_data));
+	desc->irq = irq;
+	desc->irq_data.irq = irq;
+	desc->status = IRQ_DEFAULT_INIT_FLAGS;
+	desc->chip = &no_irq_chip;
+	desc->irq_data.chip = &no_irq_chip;
+	desc->handle_irq = handle_bad_irq;
+	desc->depth = 1;
+	desc->name = NULL;
+	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
+	desc_smp_init(desc, node);
+}
+
 int nr_irqs = NR_IRQS;
 EXPORT_SYMBOL_GPL(nr_irqs);
 
+DEFINE_RAW_SPINLOCK(sparse_irq_lock);
+static DECLARE_BITMAP(allocated_irqs, NR_IRQS);
+
 #ifdef CONFIG_SPARSE_IRQ
 
 static struct irq_desc irq_desc_init = {
@@ -90,14 +137,9 @@ static void init_one_irq_desc(int irq, s
 	arch_init_chip_data(desc, node);
 }
 
-/*
- * Protect the sparse_irqs:
- */
-DEFINE_RAW_SPINLOCK(sparse_irq_lock);
-
 static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
 
-static void set_irq_desc(unsigned int irq, struct irq_desc *desc)
+static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
 {
 	radix_tree_insert(&irq_desc_tree, irq, desc);
 }
@@ -116,6 +158,93 @@ void replace_irq_desc(unsigned int irq, 
 		radix_tree_replace_slot(ptr, desc);
 }
 
+static void delete_irq_desc(unsigned int irq)
+{
+	radix_tree_delete(&irq_desc_tree, irq);
+}
+
+#ifdef CONFIG_SMP
+static void free_masks(struct irq_desc *desc)
+{
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	free_cpumask_var(desc->pending_mask);
+#endif
+	free_cpumask_var(desc->affinity);
+}
+#else
+static inline void free_masks(struct irq_desc *desc) { }
+#endif
+
+static struct irq_desc *alloc_desc(int irq, int node)
+{
+	struct irq_desc *desc;
+	gfp_t gfp = GFP_KERNEL;
+
+	desc = kzalloc_node(sizeof(*desc), gfp, node);
+	if (!desc)
+		return NULL;
+	desc->kstat_irqs = kzalloc_node(sizeof(*desc->kstat_irqs), gfp, node);
+	if (!desc)
+		goto err_desc;
+
+	if (alloc_masks(desc, gfp, node))
+		goto err_kstat;
+
+	raw_spin_lock_init(&desc->lock);
+	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
+
+	desc_set_defaults(irq, desc, node);
+
+	desc_smp_init(desc, node);
+	return desc;
+
+err_kstat:
+	kfree(desc->kstat_irqs);
+err_desc:
+	kfree(desc);
+	return NULL;
+}
+
+static void free_desc(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+	delete_irq_desc(irq);
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+
+	free_masks(desc);
+	kfree(desc->kstat_irqs);
+	kfree(desc);
+}
+
+static int alloc_descs(unsigned int start, unsigned int cnt, int node)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+	int i;
+
+	for (i = 0; i < cnt; i++) {
+		desc = alloc_desc(start + i, node);
+		if (!desc)
+			goto err;
+		raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+		irq_insert_desc(start + i, desc);
+		raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+	}
+	return start;
+
+err:
+	for (i--; i >= 0; i--)
+		free_desc(start + i);
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+	bitmap_clear(allocated_irqs, start, cnt);
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+	return -ENOMEM;
+}
+
 static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
 	[0 ... NR_IRQS_LEGACY-1] = {
 		.irq	    = -1,
@@ -162,7 +291,7 @@ int __init early_irq_init(void)
 		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
 		alloc_desc_masks(&desc[i], node, true);
 		init_desc_masks(&desc[i]);
-		set_irq_desc(i, &desc[i]);
+		irq_insert_desc(i, &desc[i]);
 	}
 
 	return arch_early_irq_init();
@@ -199,7 +328,7 @@ struct irq_desc * __ref irq_to_desc_allo
 	}
 	init_one_irq_desc(irq, desc, node);
 
-	set_irq_desc(irq, desc);
+	irq_insert_desc(irq, desc);
 
 out_unlock:
 	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
@@ -257,8 +386,89 @@ struct irq_desc *irq_to_desc_alloc_node(
 {
 	return irq_to_desc(irq);
 }
+
+static void free_desc(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&desc->lock, flags);
+#ifdef CONFIG_SMP
+	desc_set_defaults(irq, desc, desc->node);
+#else
+	desc_set_defaults(irq, desc, 0);
+#endif
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+static inline int alloc_descs(unsigned int start, unsigned int cnt, int node)
+{
+	return start;
+}
 #endif /* !CONFIG_SPARSE_IRQ */
 
+/* Dynamic interrupt handling */
+
+/**
+ * irq_free_descs - free irq descriptors
+ * @from:	Start of descriptor range
+ * @cnt:	Number of consecutive irqs to free
+ */
+void irq_free_descs(unsigned int from, unsigned int cnt)
+{
+	unsigned long flags;
+	int i;
+
+	if (from >= nr_irqs || (from + cnt) > nr_irqs)
+		return;
+
+	for (i = 0; i < cnt; i++)
+		free_desc(from + i);
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+	bitmap_clear(allocated_irqs, from, cnt);
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+}
+
+/**
+ * irq_alloc_descs - allocate and initialize a range of irq descriptors
+ * @irq:	Allocate for specific irq number if irq > 0
+ * @from:	Start the search from this irq number
+ * @cnt:	Number of consecutive irqs to allocate.
+ * @node:	Preferred node on which the irq descriptor should be allocated
+ *
+ * Returns the first irq number or error code
+ */
+int __ref
+irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node)
+{
+	unsigned long flags;
+	int start, ret;
+
+	if (!cnt)
+		return -EINVAL;
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+
+	start = bitmap_find_next_zero_area(allocated_irqs, nr_irqs, from, cnt, 0);
+	ret = -EEXIST;
+	if (irq && start != irq)
+		goto err;
+
+	ret = -ENOMEM;
+	if (start >= nr_irqs)
+		goto err;
+
+	bitmap_set(allocated_irqs, start, cnt);
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+	return alloc_descs(start, cnt, node);
+
+err:
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+	return ret;
+}
+
+/* Statistics access */
 void clear_kstat_irqs(struct irq_desc *desc)
 {
 	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));

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

* [patch 14/47] genirq: Implement a sane sparse_irq allocator
  2010-09-30 23:15 ` [patch 14/47] genirq: Implement a sane sparse_irq allocator Thomas Gleixner
@ 2010-09-30 23:15   ` Thomas Gleixner
  2010-10-01  5:28   ` Yinghai Lu
  1 sibling, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-sparse-implement-sane-allocation-function.patch --]
[-- Type: text/plain, Size: 9907 bytes --]

The current sparse_irq allocator has several short comings due to
failures in the design or the lack of it:

 - Requires iteration over the number of active irqs to find a free slot
   (Some architectures have grown their own workarounds for this)
 - Removal of entries is not possible
 - Racy between create_irq_nr and destroy_irq (plugged by horrible
   callbacks)
 - Migration of active irq descriptors is not possible
 - No bulk allocation of irq ranges
 - Sprinkeled irq_desc references all over the place outside of kernel/irq/
   (The previous chip functions series is addressing this issue)

Implement a sane allocator which fixes the above short comings (though
migration of active descriptors needs a full tree wide cleanup of the
direct and mostly unlocked access to irq_desc).

The new allocator still uses a radix_tree, but uses a bitmap for
keeping track of allocated irq numbers. That allows:

 - Fast lookup of a free slot
 - Allows the removal of descriptors
 - Prevents the create/destroy race
 - Bulk allocation of consecutive irq ranges
 - Basic design is ready for migration of life descriptors after
   further cleanups

The bitmap is also used in the SPARSE_IRQ=n case for lookup and
raceless (de)allocation of irq numbers. So it removes the requirement
for looping through the descriptor array to find slots.

Right now it uses sparse_irq_lock to protect the bitmap and the radix
tree, but after cleaning up all users we should be able convert that
to a mutex and to switch the radix_tree and decriptor allocations to
GFP_KERNEL.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h  |   25 +++++
 kernel/irq/irqdesc.c |  226 +++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 243 insertions(+), 8 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -276,6 +276,31 @@ static inline struct irq_desc *move_irq_
 
 extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
 
+int irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node);
+
+static inline int irq_alloc_desc(int node)
+{
+	return irq_alloc_descs(0, 0, 1, node);
+}
+
+static inline int
+irq_alloc_desc_at(unsigned int at, int node)
+{
+	return irq_alloc_descs(at, 0, 1, node);
+}
+
+static inline int
+irq_alloc_desc_from(unsigned int from, int node)
+{
+	return irq_alloc_descs(0, from, 1, node);
+}
+
+void irq_free_descs(unsigned int irq, unsigned int cnt);
+static inline void irq_free_desc(unsigned int irq)
+{
+	irq_free_descs(irq, 1);
+}
+
 /*
  * Pick up the arch-dependent methods:
  */
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/radix-tree.h>
+#include <linux/bitmap.h>
 
 #include "internals.h"
 
@@ -33,9 +34,55 @@ static void __init init_irq_default_affi
 }
 #endif
 
+#ifdef CONFIG_SMP
+static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)
+{
+	if (!zalloc_cpumask_var_node(&desc->affinity, gfp, node))
+		return -ENOMEM;
+
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	if (!zalloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
+		free_cpumask_var(desc->affinity);
+		return -ENOMEM;
+	}
+#endif
+	return 0;
+}
+
+static void desc_smp_init(struct irq_desc *desc, int node)
+{
+	desc->node = node;
+	desc->irq_data.affinity = &desc->affinity;
+	cpumask_copy(desc->affinity, irq_default_affinity);
+}
+
+#else
+static inline int
+alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
+static inline void desc_smp_init(struct irq_desc *desc, int node) { }
+#endif
+
+static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
+{
+	memset(&desc->irq_data, 0 , sizeof(desc->irq_data));
+	desc->irq = irq;
+	desc->irq_data.irq = irq;
+	desc->status = IRQ_DEFAULT_INIT_FLAGS;
+	desc->chip = &no_irq_chip;
+	desc->irq_data.chip = &no_irq_chip;
+	desc->handle_irq = handle_bad_irq;
+	desc->depth = 1;
+	desc->name = NULL;
+	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
+	desc_smp_init(desc, node);
+}
+
 int nr_irqs = NR_IRQS;
 EXPORT_SYMBOL_GPL(nr_irqs);
 
+DEFINE_RAW_SPINLOCK(sparse_irq_lock);
+static DECLARE_BITMAP(allocated_irqs, NR_IRQS);
+
 #ifdef CONFIG_SPARSE_IRQ
 
 static struct irq_desc irq_desc_init = {
@@ -90,14 +137,9 @@ static void init_one_irq_desc(int irq, s
 	arch_init_chip_data(desc, node);
 }
 
-/*
- * Protect the sparse_irqs:
- */
-DEFINE_RAW_SPINLOCK(sparse_irq_lock);
-
 static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
 
-static void set_irq_desc(unsigned int irq, struct irq_desc *desc)
+static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
 {
 	radix_tree_insert(&irq_desc_tree, irq, desc);
 }
@@ -116,6 +158,93 @@ void replace_irq_desc(unsigned int irq, 
 		radix_tree_replace_slot(ptr, desc);
 }
 
+static void delete_irq_desc(unsigned int irq)
+{
+	radix_tree_delete(&irq_desc_tree, irq);
+}
+
+#ifdef CONFIG_SMP
+static void free_masks(struct irq_desc *desc)
+{
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	free_cpumask_var(desc->pending_mask);
+#endif
+	free_cpumask_var(desc->affinity);
+}
+#else
+static inline void free_masks(struct irq_desc *desc) { }
+#endif
+
+static struct irq_desc *alloc_desc(int irq, int node)
+{
+	struct irq_desc *desc;
+	gfp_t gfp = GFP_KERNEL;
+
+	desc = kzalloc_node(sizeof(*desc), gfp, node);
+	if (!desc)
+		return NULL;
+	desc->kstat_irqs = kzalloc_node(sizeof(*desc->kstat_irqs), gfp, node);
+	if (!desc)
+		goto err_desc;
+
+	if (alloc_masks(desc, gfp, node))
+		goto err_kstat;
+
+	raw_spin_lock_init(&desc->lock);
+	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
+
+	desc_set_defaults(irq, desc, node);
+
+	desc_smp_init(desc, node);
+	return desc;
+
+err_kstat:
+	kfree(desc->kstat_irqs);
+err_desc:
+	kfree(desc);
+	return NULL;
+}
+
+static void free_desc(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+	delete_irq_desc(irq);
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+
+	free_masks(desc);
+	kfree(desc->kstat_irqs);
+	kfree(desc);
+}
+
+static int alloc_descs(unsigned int start, unsigned int cnt, int node)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+	int i;
+
+	for (i = 0; i < cnt; i++) {
+		desc = alloc_desc(start + i, node);
+		if (!desc)
+			goto err;
+		raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+		irq_insert_desc(start + i, desc);
+		raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+	}
+	return start;
+
+err:
+	for (i--; i >= 0; i--)
+		free_desc(start + i);
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+	bitmap_clear(allocated_irqs, start, cnt);
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+	return -ENOMEM;
+}
+
 static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
 	[0 ... NR_IRQS_LEGACY-1] = {
 		.irq	    = -1,
@@ -162,7 +291,7 @@ int __init early_irq_init(void)
 		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
 		alloc_desc_masks(&desc[i], node, true);
 		init_desc_masks(&desc[i]);
-		set_irq_desc(i, &desc[i]);
+		irq_insert_desc(i, &desc[i]);
 	}
 
 	return arch_early_irq_init();
@@ -199,7 +328,7 @@ struct irq_desc * __ref irq_to_desc_allo
 	}
 	init_one_irq_desc(irq, desc, node);
 
-	set_irq_desc(irq, desc);
+	irq_insert_desc(irq, desc);
 
 out_unlock:
 	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
@@ -257,8 +386,89 @@ struct irq_desc *irq_to_desc_alloc_node(
 {
 	return irq_to_desc(irq);
 }
+
+static void free_desc(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&desc->lock, flags);
+#ifdef CONFIG_SMP
+	desc_set_defaults(irq, desc, desc->node);
+#else
+	desc_set_defaults(irq, desc, 0);
+#endif
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+static inline int alloc_descs(unsigned int start, unsigned int cnt, int node)
+{
+	return start;
+}
 #endif /* !CONFIG_SPARSE_IRQ */
 
+/* Dynamic interrupt handling */
+
+/**
+ * irq_free_descs - free irq descriptors
+ * @from:	Start of descriptor range
+ * @cnt:	Number of consecutive irqs to free
+ */
+void irq_free_descs(unsigned int from, unsigned int cnt)
+{
+	unsigned long flags;
+	int i;
+
+	if (from >= nr_irqs || (from + cnt) > nr_irqs)
+		return;
+
+	for (i = 0; i < cnt; i++)
+		free_desc(from + i);
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+	bitmap_clear(allocated_irqs, from, cnt);
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+}
+
+/**
+ * irq_alloc_descs - allocate and initialize a range of irq descriptors
+ * @irq:	Allocate for specific irq number if irq > 0
+ * @from:	Start the search from this irq number
+ * @cnt:	Number of consecutive irqs to allocate.
+ * @node:	Preferred node on which the irq descriptor should be allocated
+ *
+ * Returns the first irq number or error code
+ */
+int __ref
+irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node)
+{
+	unsigned long flags;
+	int start, ret;
+
+	if (!cnt)
+		return -EINVAL;
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+
+	start = bitmap_find_next_zero_area(allocated_irqs, nr_irqs, from, cnt, 0);
+	ret = -EEXIST;
+	if (irq && start != irq)
+		goto err;
+
+	ret = -ENOMEM;
+	if (start >= nr_irqs)
+		goto err;
+
+	bitmap_set(allocated_irqs, start, cnt);
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+	return alloc_descs(start, cnt, node);
+
+err:
+	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
+	return ret;
+}
+
+/* Statistics access */
 void clear_kstat_irqs(struct irq_desc *desc)
 {
 	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));



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

* [patch 15/47] genirq: Prepare proc for real sparse irq support
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (13 preceding siblings ...)
  2010-09-30 23:15 ` [patch 14/47] genirq: Implement a sane sparse_irq allocator Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15 ` [patch 16/47] genirq: Implement sane enumeration Thomas Gleixner
                   ` (35 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-prepare-proc-for-real-sparse.patch --]
[-- Type: text/plain, Size: 2648 bytes --]

/proc/irq never removes any entries, but when irq descriptors can be
freed for real this is necessary. Otherwise we'd reference a freed
descriptor in /proc/irq/N

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/internals.h |    2 ++
 kernel/irq/irqdesc.c   |    2 ++
 kernel/irq/proc.c      |   18 ++++++++++++++++++
 3 files changed, 22 insertions(+)

Index: linux-2.6-tip/kernel/irq/internals.h
===================================================================
--- linux-2.6-tip.orig/kernel/irq/internals.h
+++ linux-2.6-tip/kernel/irq/internals.h
@@ -26,10 +26,12 @@ void replace_irq_desc(unsigned int irq, 
 
 #ifdef CONFIG_PROC_FS
 extern void register_irq_proc(unsigned int irq, struct irq_desc *desc);
+extern void unregister_irq_proc(unsigned int irq, struct irq_desc *desc);
 extern void register_handler_proc(unsigned int irq, struct irqaction *action);
 extern void unregister_handler_proc(unsigned int irq, struct irqaction *action);
 #else
 static inline void register_irq_proc(unsigned int irq, struct irq_desc *desc) { }
+static inline void unregister_irq_proc(unsigned int irq, struct irq_desc *desc); { }
 static inline void register_handler_proc(unsigned int irq,
 					 struct irqaction *action) { }
 static inline void unregister_handler_proc(unsigned int irq,
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -210,6 +210,8 @@ static void free_desc(unsigned int irq)
 	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned long flags;
 
+	unregister_irq_proc(irq, desc);
+
 	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
 	delete_irq_desc(irq);
 	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
Index: linux-2.6-tip/kernel/irq/proc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/proc.c
+++ linux-2.6-tip/kernel/irq/proc.c
@@ -297,6 +297,24 @@ void register_irq_proc(unsigned int irq,
 			 &irq_spurious_proc_fops, (void *)(long)irq);
 }
 
+void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)
+{
+	char name [MAX_NAMELEN];
+
+	if (!root_irq_dir || !desc->dir)
+		return;
+#ifdef CONFIG_SMP
+	remove_proc_entry("smp_affinity", desc->dir);
+	remove_proc_entry("affinity_hint", desc->dir);
+	remove_proc_entry("node", desc->dir);
+#endif
+	remove_proc_entry("spurious", desc->dir);
+
+	memset(name, 0, MAX_NAMELEN);
+	sprintf(name, "%u", irq);
+	remove_proc_entry(name, root_irq_dir);
+}
+
 #undef MAX_NAMELEN
 
 void unregister_handler_proc(unsigned int irq, struct irqaction *action)

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

* [patch 16/47] genirq: Implement sane enumeration
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (14 preceding siblings ...)
  2010-09-30 23:15 ` [patch 15/47] genirq: Prepare proc for real sparse irq support Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
  2010-10-03 10:55   ` Grant Likely
  2010-09-30 23:15 ` [patch 17/47] genirq-update-kerneldoc.patch Thomas Gleixner
                   ` (34 subsequent siblings)
  50 siblings, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-implement-sane-enumeration.patch --]
[-- Type: text/plain, Size: 1765 bytes --]

Use the allocator bitmap to lookup active interrupts.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irqnr.h |    5 +++++
 kernel/irq/irqdesc.c  |   17 +++++++++++++++++
 2 files changed, 22 insertions(+)

Index: linux-2.6-tip/include/linux/irqnr.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irqnr.h
+++ linux-2.6-tip/include/linux/irqnr.h
@@ -25,6 +25,7 @@
 
 extern int nr_irqs;
 extern struct irq_desc *irq_to_desc(unsigned int irq);
+unsigned int irq_get_next_irq(unsigned int offset);
 
 # define for_each_irq_desc(irq, desc)					\
 	for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs;		\
@@ -47,6 +48,10 @@ extern struct irq_desc *irq_to_desc(unsi
 #define irq_node(irq)	0
 #endif
 
+# define for_each_active_irq(irq)			\
+	for (irq = irq_get_next_irq(0); irq < nr_irqs;	\
+	     irq = irq_get_next_irq(irq))
+
 #endif /* CONFIG_GENERIC_HARDIRQS */
 
 #define for_each_irq_nr(irq)                   \
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -470,6 +470,23 @@ err:
 	return ret;
 }
 
+/**
+ * irq_get_next_irq - get next allocated irq number
+ * @offset:	where to start the search
+ *
+ * Returns next irq number after offset or nr_irqs if none is found.
+ */
+unsigned int irq_get_next_irq(unsigned int offset)
+{
+	unsigned long flags;
+	unsigned int res;
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+	res = find_next_bit_set(allocated_irqs, nr_irqs, offset);
+	raw_spin_unlock_irqsave(&sparse_irq_lock, flags);
+	return res;
+}
+
 /* Statistics access */
 void clear_kstat_irqs(struct irq_desc *desc)
 {

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

* [patch 16/47] genirq: Implement sane enumeration
  2010-09-30 23:15 ` [patch 16/47] genirq: Implement sane enumeration Thomas Gleixner
@ 2010-09-30 23:15   ` Thomas Gleixner
  2010-10-03 10:55   ` Grant Likely
  1 sibling, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-implement-sane-enumeration.patch --]
[-- Type: text/plain, Size: 1767 bytes --]

Use the allocator bitmap to lookup active interrupts.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irqnr.h |    5 +++++
 kernel/irq/irqdesc.c  |   17 +++++++++++++++++
 2 files changed, 22 insertions(+)

Index: linux-2.6-tip/include/linux/irqnr.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irqnr.h
+++ linux-2.6-tip/include/linux/irqnr.h
@@ -25,6 +25,7 @@
 
 extern int nr_irqs;
 extern struct irq_desc *irq_to_desc(unsigned int irq);
+unsigned int irq_get_next_irq(unsigned int offset);
 
 # define for_each_irq_desc(irq, desc)					\
 	for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs;		\
@@ -47,6 +48,10 @@ extern struct irq_desc *irq_to_desc(unsi
 #define irq_node(irq)	0
 #endif
 
+# define for_each_active_irq(irq)			\
+	for (irq = irq_get_next_irq(0); irq < nr_irqs;	\
+	     irq = irq_get_next_irq(irq))
+
 #endif /* CONFIG_GENERIC_HARDIRQS */
 
 #define for_each_irq_nr(irq)                   \
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -470,6 +470,23 @@ err:
 	return ret;
 }
 
+/**
+ * irq_get_next_irq - get next allocated irq number
+ * @offset:	where to start the search
+ *
+ * Returns next irq number after offset or nr_irqs if none is found.
+ */
+unsigned int irq_get_next_irq(unsigned int offset)
+{
+	unsigned long flags;
+	unsigned int res;
+
+	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
+	res = find_next_bit_set(allocated_irqs, nr_irqs, offset);
+	raw_spin_unlock_irqsave(&sparse_irq_lock, flags);
+	return res;
+}
+
 /* Statistics access */
 void clear_kstat_irqs(struct irq_desc *desc)
 {



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

* [patch 17/47] genirq-update-kerneldoc.patch
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (15 preceding siblings ...)
  2010-09-30 23:15 ` [patch 16/47] genirq: Implement sane enumeration Thomas Gleixner
@ 2010-09-30 23:15 ` Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 18/47] genirq: Use sane sparse allocator Thomas Gleixner
                   ` (33 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-update-kerneldoc.patch --]
[-- Type: text/plain, Size: 6162 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 Documentation/DocBook/genericirq.tmpl |   82 +++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 31 deletions(-)

Index: linux-2.6-tip/Documentation/DocBook/genericirq.tmpl
===================================================================
--- linux-2.6-tip.orig/Documentation/DocBook/genericirq.tmpl
+++ linux-2.6-tip/Documentation/DocBook/genericirq.tmpl
@@ -28,7 +28,7 @@
   </authorgroup>
 
   <copyright>
-   <year>2005-2006</year>
+   <year>2005-2010</year>
    <holder>Thomas Gleixner</holder>
   </copyright>
   <copyright>
@@ -100,6 +100,10 @@
 	  <listitem><para>Edge type</para></listitem>
 	  <listitem><para>Simple type</para></listitem>
 	</itemizedlist>
+	During the implementation we identified another type:
+	<itemizedlist>
+	  <listitem><para>Fast EOIU type</para></listitem>
+	</itemizedlist>
 	In the SMP world of the __do_IRQ() super-handler another type
 	was identified:
 	<itemizedlist>
@@ -153,6 +157,7 @@
 	is still available. This leads to a kind of duality for the time
 	being. Over time the new model should be used in more and more
 	architectures, as it enables smaller and cleaner IRQ subsystems.
+	It's deprecated for three years now and about to be removed.
 	</para>
   </chapter>
   <chapter id="bugs">
@@ -217,6 +222,7 @@
 	  <itemizedlist>
 	  <listitem><para>handle_level_irq</para></listitem>
 	  <listitem><para>handle_edge_irq</para></listitem>
+	  <listitem><para>handle_fasteoi_irq</para></listitem>
 	  <listitem><para>handle_simple_irq</para></listitem>
 	  <listitem><para>handle_percpu_irq</para></listitem>
 	  </itemizedlist>
@@ -233,33 +239,33 @@
 		are used by the default flow implementations.
 		The following helper functions are implemented (simplified excerpt):
 		<programlisting>
-default_enable(irq)
+default_enable(struct irq_data *data)
 {
-	desc->chip->unmask(irq);
+	desc->chip->irq_unmask(data);
 }
 
-default_disable(irq)
+default_disable(struct irq_data *data)
 {
-	if (!delay_disable(irq))
-		desc->chip->mask(irq);
+	if (!delay_disable(data))
+		desc->chip->irq_mask(data);
 }
 
-default_ack(irq)
+default_ack(struct irq_data *data)
 {
-	chip->ack(irq);
+	chip->irq_ack(data);
 }
 
-default_mask_ack(irq)
+default_mask_ack(struct irq_data *data)
 {
-	if (chip->mask_ack) {
-		chip->mask_ack(irq);
+	if (chip->irq_mask_ack) {
+		chip->irq_mask_ack(data);
 	} else {
-		chip->mask(irq);
-		chip->ack(irq);
+		chip->irq_mask(data);
+		chip->irq_ack(data);
 	}
 }
 
-noop(irq)
+noop(struct irq_data *data))
 {
 }
 
@@ -278,9 +284,24 @@ noop(irq)
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-desc->chip->start();
+desc->chip->irq_mask();
+handle_IRQ_event(desc->action);
+desc->chip->irq_unmask();
+		</programlisting>
+		</para>
+   	    </sect3>
+	    <sect3 id="Default_FASTEOI_IRQ_flow_handler">
+	 	<title>Default Fast EOI IRQ flow handler</title>
+		<para>
+		handle_fasteoi_irq provides a generic implementation
+		for interrupts, which only need an EOI at the end of
+		the handler
+		</para>
+		<para>
+		The following control flow is implemented (simplified excerpt):
+		<programlisting>
 handle_IRQ_event(desc->action);
-desc->chip->end();
+desc->chip->irq_eoi();
 		</programlisting>
 		</para>
    	    </sect3>
@@ -294,20 +315,19 @@ desc->chip->end();
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
 if (desc->status &amp; running) {
-	desc->chip->hold();
+	desc->chip->irq_mask();
 	desc->status |= pending | masked;
 	return;
 }
-desc->chip->start();
+desc->chip->irq_ack();
 desc->status |= running;
 do {
 	if (desc->status &amp; masked)
-		desc->chip->enable();
+		desc->chip->irq_unmask();
 	desc->status &amp;= ~pending;
 	handle_IRQ_event(desc->action);
 } while (status &amp; pending);
 desc->status &amp;= ~running;
-desc->chip->end();
 		</programlisting>
 		</para>
    	    </sect3>
@@ -342,9 +362,9 @@ handle_IRQ_event(desc->action);
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-desc->chip->start();
 handle_IRQ_event(desc->action);
-desc->chip->end();
+if (desc->chip->irq_eoi)
+        desc->chip->irq_eoi();
 		</programlisting>
 		</para>
    	    </sect3>
@@ -375,8 +395,7 @@ desc->chip->end();
 	mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when
 	you want to use the delayed interrupt disable feature and your
 	hardware is not capable of retriggering	an interrupt.)
-	The delayed interrupt disable can be runtime enabled, per interrupt,
-	by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field.
+	The delayed interrupt disable is not configurable.
 	</para>
 	</sect2>
     </sect1>
@@ -387,13 +406,13 @@ desc->chip->end();
 	contains all the direct chip relevant functions, which
 	can be utilized by the irq flow implementations.
 	  <itemizedlist>
-	  <listitem><para>ack()</para></listitem>
-	  <listitem><para>mask_ack() - Optional, recommended for performance</para></listitem>
-	  <listitem><para>mask()</para></listitem>
-	  <listitem><para>unmask()</para></listitem>
-	  <listitem><para>retrigger() - Optional</para></listitem>
-	  <listitem><para>set_type() - Optional</para></listitem>
-	  <listitem><para>set_wake() - Optional</para></listitem>
+	  <listitem><para>irq_ack()</para></listitem>
+	  <listitem><para>irq_mask_ack() - Optional, recommended for performance</para></listitem>
+	  <listitem><para>irq_mask()</para></listitem>
+	  <listitem><para>irq_unmask()</para></listitem>
+	  <listitem><para>irq_retrigger() - Optional</para></listitem>
+	  <listitem><para>irq_set_type() - Optional</para></listitem>
+	  <listitem><para>irq_set_wake() - Optional</para></listitem>
 	  </itemizedlist>
 	These primitives are strictly intended to mean what they say: ack means
 	ACK, masking means masking of an IRQ line, etc. It is up to the flow
@@ -449,6 +468,7 @@ desc->chip->end();
      This chapter contains the autogenerated documentation of the kernel API functions
       which are exported.
      </para>
+!Ekernel/irq/irqdesc.c
 !Ekernel/irq/manage.c
 !Ekernel/irq/chip.c
   </chapter>

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

* [patch 17/47] genirq-update-kerneldoc.patch
  2010-09-30 23:15 ` [patch 17/47] genirq-update-kerneldoc.patch Thomas Gleixner
@ 2010-09-30 23:15   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:15 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-update-kerneldoc.patch --]
[-- Type: text/plain, Size: 6164 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 Documentation/DocBook/genericirq.tmpl |   82 +++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 31 deletions(-)

Index: linux-2.6-tip/Documentation/DocBook/genericirq.tmpl
===================================================================
--- linux-2.6-tip.orig/Documentation/DocBook/genericirq.tmpl
+++ linux-2.6-tip/Documentation/DocBook/genericirq.tmpl
@@ -28,7 +28,7 @@
   </authorgroup>
 
   <copyright>
-   <year>2005-2006</year>
+   <year>2005-2010</year>
    <holder>Thomas Gleixner</holder>
   </copyright>
   <copyright>
@@ -100,6 +100,10 @@
 	  <listitem><para>Edge type</para></listitem>
 	  <listitem><para>Simple type</para></listitem>
 	</itemizedlist>
+	During the implementation we identified another type:
+	<itemizedlist>
+	  <listitem><para>Fast EOIU type</para></listitem>
+	</itemizedlist>
 	In the SMP world of the __do_IRQ() super-handler another type
 	was identified:
 	<itemizedlist>
@@ -153,6 +157,7 @@
 	is still available. This leads to a kind of duality for the time
 	being. Over time the new model should be used in more and more
 	architectures, as it enables smaller and cleaner IRQ subsystems.
+	It's deprecated for three years now and about to be removed.
 	</para>
   </chapter>
   <chapter id="bugs">
@@ -217,6 +222,7 @@
 	  <itemizedlist>
 	  <listitem><para>handle_level_irq</para></listitem>
 	  <listitem><para>handle_edge_irq</para></listitem>
+	  <listitem><para>handle_fasteoi_irq</para></listitem>
 	  <listitem><para>handle_simple_irq</para></listitem>
 	  <listitem><para>handle_percpu_irq</para></listitem>
 	  </itemizedlist>
@@ -233,33 +239,33 @@
 		are used by the default flow implementations.
 		The following helper functions are implemented (simplified excerpt):
 		<programlisting>
-default_enable(irq)
+default_enable(struct irq_data *data)
 {
-	desc->chip->unmask(irq);
+	desc->chip->irq_unmask(data);
 }
 
-default_disable(irq)
+default_disable(struct irq_data *data)
 {
-	if (!delay_disable(irq))
-		desc->chip->mask(irq);
+	if (!delay_disable(data))
+		desc->chip->irq_mask(data);
 }
 
-default_ack(irq)
+default_ack(struct irq_data *data)
 {
-	chip->ack(irq);
+	chip->irq_ack(data);
 }
 
-default_mask_ack(irq)
+default_mask_ack(struct irq_data *data)
 {
-	if (chip->mask_ack) {
-		chip->mask_ack(irq);
+	if (chip->irq_mask_ack) {
+		chip->irq_mask_ack(data);
 	} else {
-		chip->mask(irq);
-		chip->ack(irq);
+		chip->irq_mask(data);
+		chip->irq_ack(data);
 	}
 }
 
-noop(irq)
+noop(struct irq_data *data))
 {
 }
 
@@ -278,9 +284,24 @@ noop(irq)
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-desc->chip->start();
+desc->chip->irq_mask();
+handle_IRQ_event(desc->action);
+desc->chip->irq_unmask();
+		</programlisting>
+		</para>
+   	    </sect3>
+	    <sect3 id="Default_FASTEOI_IRQ_flow_handler">
+	 	<title>Default Fast EOI IRQ flow handler</title>
+		<para>
+		handle_fasteoi_irq provides a generic implementation
+		for interrupts, which only need an EOI at the end of
+		the handler
+		</para>
+		<para>
+		The following control flow is implemented (simplified excerpt):
+		<programlisting>
 handle_IRQ_event(desc->action);
-desc->chip->end();
+desc->chip->irq_eoi();
 		</programlisting>
 		</para>
    	    </sect3>
@@ -294,20 +315,19 @@ desc->chip->end();
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
 if (desc->status &amp; running) {
-	desc->chip->hold();
+	desc->chip->irq_mask();
 	desc->status |= pending | masked;
 	return;
 }
-desc->chip->start();
+desc->chip->irq_ack();
 desc->status |= running;
 do {
 	if (desc->status &amp; masked)
-		desc->chip->enable();
+		desc->chip->irq_unmask();
 	desc->status &amp;= ~pending;
 	handle_IRQ_event(desc->action);
 } while (status &amp; pending);
 desc->status &amp;= ~running;
-desc->chip->end();
 		</programlisting>
 		</para>
    	    </sect3>
@@ -342,9 +362,9 @@ handle_IRQ_event(desc->action);
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-desc->chip->start();
 handle_IRQ_event(desc->action);
-desc->chip->end();
+if (desc->chip->irq_eoi)
+        desc->chip->irq_eoi();
 		</programlisting>
 		</para>
    	    </sect3>
@@ -375,8 +395,7 @@ desc->chip->end();
 	mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when
 	you want to use the delayed interrupt disable feature and your
 	hardware is not capable of retriggering	an interrupt.)
-	The delayed interrupt disable can be runtime enabled, per interrupt,
-	by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field.
+	The delayed interrupt disable is not configurable.
 	</para>
 	</sect2>
     </sect1>
@@ -387,13 +406,13 @@ desc->chip->end();
 	contains all the direct chip relevant functions, which
 	can be utilized by the irq flow implementations.
 	  <itemizedlist>
-	  <listitem><para>ack()</para></listitem>
-	  <listitem><para>mask_ack() - Optional, recommended for performance</para></listitem>
-	  <listitem><para>mask()</para></listitem>
-	  <listitem><para>unmask()</para></listitem>
-	  <listitem><para>retrigger() - Optional</para></listitem>
-	  <listitem><para>set_type() - Optional</para></listitem>
-	  <listitem><para>set_wake() - Optional</para></listitem>
+	  <listitem><para>irq_ack()</para></listitem>
+	  <listitem><para>irq_mask_ack() - Optional, recommended for performance</para></listitem>
+	  <listitem><para>irq_mask()</para></listitem>
+	  <listitem><para>irq_unmask()</para></listitem>
+	  <listitem><para>irq_retrigger() - Optional</para></listitem>
+	  <listitem><para>irq_set_type() - Optional</para></listitem>
+	  <listitem><para>irq_set_wake() - Optional</para></listitem>
 	  </itemizedlist>
 	These primitives are strictly intended to mean what they say: ack means
 	ACK, masking means masking of an IRQ line, etc. It is up to the flow
@@ -449,6 +468,7 @@ desc->chip->end();
      This chapter contains the autogenerated documentation of the kernel API functions
       which are exported.
      </para>
+!Ekernel/irq/irqdesc.c
 !Ekernel/irq/manage.c
 !Ekernel/irq/chip.c
   </chapter>



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

* [patch 18/47] genirq: Use sane sparse allocator
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (16 preceding siblings ...)
  2010-09-30 23:15 ` [patch 17/47] genirq-update-kerneldoc.patch Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 19/47] genirq: Query arch for number of early descriptors Thomas Gleixner
                   ` (32 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-use-sane-allocator.patch --]
[-- Type: text/plain, Size: 5715 bytes --]

Make irq_to_desc_alloc_node() a wrapper around the new allocator.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/irqdesc.c |  133 ++++++---------------------------------------------
 1 file changed, 17 insertions(+), 116 deletions(-)

Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -85,15 +85,6 @@ static DECLARE_BITMAP(allocated_irqs, NR
 
 #ifdef CONFIG_SPARSE_IRQ
 
-static struct irq_desc irq_desc_init = {
-	.irq	    = -1,
-	.status	    = IRQ_DEFAULT_INIT_FLAGS,
-	.chip	    = &no_irq_chip,
-	.handle_irq = handle_bad_irq,
-	.depth      = 1,
-	.lock       = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-};
-
 void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
 {
 	void *ptr;
@@ -111,32 +102,6 @@ void __ref init_kstat_irqs(struct irq_de
 	}
 }
 
-static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
-{
-	memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
-
-	raw_spin_lock_init(&desc->lock);
-	desc->irq = irq;
-	desc->irq_data.irq = irq;
-	desc->irq_data.chip = desc->chip;
-#ifdef CONFIG_SMP
-	desc->node = node;
-	desc->irq_data.affinity = &desc->affinity;
-#endif
-	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	init_kstat_irqs(desc, node, nr_cpu_ids);
-	if (!desc->kstat_irqs) {
-		printk(KERN_ERR "can not alloc kstat_irqs\n");
-		BUG_ON(1);
-	}
-	if (!alloc_desc_masks(desc, node, false)) {
-		printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
-		BUG_ON(1);
-	}
-	init_desc_masks(desc);
-	arch_init_chip_data(desc, node);
-}
-
 static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
 
 static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
@@ -178,7 +143,7 @@ static inline void free_masks(struct irq
 static struct irq_desc *alloc_desc(int irq, int node)
 {
 	struct irq_desc *desc;
-	gfp_t gfp = GFP_KERNEL;
+	gfp_t gfp = GFP_ATOMIC;
 
 	desc = kzalloc_node(sizeof(*desc), gfp, node);
 	if (!desc)
@@ -231,6 +196,8 @@ static int alloc_descs(unsigned int star
 		desc = alloc_desc(start + i, node);
 		if (!desc)
 			goto err;
+		/* temporary until I fixed x86 madness */
+		arch_init_chip_data(desc, node);
 		raw_spin_lock_irqsave(&sparse_irq_lock, flags);
 		irq_insert_desc(start + i, desc);
 		raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
@@ -247,25 +214,19 @@ err:
 	return -ENOMEM;
 }
 
-static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
-	[0 ... NR_IRQS_LEGACY-1] = {
-		.irq	    = -1,
-		.status	    = IRQ_DEFAULT_INIT_FLAGS,
-		.chip	    = &no_irq_chip,
-		.handle_irq = handle_bad_irq,
-		.depth	    = 1,
-		.lock	    = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-	}
-};
+struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
+{
+	int res = irq_alloc_descs(irq, irq, 1, node);
 
-static unsigned int *kstat_irqs_legacy;
+	if (res == -EEXIST || res == irq)
+		return irq_to_desc(irq);
+	return NULL;
+}
 
 int __init early_irq_init(void)
 {
+	int i, node = first_online_node;
 	struct irq_desc *desc;
-	int legacy_count;
-	int node;
-	int i;
 
 	init_irq_default_affinity();
 
@@ -273,71 +234,14 @@ int __init early_irq_init(void)
 	arch_probe_nr_irqs();
 	printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
 
-	desc = irq_desc_legacy;
-	legacy_count = ARRAY_SIZE(irq_desc_legacy);
-	node = first_online_node;
-
-	/* allocate based on nr_cpu_ids */
-	kstat_irqs_legacy = kzalloc_node(NR_IRQS_LEGACY * nr_cpu_ids *
-					  sizeof(int), GFP_NOWAIT, node);
-
-	for (i = 0; i < legacy_count; i++) {
-		desc[i].irq = i;
-		desc[i].irq_data.irq = i;
-		desc[i].irq_data.chip = desc[i].chip;
-#ifdef CONFIG_SMP
-		desc[i].node = node;
-		desc[i].irq_data.affinity = &desc[i].affinity;
-#endif
-		desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
-		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
-		alloc_desc_masks(&desc[i], node, true);
-		init_desc_masks(&desc[i]);
-		irq_insert_desc(i, &desc[i]);
+	for (i = 0; i < NR_IRQS_LEGACY; i++) {
+		desc = alloc_desc(i, node);
+		set_bit(i, allocated_irqs);
+		irq_insert_desc(i, desc);
 	}
-
 	return arch_early_irq_init();
 }
 
-struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
-{
-	struct irq_desc *desc;
-	unsigned long flags;
-
-	if (irq >= nr_irqs) {
-		WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
-			irq, nr_irqs);
-		return NULL;
-	}
-
-	desc = irq_to_desc(irq);
-	if (desc)
-		return desc;
-
-	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
-
-	/* We have to check it to avoid races with another CPU */
-	desc = irq_to_desc(irq);
-	if (desc)
-		goto out_unlock;
-
-	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
-
-	printk(KERN_DEBUG "  alloc irq_desc for %d on node %d\n", irq, node);
-	if (!desc) {
-		printk(KERN_ERR "can not alloc irq_desc\n");
-		BUG_ON(1);
-	}
-	init_one_irq_desc(irq, desc, node);
-
-	irq_insert_desc(irq, desc);
-
-out_unlock:
-	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
-
-	return desc;
-}
-
 #else /* !CONFIG_SPARSE_IRQ */
 
 struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
@@ -368,12 +272,9 @@ int __init early_irq_init(void)
 		desc[i].irq = i;
 		desc[i].irq_data.irq = i;
 		desc[i].irq_data.chip = desc[i].chip;
-#ifdef CONFIG_SMP
-		desc[i].irq_data.affinity = &desc[i].affinity;
-#endif
-		alloc_desc_masks(&desc[i], 0, true);
-		init_desc_masks(&desc[i]);
 		desc[i].kstat_irqs = kstat_irqs_all[i];
+		alloc_masks(desc + 1, GFP_KERNEL, first_online_node);
+		desc_smp_init(desc + i, first_online_node);
 		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
 	}
 	return arch_early_irq_init();

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

* [patch 18/47] genirq: Use sane sparse allocator
  2010-09-30 23:16 ` [patch 18/47] genirq: Use sane sparse allocator Thomas Gleixner
@ 2010-09-30 23:16   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-use-sane-allocator.patch --]
[-- Type: text/plain, Size: 5717 bytes --]

Make irq_to_desc_alloc_node() a wrapper around the new allocator.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/irqdesc.c |  133 ++++++---------------------------------------------
 1 file changed, 17 insertions(+), 116 deletions(-)

Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -85,15 +85,6 @@ static DECLARE_BITMAP(allocated_irqs, NR
 
 #ifdef CONFIG_SPARSE_IRQ
 
-static struct irq_desc irq_desc_init = {
-	.irq	    = -1,
-	.status	    = IRQ_DEFAULT_INIT_FLAGS,
-	.chip	    = &no_irq_chip,
-	.handle_irq = handle_bad_irq,
-	.depth      = 1,
-	.lock       = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-};
-
 void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
 {
 	void *ptr;
@@ -111,32 +102,6 @@ void __ref init_kstat_irqs(struct irq_de
 	}
 }
 
-static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
-{
-	memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
-
-	raw_spin_lock_init(&desc->lock);
-	desc->irq = irq;
-	desc->irq_data.irq = irq;
-	desc->irq_data.chip = desc->chip;
-#ifdef CONFIG_SMP
-	desc->node = node;
-	desc->irq_data.affinity = &desc->affinity;
-#endif
-	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	init_kstat_irqs(desc, node, nr_cpu_ids);
-	if (!desc->kstat_irqs) {
-		printk(KERN_ERR "can not alloc kstat_irqs\n");
-		BUG_ON(1);
-	}
-	if (!alloc_desc_masks(desc, node, false)) {
-		printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
-		BUG_ON(1);
-	}
-	init_desc_masks(desc);
-	arch_init_chip_data(desc, node);
-}
-
 static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
 
 static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
@@ -178,7 +143,7 @@ static inline void free_masks(struct irq
 static struct irq_desc *alloc_desc(int irq, int node)
 {
 	struct irq_desc *desc;
-	gfp_t gfp = GFP_KERNEL;
+	gfp_t gfp = GFP_ATOMIC;
 
 	desc = kzalloc_node(sizeof(*desc), gfp, node);
 	if (!desc)
@@ -231,6 +196,8 @@ static int alloc_descs(unsigned int star
 		desc = alloc_desc(start + i, node);
 		if (!desc)
 			goto err;
+		/* temporary until I fixed x86 madness */
+		arch_init_chip_data(desc, node);
 		raw_spin_lock_irqsave(&sparse_irq_lock, flags);
 		irq_insert_desc(start + i, desc);
 		raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
@@ -247,25 +214,19 @@ err:
 	return -ENOMEM;
 }
 
-static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
-	[0 ... NR_IRQS_LEGACY-1] = {
-		.irq	    = -1,
-		.status	    = IRQ_DEFAULT_INIT_FLAGS,
-		.chip	    = &no_irq_chip,
-		.handle_irq = handle_bad_irq,
-		.depth	    = 1,
-		.lock	    = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-	}
-};
+struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
+{
+	int res = irq_alloc_descs(irq, irq, 1, node);
 
-static unsigned int *kstat_irqs_legacy;
+	if (res == -EEXIST || res == irq)
+		return irq_to_desc(irq);
+	return NULL;
+}
 
 int __init early_irq_init(void)
 {
+	int i, node = first_online_node;
 	struct irq_desc *desc;
-	int legacy_count;
-	int node;
-	int i;
 
 	init_irq_default_affinity();
 
@@ -273,71 +234,14 @@ int __init early_irq_init(void)
 	arch_probe_nr_irqs();
 	printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
 
-	desc = irq_desc_legacy;
-	legacy_count = ARRAY_SIZE(irq_desc_legacy);
-	node = first_online_node;
-
-	/* allocate based on nr_cpu_ids */
-	kstat_irqs_legacy = kzalloc_node(NR_IRQS_LEGACY * nr_cpu_ids *
-					  sizeof(int), GFP_NOWAIT, node);
-
-	for (i = 0; i < legacy_count; i++) {
-		desc[i].irq = i;
-		desc[i].irq_data.irq = i;
-		desc[i].irq_data.chip = desc[i].chip;
-#ifdef CONFIG_SMP
-		desc[i].node = node;
-		desc[i].irq_data.affinity = &desc[i].affinity;
-#endif
-		desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
-		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
-		alloc_desc_masks(&desc[i], node, true);
-		init_desc_masks(&desc[i]);
-		irq_insert_desc(i, &desc[i]);
+	for (i = 0; i < NR_IRQS_LEGACY; i++) {
+		desc = alloc_desc(i, node);
+		set_bit(i, allocated_irqs);
+		irq_insert_desc(i, desc);
 	}
-
 	return arch_early_irq_init();
 }
 
-struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
-{
-	struct irq_desc *desc;
-	unsigned long flags;
-
-	if (irq >= nr_irqs) {
-		WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
-			irq, nr_irqs);
-		return NULL;
-	}
-
-	desc = irq_to_desc(irq);
-	if (desc)
-		return desc;
-
-	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
-
-	/* We have to check it to avoid races with another CPU */
-	desc = irq_to_desc(irq);
-	if (desc)
-		goto out_unlock;
-
-	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
-
-	printk(KERN_DEBUG "  alloc irq_desc for %d on node %d\n", irq, node);
-	if (!desc) {
-		printk(KERN_ERR "can not alloc irq_desc\n");
-		BUG_ON(1);
-	}
-	init_one_irq_desc(irq, desc, node);
-
-	irq_insert_desc(irq, desc);
-
-out_unlock:
-	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
-
-	return desc;
-}
-
 #else /* !CONFIG_SPARSE_IRQ */
 
 struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
@@ -368,12 +272,9 @@ int __init early_irq_init(void)
 		desc[i].irq = i;
 		desc[i].irq_data.irq = i;
 		desc[i].irq_data.chip = desc[i].chip;
-#ifdef CONFIG_SMP
-		desc[i].irq_data.affinity = &desc[i].affinity;
-#endif
-		alloc_desc_masks(&desc[i], 0, true);
-		init_desc_masks(&desc[i]);
 		desc[i].kstat_irqs = kstat_irqs_all[i];
+		alloc_masks(desc + 1, GFP_KERNEL, first_online_node);
+		desc_smp_init(desc + i, first_online_node);
 		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
 	}
 	return arch_early_irq_init();



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

* [patch 19/47] genirq: Query arch for number of early descriptors
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (17 preceding siblings ...)
  2010-09-30 23:16 ` [patch 18/47] genirq: Use sane sparse allocator Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 20/47] x86: Remove useless reinitialization of irq descriptors Thomas Gleixner
                   ` (31 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-ask-arch-for-number-of-irqs-to-init.patch --]
[-- Type: text/plain, Size: 3048 bytes --]

sparse irq sets up NR_IRQS_LEGACY irq descriptors and archs then go
ahead and allocate more.

Use the unused return value of arch_probe_nr_irqs() to let the
architecture return the number of early allocations. Fix up all users.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/kernel/irq.c          |    8 +-------
 arch/sh/kernel/irq.c           |    2 +-
 arch/x86/kernel/apic/io_apic.c |    2 +-
 kernel/irq/irqdesc.c           |    6 +++---
 kernel/softirq.c               |    2 +-
 5 files changed, 7 insertions(+), 13 deletions(-)

Index: linux-2.6-tip/arch/arm/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/kernel/irq.c
+++ linux-2.6-tip/arch/arm/kernel/irq.c
@@ -148,12 +148,6 @@ void set_irq_flags(unsigned int irq, uns
 
 void __init init_IRQ(void)
 {
-	struct irq_desc *desc;
-	int irq;
-
-	for (irq = 0; irq < nr_irqs; irq++)
-		desc = irq_to_desc_alloc_node(irq, 0);
-
 	init_arch_irq();
 }
 
@@ -161,7 +155,7 @@ void __init init_IRQ(void)
 int __init arch_probe_nr_irqs(void)
 {
 	nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS;
-	return 0;
+	return nr_irqs;
 }
 #endif
 
Index: linux-2.6-tip/arch/sh/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/sh/kernel/irq.c
+++ linux-2.6-tip/arch/sh/kernel/irq.c
@@ -290,7 +290,7 @@ void __init init_IRQ(void)
 int __init arch_probe_nr_irqs(void)
 {
 	nr_irqs = sh_mv.mv_nr_irqs;
-	return 0;
+	return NR_IRQS_LEGACY;
 }
 #endif
 
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3886,7 +3886,7 @@ int __init arch_probe_nr_irqs(void)
 	if (nr < nr_irqs)
 		nr_irqs = nr;
 
-	return 0;
+	return nr_irqs_gsi;
 }
 #endif
 
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -225,16 +225,16 @@ struct irq_desc * __ref irq_to_desc_allo
 
 int __init early_irq_init(void)
 {
-	int i, node = first_online_node;
+	int i, initcnt, node = first_online_node;
 	struct irq_desc *desc;
 
 	init_irq_default_affinity();
 
 	 /* initialize nr_irqs based on nr_cpu_ids */
-	arch_probe_nr_irqs();
+	initcnt = arch_probe_nr_irqs();
 	printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
 
-	for (i = 0; i < NR_IRQS_LEGACY; i++) {
+	for (i = 0; i < initcnt; i++) {
 		desc = alloc_desc(i, node);
 		set_bit(i, allocated_irqs);
 		irq_insert_desc(i, desc);
Index: linux-2.6-tip/kernel/softirq.c
===================================================================
--- linux-2.6-tip.orig/kernel/softirq.c
+++ linux-2.6-tip/kernel/softirq.c
@@ -888,7 +888,7 @@ int __init __weak early_irq_init(void)
 
 int __init __weak arch_probe_nr_irqs(void)
 {
-	return 0;
+	return NR_IRQS_LEGACY;
 }
 
 int __init __weak arch_early_irq_init(void)

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

* [patch 19/47] genirq: Query arch for number of early descriptors
  2010-09-30 23:16 ` [patch 19/47] genirq: Query arch for number of early descriptors Thomas Gleixner
@ 2010-09-30 23:16   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-ask-arch-for-number-of-irqs-to-init.patch --]
[-- Type: text/plain, Size: 3050 bytes --]

sparse irq sets up NR_IRQS_LEGACY irq descriptors and archs then go
ahead and allocate more.

Use the unused return value of arch_probe_nr_irqs() to let the
architecture return the number of early allocations. Fix up all users.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/kernel/irq.c          |    8 +-------
 arch/sh/kernel/irq.c           |    2 +-
 arch/x86/kernel/apic/io_apic.c |    2 +-
 kernel/irq/irqdesc.c           |    6 +++---
 kernel/softirq.c               |    2 +-
 5 files changed, 7 insertions(+), 13 deletions(-)

Index: linux-2.6-tip/arch/arm/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/kernel/irq.c
+++ linux-2.6-tip/arch/arm/kernel/irq.c
@@ -148,12 +148,6 @@ void set_irq_flags(unsigned int irq, uns
 
 void __init init_IRQ(void)
 {
-	struct irq_desc *desc;
-	int irq;
-
-	for (irq = 0; irq < nr_irqs; irq++)
-		desc = irq_to_desc_alloc_node(irq, 0);
-
 	init_arch_irq();
 }
 
@@ -161,7 +155,7 @@ void __init init_IRQ(void)
 int __init arch_probe_nr_irqs(void)
 {
 	nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS;
-	return 0;
+	return nr_irqs;
 }
 #endif
 
Index: linux-2.6-tip/arch/sh/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/sh/kernel/irq.c
+++ linux-2.6-tip/arch/sh/kernel/irq.c
@@ -290,7 +290,7 @@ void __init init_IRQ(void)
 int __init arch_probe_nr_irqs(void)
 {
 	nr_irqs = sh_mv.mv_nr_irqs;
-	return 0;
+	return NR_IRQS_LEGACY;
 }
 #endif
 
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3886,7 +3886,7 @@ int __init arch_probe_nr_irqs(void)
 	if (nr < nr_irqs)
 		nr_irqs = nr;
 
-	return 0;
+	return nr_irqs_gsi;
 }
 #endif
 
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -225,16 +225,16 @@ struct irq_desc * __ref irq_to_desc_allo
 
 int __init early_irq_init(void)
 {
-	int i, node = first_online_node;
+	int i, initcnt, node = first_online_node;
 	struct irq_desc *desc;
 
 	init_irq_default_affinity();
 
 	 /* initialize nr_irqs based on nr_cpu_ids */
-	arch_probe_nr_irqs();
+	initcnt = arch_probe_nr_irqs();
 	printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
 
-	for (i = 0; i < NR_IRQS_LEGACY; i++) {
+	for (i = 0; i < initcnt; i++) {
 		desc = alloc_desc(i, node);
 		set_bit(i, allocated_irqs);
 		irq_insert_desc(i, desc);
Index: linux-2.6-tip/kernel/softirq.c
===================================================================
--- linux-2.6-tip.orig/kernel/softirq.c
+++ linux-2.6-tip/kernel/softirq.c
@@ -888,7 +888,7 @@ int __init __weak early_irq_init(void)
 
 int __init __weak arch_probe_nr_irqs(void)
 {
-	return 0;
+	return NR_IRQS_LEGACY;
 }
 
 int __init __weak arch_early_irq_init(void)



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

* [patch 20/47] x86: Remove useless reinitialization of irq descriptors
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (18 preceding siblings ...)
  2010-09-30 23:16 ` [patch 19/47] genirq: Query arch for number of early descriptors Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
  2010-10-03 15:21   ` Eric W. Biederman
  2010-09-30 23:16 ` [patch 21/47] x86: Sanitize apb timer interrupt handling Thomas Gleixner
                   ` (30 subsequent siblings)
  50 siblings, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-remove-useless-gunk.patch --]
[-- Type: text/plain, Size: 1234 bytes --]

The descriptors are already initialized in exaclty this way.

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

Index: linux-2.6-tip/arch/x86/kernel/irqinit.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/irqinit.c
+++ linux-2.6-tip/arch/x86/kernel/irqinit.c
@@ -100,6 +100,8 @@ int vector_used_by_percpu_irq(unsigned i
 
 void __init init_ISA_irqs(void)
 {
+	struct irq_chip *chip = legacy_pic->chip;
+	const char *name = chip->name;
 	int i;
 
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
@@ -107,19 +109,8 @@ void __init init_ISA_irqs(void)
 #endif
 	legacy_pic->init(0);
 
-	/*
-	 * 16 old-style INTA-cycle interrupts:
-	 */
-	for (i = 0; i < legacy_pic->nr_legacy_irqs; i++) {
-		struct irq_desc *desc = irq_to_desc(i);
-
-		desc->status = IRQ_DISABLED;
-		desc->action = NULL;
-		desc->depth = 1;
-
-		set_irq_chip_and_handler_name(i, &i8259A_chip,
-					      handle_level_irq, "XT");
-	}
+	for (i = 0; i < legacy_pic->nr_legacy_irqs; i++)
+		set_irq_chip_and_handler_name(i, chip, handle_level_irq, name);
 }
 
 void __init init_IRQ(void)

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

* [patch 20/47] x86: Remove useless reinitialization of irq descriptors
  2010-09-30 23:16 ` [patch 20/47] x86: Remove useless reinitialization of irq descriptors Thomas Gleixner
@ 2010-09-30 23:16   ` Thomas Gleixner
  2010-10-03 15:21   ` Eric W. Biederman
  1 sibling, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-remove-useless-gunk.patch --]
[-- Type: text/plain, Size: 1236 bytes --]

The descriptors are already initialized in exaclty this way.

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

Index: linux-2.6-tip/arch/x86/kernel/irqinit.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/irqinit.c
+++ linux-2.6-tip/arch/x86/kernel/irqinit.c
@@ -100,6 +100,8 @@ int vector_used_by_percpu_irq(unsigned i
 
 void __init init_ISA_irqs(void)
 {
+	struct irq_chip *chip = legacy_pic->chip;
+	const char *name = chip->name;
 	int i;
 
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
@@ -107,19 +109,8 @@ void __init init_ISA_irqs(void)
 #endif
 	legacy_pic->init(0);
 
-	/*
-	 * 16 old-style INTA-cycle interrupts:
-	 */
-	for (i = 0; i < legacy_pic->nr_legacy_irqs; i++) {
-		struct irq_desc *desc = irq_to_desc(i);
-
-		desc->status = IRQ_DISABLED;
-		desc->action = NULL;
-		desc->depth = 1;
-
-		set_irq_chip_and_handler_name(i, &i8259A_chip,
-					      handle_level_irq, "XT");
-	}
+	for (i = 0; i < legacy_pic->nr_legacy_irqs; i++)
+		set_irq_chip_and_handler_name(i, chip, handle_level_irq, name);
 }
 
 void __init init_IRQ(void)



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

* [patch 21/47] x86: Sanitize apb timer interrupt handling
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (19 preceding siblings ...)
  2010-09-30 23:16 ` [patch 20/47] x86: Remove useless reinitialization of irq descriptors Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 22/47] x86: lguest: Convert to new irq chip functions Thomas Gleixner
                   ` (29 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-sanitize-abptimer.patch --]
[-- Type: text/plain, Size: 2758 bytes --]

Disable the interrupt in CPU_DEAD where it belongs. Remove the
open coded irq_desc manipulation.

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

Index: linux-2.6-tip/arch/x86/kernel/apb_timer.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apb_timer.c
+++ linux-2.6-tip/arch/x86/kernel/apb_timer.c
@@ -231,34 +231,6 @@ static void apbt_restart_clocksource(str
 	apbt_start_counter(phy_cs_timer_id);
 }
 
-/* Setup IRQ routing via IOAPIC */
-#ifdef CONFIG_SMP
-static void apbt_setup_irq(struct apbt_dev *adev)
-{
-	struct irq_chip *chip;
-	struct irq_desc *desc;
-
-	/* timer0 irq has been setup early */
-	if (adev->irq == 0)
-		return;
-	desc = irq_to_desc(adev->irq);
-	chip = get_irq_chip(adev->irq);
-	disable_irq(adev->irq);
-	desc->status |= IRQ_MOVE_PCNTXT;
-	irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
-	/* APB timer irqs are set up as mp_irqs, timer is edge triggerred */
-	set_irq_chip_and_handler_name(adev->irq, chip, handle_edge_irq, "edge");
-	enable_irq(adev->irq);
-	if (system_state == SYSTEM_BOOTING)
-		if (request_irq(adev->irq, apbt_interrupt_handler,
-				IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
-				adev->name, adev)) {
-			printk(KERN_ERR "Failed request IRQ for APBT%d\n",
-			       adev->num);
-		}
-}
-#endif
-
 static void apbt_enable_int(int n)
 {
 	unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
@@ -334,6 +306,27 @@ static int __init apbt_clockevent_regist
 }
 
 #ifdef CONFIG_SMP
+
+static void apbt_setup_irq(struct apbt_dev *adev)
+{
+	/* timer0 irq has been setup early */
+	if (adev->irq == 0)
+		return;
+
+	if (system_state == SYSTEM_BOOTING) {
+		irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT);
+		/* APB timer irqs are set up as mp_irqs, timer is edge type */
+		__set_irq_handler(adev->irq, handle_edge_irq, 0, "edge");
+		if (request_irq(adev->irq, apbt_interrupt_handler,
+				IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
+				adev->name, adev)) {
+			printk(KERN_ERR "Failed request IRQ for APBT%d\n",
+			       adev->num);
+		}
+	} else
+		enable_irq(adev->irq);
+}
+
 /* Should be called with per cpu */
 void apbt_setup_secondary_clock(void)
 {
@@ -389,10 +382,11 @@ static int apbt_cpuhp_notify(struct noti
 
 	switch (action & 0xf) {
 	case CPU_DEAD:
+		disable_irq(adev->irq);
 		apbt_disable_int(cpu);
-		if (system_state == SYSTEM_RUNNING)
+		if (system_state == SYSTEM_RUNNING) {
 			pr_debug("skipping APBT CPU %lu offline\n", cpu);
-		else if (adev) {
+		}else if (adev) {
 			pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
 			free_irq(adev->irq, adev);
 		}

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

* [patch 21/47] x86: Sanitize apb timer interrupt handling
  2010-09-30 23:16 ` [patch 21/47] x86: Sanitize apb timer interrupt handling Thomas Gleixner
@ 2010-09-30 23:16   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-sanitize-abptimer.patch --]
[-- Type: text/plain, Size: 2760 bytes --]

Disable the interrupt in CPU_DEAD where it belongs. Remove the
open coded irq_desc manipulation.

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

Index: linux-2.6-tip/arch/x86/kernel/apb_timer.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apb_timer.c
+++ linux-2.6-tip/arch/x86/kernel/apb_timer.c
@@ -231,34 +231,6 @@ static void apbt_restart_clocksource(str
 	apbt_start_counter(phy_cs_timer_id);
 }
 
-/* Setup IRQ routing via IOAPIC */
-#ifdef CONFIG_SMP
-static void apbt_setup_irq(struct apbt_dev *adev)
-{
-	struct irq_chip *chip;
-	struct irq_desc *desc;
-
-	/* timer0 irq has been setup early */
-	if (adev->irq == 0)
-		return;
-	desc = irq_to_desc(adev->irq);
-	chip = get_irq_chip(adev->irq);
-	disable_irq(adev->irq);
-	desc->status |= IRQ_MOVE_PCNTXT;
-	irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
-	/* APB timer irqs are set up as mp_irqs, timer is edge triggerred */
-	set_irq_chip_and_handler_name(adev->irq, chip, handle_edge_irq, "edge");
-	enable_irq(adev->irq);
-	if (system_state == SYSTEM_BOOTING)
-		if (request_irq(adev->irq, apbt_interrupt_handler,
-				IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
-				adev->name, adev)) {
-			printk(KERN_ERR "Failed request IRQ for APBT%d\n",
-			       adev->num);
-		}
-}
-#endif
-
 static void apbt_enable_int(int n)
 {
 	unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
@@ -334,6 +306,27 @@ static int __init apbt_clockevent_regist
 }
 
 #ifdef CONFIG_SMP
+
+static void apbt_setup_irq(struct apbt_dev *adev)
+{
+	/* timer0 irq has been setup early */
+	if (adev->irq == 0)
+		return;
+
+	if (system_state == SYSTEM_BOOTING) {
+		irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT);
+		/* APB timer irqs are set up as mp_irqs, timer is edge type */
+		__set_irq_handler(adev->irq, handle_edge_irq, 0, "edge");
+		if (request_irq(adev->irq, apbt_interrupt_handler,
+				IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
+				adev->name, adev)) {
+			printk(KERN_ERR "Failed request IRQ for APBT%d\n",
+			       adev->num);
+		}
+	} else
+		enable_irq(adev->irq);
+}
+
 /* Should be called with per cpu */
 void apbt_setup_secondary_clock(void)
 {
@@ -389,10 +382,11 @@ static int apbt_cpuhp_notify(struct noti
 
 	switch (action & 0xf) {
 	case CPU_DEAD:
+		disable_irq(adev->irq);
 		apbt_disable_int(cpu);
-		if (system_state == SYSTEM_RUNNING)
+		if (system_state == SYSTEM_RUNNING) {
 			pr_debug("skipping APBT CPU %lu offline\n", cpu);
-		else if (adev) {
+		}else if (adev) {
 			pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
 			free_irq(adev->irq, adev);
 		}



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

* [patch 22/47] x86: lguest: Convert to new irq chip functions
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (20 preceding siblings ...)
  2010-09-30 23:16 ` [patch 21/47] x86: Sanitize apb timer interrupt handling Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 23/47] x86: Cleanup visws interrupt handling Thomas Gleixner
                   ` (28 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-convert-virt.patch --]
[-- Type: text/plain, Size: 1339 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/lguest/boot.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

Index: linux-2.6-tip/arch/x86/lguest/boot.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/lguest/boot.c
+++ linux-2.6-tip/arch/x86/lguest/boot.c
@@ -788,22 +788,22 @@ static void lguest_flush_tlb_kernel(void
  * simple as setting a bit.  We don't actually "ack" interrupts as such, we
  * just mask and unmask them.  I wonder if we should be cleverer?
  */
-static void disable_lguest_irq(unsigned int irq)
+static void disable_lguest_irq(struct irq_data *data)
 {
-	set_bit(irq, lguest_data.blocked_interrupts);
+	set_bit(data->irq, lguest_data.blocked_interrupts);
 }
 
-static void enable_lguest_irq(unsigned int irq)
+static void enable_lguest_irq(struct irq_data *data)
 {
-	clear_bit(irq, lguest_data.blocked_interrupts);
+	clear_bit(data->irq, lguest_data.blocked_interrupts);
 }
 
 /* This structure describes the lguest IRQ controller. */
 static struct irq_chip lguest_irq_controller = {
 	.name		= "lguest",
-	.mask		= disable_lguest_irq,
-	.mask_ack	= disable_lguest_irq,
-	.unmask		= enable_lguest_irq,
+	.irq_mask	= disable_lguest_irq,
+	.irq_mask_ack	= disable_lguest_irq,
+	.irq_unmask	= enable_lguest_irq,
 };
 
 /*

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

* [patch 23/47] x86: Cleanup visws interrupt handling
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (21 preceding siblings ...)
  2010-09-30 23:16 ` [patch 22/47] x86: lguest: Convert to new irq chip functions Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 24/47] x86: i8259: Convert to new irq_chip functions Thomas Gleixner
                   ` (27 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-cleanup-visws.patch --]
[-- Type: text/plain, Size: 6778 bytes --]

Remove the open coded access to irq_desc and convert to the new irq
chip functions. Change the mask function of piix4_virtual_irq_type so
we can use the generic irq handling function for the virtual interrupt
instead of open coding it.

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

Index: linux-2.6-tip/arch/x86/kernel/visws_quirks.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/visws_quirks.c
+++ linux-2.6-tip/arch/x86/kernel/visws_quirks.c
@@ -66,10 +66,7 @@ static void __init visws_time_init(void)
 }
 
 /* Replaces the default init_ISA_irqs in the generic setup */
-static void __init visws_pre_intr_init(void)
-{
-	init_VISWS_APIC_irqs();
-}
+static void __init visws_pre_intr_init(void);
 
 /* Quirk for machine specific memory setup. */
 
@@ -429,67 +426,34 @@ static int is_co_apic(unsigned int irq)
 /*
  * This is the SGI Cobalt (IO-)APIC:
  */
-
-static void enable_cobalt_irq(unsigned int irq)
+static void enable_cobalt_irq(struct irq_data *data)
 {
-	co_apic_set(is_co_apic(irq), irq);
+	co_apic_set(is_co_apic(data->irq), data->irq);
 }
 
-static void disable_cobalt_irq(unsigned int irq)
+static void disable_cobalt_irq(struct irq_data *data)
 {
-	int entry = is_co_apic(irq);
+	int entry = is_co_apic(data->irq);
 
 	co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK);
 	co_apic_read(CO_APIC_LO(entry));
 }
 
-/*
- * "irq" really just serves to identify the device.  Here is where we
- * map this to the Cobalt APIC entry where it's physically wired.
- * This is called via request_irq -> setup_irq -> irq_desc->startup()
- */
-static unsigned int startup_cobalt_irq(unsigned int irq)
-{
-	unsigned long flags;
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	spin_lock_irqsave(&cobalt_lock, flags);
-	if ((desc->status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
-		desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
-	enable_cobalt_irq(irq);
-	spin_unlock_irqrestore(&cobalt_lock, flags);
-	return 0;
-}
-
-static void ack_cobalt_irq(unsigned int irq)
+static void ack_cobalt_irq(struct irq_data *data)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&cobalt_lock, flags);
-	disable_cobalt_irq(irq);
+	disable_cobalt_irq(data);
 	apic_write(APIC_EOI, APIC_EIO_ACK);
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
-static void end_cobalt_irq(unsigned int irq)
-{
-	unsigned long flags;
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	spin_lock_irqsave(&cobalt_lock, flags);
-	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		enable_cobalt_irq(irq);
-	spin_unlock_irqrestore(&cobalt_lock, flags);
-}
-
 static struct irq_chip cobalt_irq_type = {
-	.name =		"Cobalt-APIC",
-	.startup =	startup_cobalt_irq,
-	.shutdown =	disable_cobalt_irq,
-	.enable =	enable_cobalt_irq,
-	.disable =	disable_cobalt_irq,
-	.ack =		ack_cobalt_irq,
-	.end =		end_cobalt_irq,
+	.name		= "Cobalt-APIC",
+	.irq_enable	= enable_cobalt_irq,
+	.irq_disable	= disable_cobalt_irq,
+	.irq_ack	= ack_cobalt_irq,
 };
 
 
@@ -503,35 +467,34 @@ static struct irq_chip cobalt_irq_type =
  * interrupt controller type, and through a special virtual interrupt-
  * controller. Device drivers only see the virtual interrupt sources.
  */
-static unsigned int startup_piix4_master_irq(unsigned int irq)
+static unsigned int startup_piix4_master_irq(struct irq_data *data)
 {
 	legacy_pic->init(0);
-
-	return startup_cobalt_irq(irq);
+	enable_cobalt_irq(data);
 }
 
-static void end_piix4_master_irq(unsigned int irq)
+static void end_piix4_master_irq(struct irq_data *data)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&cobalt_lock, flags);
-	enable_cobalt_irq(irq);
+	enable_cobalt_irq(data);
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
 static struct irq_chip piix4_master_irq_type = {
-	.name =		"PIIX4-master",
-	.startup =	startup_piix4_master_irq,
-	.ack =		ack_cobalt_irq,
-	.end =		end_piix4_master_irq,
+	.name		= "PIIX4-master",
+	.irq_startup	= startup_piix4_master_irq,
+	.irq_ack	= ack_cobalt_irq,
 };
 
+static void pii4_mask(struct irq_data *data) { }
 
 static struct irq_chip piix4_virtual_irq_type = {
-	.name =		"PIIX4-virtual",
+	.name		= "PIIX4-virtual",
+	.mask		= pii4_mask,
 };
 
-
 /*
  * PIIX4-8259 master/virtual functions to handle interrupt requests
  * from legacy devices: floppy, parallel, serial, rtc.
@@ -549,9 +512,8 @@ static struct irq_chip piix4_virtual_irq
  */
 static irqreturn_t piix4_master_intr(int irq, void *dev_id)
 {
-	int realirq;
-	struct irq_desc *desc;
 	unsigned long flags;
+	int realirq;
 
 	raw_spin_lock_irqsave(&i8259A_lock, flags);
 
@@ -592,18 +554,10 @@ static irqreturn_t piix4_master_intr(int
 
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 
-	desc = irq_to_desc(realirq);
-
 	/*
 	 * handle this 'virtual interrupt' as a Cobalt one now.
 	 */
-	kstat_incr_irqs_this_cpu(realirq, desc);
-
-	if (likely(desc->action != NULL))
-		handle_IRQ_event(realirq, desc->action);
-
-	if (!(desc->status & IRQ_DISABLED))
-		legacy_pic->chip->unmask(realirq);
+	generic_handle_irq(realirq);
 
 	return IRQ_HANDLED;
 
@@ -624,41 +578,35 @@ static struct irqaction cascade_action =
 
 static inline void set_piix4_virtual_irq_type(void)
 {
-	piix4_virtual_irq_type.shutdown = i8259A_chip.mask;
 	piix4_virtual_irq_type.enable =	i8259A_chip.unmask;
 	piix4_virtual_irq_type.disable = i8259A_chip.mask;
+	piix4_virtual_irq_type.unmask =	i8259A_chip.unmask;
 }
 
-void init_VISWS_APIC_irqs(void)
+static void __init visws_pre_intr_init(void)
 {
 	int i;
 
+	set_piix4_virtual_irq_type();
+
 	for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
-		struct irq_desc *desc = irq_to_desc(i);
+		struct irq_chip *chip = NULL;
 
-		desc->status = IRQ_DISABLED;
-		desc->action = 0;
-		desc->depth = 1;
+		if (i == 0)
+			chip = &cobalt_irq_type;
+		else if (i == CO_IRQ_IDE0)
+			chip = &cobalt_irq_type;
+		else if (i == CO_IRQ_IDE1)
+			>chip = &cobalt_irq_type;
+		else if (i == CO_IRQ_8259)
+			chip = &piix4_master_irq_type;
+		else if (i < CO_IRQ_APIC0)
+			chip = &piix4_virtual_irq_type;
+		else if (IS_CO_APIC(i))
+			chip = &cobalt_irq_type;
 
-		if (i == 0) {
-			desc->chip = &cobalt_irq_type;
-		}
-		else if (i == CO_IRQ_IDE0) {
-			desc->chip = &cobalt_irq_type;
-		}
-		else if (i == CO_IRQ_IDE1) {
-			desc->chip = &cobalt_irq_type;
-		}
-		else if (i == CO_IRQ_8259) {
-			desc->chip = &piix4_master_irq_type;
-		}
-		else if (i < CO_IRQ_APIC0) {
-			set_piix4_virtual_irq_type();
-			desc->chip = &piix4_virtual_irq_type;
-		}
-		else if (IS_CO_APIC(i)) {
-			desc->chip = &cobalt_irq_type;
-		}
+		if (chip)
+			set_irq_chip(i, chip);
 	}
 
 	setup_irq(CO_IRQ_8259, &master_action);

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

* [patch 23/47] x86: Cleanup visws interrupt handling
  2010-09-30 23:16 ` [patch 23/47] x86: Cleanup visws interrupt handling Thomas Gleixner
@ 2010-09-30 23:16   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-cleanup-visws.patch --]
[-- Type: text/plain, Size: 6780 bytes --]

Remove the open coded access to irq_desc and convert to the new irq
chip functions. Change the mask function of piix4_virtual_irq_type so
we can use the generic irq handling function for the virtual interrupt
instead of open coding it.

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

Index: linux-2.6-tip/arch/x86/kernel/visws_quirks.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/visws_quirks.c
+++ linux-2.6-tip/arch/x86/kernel/visws_quirks.c
@@ -66,10 +66,7 @@ static void __init visws_time_init(void)
 }
 
 /* Replaces the default init_ISA_irqs in the generic setup */
-static void __init visws_pre_intr_init(void)
-{
-	init_VISWS_APIC_irqs();
-}
+static void __init visws_pre_intr_init(void);
 
 /* Quirk for machine specific memory setup. */
 
@@ -429,67 +426,34 @@ static int is_co_apic(unsigned int irq)
 /*
  * This is the SGI Cobalt (IO-)APIC:
  */
-
-static void enable_cobalt_irq(unsigned int irq)
+static void enable_cobalt_irq(struct irq_data *data)
 {
-	co_apic_set(is_co_apic(irq), irq);
+	co_apic_set(is_co_apic(data->irq), data->irq);
 }
 
-static void disable_cobalt_irq(unsigned int irq)
+static void disable_cobalt_irq(struct irq_data *data)
 {
-	int entry = is_co_apic(irq);
+	int entry = is_co_apic(data->irq);
 
 	co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK);
 	co_apic_read(CO_APIC_LO(entry));
 }
 
-/*
- * "irq" really just serves to identify the device.  Here is where we
- * map this to the Cobalt APIC entry where it's physically wired.
- * This is called via request_irq -> setup_irq -> irq_desc->startup()
- */
-static unsigned int startup_cobalt_irq(unsigned int irq)
-{
-	unsigned long flags;
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	spin_lock_irqsave(&cobalt_lock, flags);
-	if ((desc->status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
-		desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
-	enable_cobalt_irq(irq);
-	spin_unlock_irqrestore(&cobalt_lock, flags);
-	return 0;
-}
-
-static void ack_cobalt_irq(unsigned int irq)
+static void ack_cobalt_irq(struct irq_data *data)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&cobalt_lock, flags);
-	disable_cobalt_irq(irq);
+	disable_cobalt_irq(data);
 	apic_write(APIC_EOI, APIC_EIO_ACK);
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
-static void end_cobalt_irq(unsigned int irq)
-{
-	unsigned long flags;
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	spin_lock_irqsave(&cobalt_lock, flags);
-	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		enable_cobalt_irq(irq);
-	spin_unlock_irqrestore(&cobalt_lock, flags);
-}
-
 static struct irq_chip cobalt_irq_type = {
-	.name =		"Cobalt-APIC",
-	.startup =	startup_cobalt_irq,
-	.shutdown =	disable_cobalt_irq,
-	.enable =	enable_cobalt_irq,
-	.disable =	disable_cobalt_irq,
-	.ack =		ack_cobalt_irq,
-	.end =		end_cobalt_irq,
+	.name		= "Cobalt-APIC",
+	.irq_enable	= enable_cobalt_irq,
+	.irq_disable	= disable_cobalt_irq,
+	.irq_ack	= ack_cobalt_irq,
 };
 
 
@@ -503,35 +467,34 @@ static struct irq_chip cobalt_irq_type =
  * interrupt controller type, and through a special virtual interrupt-
  * controller. Device drivers only see the virtual interrupt sources.
  */
-static unsigned int startup_piix4_master_irq(unsigned int irq)
+static unsigned int startup_piix4_master_irq(struct irq_data *data)
 {
 	legacy_pic->init(0);
-
-	return startup_cobalt_irq(irq);
+	enable_cobalt_irq(data);
 }
 
-static void end_piix4_master_irq(unsigned int irq)
+static void end_piix4_master_irq(struct irq_data *data)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&cobalt_lock, flags);
-	enable_cobalt_irq(irq);
+	enable_cobalt_irq(data);
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
 static struct irq_chip piix4_master_irq_type = {
-	.name =		"PIIX4-master",
-	.startup =	startup_piix4_master_irq,
-	.ack =		ack_cobalt_irq,
-	.end =		end_piix4_master_irq,
+	.name		= "PIIX4-master",
+	.irq_startup	= startup_piix4_master_irq,
+	.irq_ack	= ack_cobalt_irq,
 };
 
+static void pii4_mask(struct irq_data *data) { }
 
 static struct irq_chip piix4_virtual_irq_type = {
-	.name =		"PIIX4-virtual",
+	.name		= "PIIX4-virtual",
+	.mask		= pii4_mask,
 };
 
-
 /*
  * PIIX4-8259 master/virtual functions to handle interrupt requests
  * from legacy devices: floppy, parallel, serial, rtc.
@@ -549,9 +512,8 @@ static struct irq_chip piix4_virtual_irq
  */
 static irqreturn_t piix4_master_intr(int irq, void *dev_id)
 {
-	int realirq;
-	struct irq_desc *desc;
 	unsigned long flags;
+	int realirq;
 
 	raw_spin_lock_irqsave(&i8259A_lock, flags);
 
@@ -592,18 +554,10 @@ static irqreturn_t piix4_master_intr(int
 
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 
-	desc = irq_to_desc(realirq);
-
 	/*
 	 * handle this 'virtual interrupt' as a Cobalt one now.
 	 */
-	kstat_incr_irqs_this_cpu(realirq, desc);
-
-	if (likely(desc->action != NULL))
-		handle_IRQ_event(realirq, desc->action);
-
-	if (!(desc->status & IRQ_DISABLED))
-		legacy_pic->chip->unmask(realirq);
+	generic_handle_irq(realirq);
 
 	return IRQ_HANDLED;
 
@@ -624,41 +578,35 @@ static struct irqaction cascade_action =
 
 static inline void set_piix4_virtual_irq_type(void)
 {
-	piix4_virtual_irq_type.shutdown = i8259A_chip.mask;
 	piix4_virtual_irq_type.enable =	i8259A_chip.unmask;
 	piix4_virtual_irq_type.disable = i8259A_chip.mask;
+	piix4_virtual_irq_type.unmask =	i8259A_chip.unmask;
 }
 
-void init_VISWS_APIC_irqs(void)
+static void __init visws_pre_intr_init(void)
 {
 	int i;
 
+	set_piix4_virtual_irq_type();
+
 	for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
-		struct irq_desc *desc = irq_to_desc(i);
+		struct irq_chip *chip = NULL;
 
-		desc->status = IRQ_DISABLED;
-		desc->action = 0;
-		desc->depth = 1;
+		if (i == 0)
+			chip = &cobalt_irq_type;
+		else if (i == CO_IRQ_IDE0)
+			chip = &cobalt_irq_type;
+		else if (i == CO_IRQ_IDE1)
+			>chip = &cobalt_irq_type;
+		else if (i == CO_IRQ_8259)
+			chip = &piix4_master_irq_type;
+		else if (i < CO_IRQ_APIC0)
+			chip = &piix4_virtual_irq_type;
+		else if (IS_CO_APIC(i))
+			chip = &cobalt_irq_type;
 
-		if (i == 0) {
-			desc->chip = &cobalt_irq_type;
-		}
-		else if (i == CO_IRQ_IDE0) {
-			desc->chip = &cobalt_irq_type;
-		}
-		else if (i == CO_IRQ_IDE1) {
-			desc->chip = &cobalt_irq_type;
-		}
-		else if (i == CO_IRQ_8259) {
-			desc->chip = &piix4_master_irq_type;
-		}
-		else if (i < CO_IRQ_APIC0) {
-			set_piix4_virtual_irq_type();
-			desc->chip = &piix4_virtual_irq_type;
-		}
-		else if (IS_CO_APIC(i)) {
-			desc->chip = &cobalt_irq_type;
-		}
+		if (chip)
+			set_irq_chip(i, chip);
 	}
 
 	setup_irq(CO_IRQ_8259, &master_action);



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

* [patch 24/47] x86: i8259: Convert to new irq_chip functions
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (22 preceding siblings ...)
  2010-09-30 23:16 ` [patch 23/47] x86: Cleanup visws interrupt handling Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 25/47] x86: Cleanup io_apic Thomas Gleixner
                   ` (26 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-convert-i8259.patch --]
[-- Type: text/plain, Size: 8876 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/i8259.h   |    2 +
 arch/x86/kernel/apic/io_apic.c |   20 ++++++-------
 arch/x86/kernel/apic/nmi.c     |    2 -
 arch/x86/kernel/i8259.c        |   63 ++++++++++++++++++++---------------------
 arch/x86/kernel/smpboot.c      |    4 +-
 5 files changed, 47 insertions(+), 44 deletions(-)

Index: linux-2.6-tip/arch/x86/include/asm/i8259.h
===================================================================
--- linux-2.6-tip.orig/arch/x86/include/asm/i8259.h
+++ linux-2.6-tip/arch/x86/include/asm/i8259.h
@@ -55,6 +55,8 @@ extern struct irq_chip i8259A_chip;
 struct legacy_pic {
 	int nr_legacy_irqs;
 	struct irq_chip *chip;
+	void (*mask)(unsigned int irq);
+	void (*unmask)(unsigned int irq);
 	void (*mask_all)(void);
 	void (*restore_mask)(void);
 	void (*init)(int auto_eoi);
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -1474,7 +1474,7 @@ static void setup_IO_APIC_irq(int apic_i
 
 	ioapic_register_intr(irq, desc, trigger);
 	if (irq < legacy_pic->nr_legacy_irqs)
-		legacy_pic->chip->mask(irq);
+		legacy_pic->mask(irq);
 
 	ioapic_write_entry(apic_id, pin, entry);
 }
@@ -2248,7 +2248,7 @@ static unsigned int startup_ioapic_irq(u
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	if (irq < legacy_pic->nr_legacy_irqs) {
-		legacy_pic->chip->mask(irq);
+		legacy_pic->mask(irq);
 		if (legacy_pic->irq_pending(irq))
 			was_pending = 1;
 	}
@@ -2943,7 +2943,7 @@ static inline void __init check_timer(vo
 	/*
 	 * get/set the timer IRQ vector:
 	 */
-	legacy_pic->chip->mask(0);
+	legacy_pic->mask(0);
 	assign_irq_vector(0, cfg, apic->target_cpus());
 
 	/*
@@ -3015,7 +3015,7 @@ static inline void __init check_timer(vo
 		if (timer_irq_works()) {
 			if (nmi_watchdog == NMI_IO_APIC) {
 				setup_nmi();
-				legacy_pic->chip->unmask(0);
+				legacy_pic->unmask(0);
 			}
 			if (disable_timer_pin_1 > 0)
 				clear_IO_APIC_pin(0, pin1);
@@ -3038,14 +3038,14 @@ static inline void __init check_timer(vo
 		 */
 		replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2);
 		setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
-		legacy_pic->chip->unmask(0);
+		legacy_pic->unmask(0);
 		if (timer_irq_works()) {
 			apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
 			timer_through_8259 = 1;
 			if (nmi_watchdog == NMI_IO_APIC) {
-				legacy_pic->chip->mask(0);
+				legacy_pic->mask(0);
 				setup_nmi();
-				legacy_pic->chip->unmask(0);
+				legacy_pic->unmask(0);
 			}
 			goto out;
 		}
@@ -3053,7 +3053,7 @@ static inline void __init check_timer(vo
 		 * Cleanup, just in case ...
 		 */
 		local_irq_disable();
-		legacy_pic->chip->mask(0);
+		legacy_pic->mask(0);
 		clear_IO_APIC_pin(apic2, pin2);
 		apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
 	}
@@ -3072,14 +3072,14 @@ static inline void __init check_timer(vo
 
 	lapic_register_intr(0, desc);
 	apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);	/* Fixed mode */
-	legacy_pic->chip->unmask(0);
+	legacy_pic->unmask(0);
 
 	if (timer_irq_works()) {
 		apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
 		goto out;
 	}
 	local_irq_disable();
-	legacy_pic->chip->mask(0);
+	legacy_pic->mask(0);
 	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
 	apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
 
Index: linux-2.6-tip/arch/x86/kernel/apic/nmi.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/nmi.c
+++ linux-2.6-tip/arch/x86/kernel/apic/nmi.c
@@ -178,7 +178,7 @@ int __init check_nmi_watchdog(void)
 error:
 	if (nmi_watchdog == NMI_IO_APIC) {
 		if (!timer_through_8259)
-			legacy_pic->chip->mask(0);
+			legacy_pic->mask(0);
 		on_each_cpu(__acpi_nmi_disable, NULL, 1);
 	}
 
Index: linux-2.6-tip/arch/x86/kernel/i8259.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/i8259.c
+++ linux-2.6-tip/arch/x86/kernel/i8259.c
@@ -29,24 +29,10 @@
  * plus some generic x86 specific things if generic specifics makes
  * any sense at all.
  */
+static void init_8259A(int auto_eoi);
 
 static int i8259A_auto_eoi;
 DEFINE_RAW_SPINLOCK(i8259A_lock);
-static void mask_and_ack_8259A(unsigned int);
-static void mask_8259A(void);
-static void unmask_8259A(void);
-static void disable_8259A_irq(unsigned int irq);
-static void enable_8259A_irq(unsigned int irq);
-static void init_8259A(int auto_eoi);
-static int i8259A_irq_pending(unsigned int irq);
-
-struct irq_chip i8259A_chip = {
-	.name		= "XT-PIC",
-	.mask		= disable_8259A_irq,
-	.disable	= disable_8259A_irq,
-	.unmask		= enable_8259A_irq,
-	.mask_ack	= mask_and_ack_8259A,
-};
 
 /*
  * 8259A PIC functions to handle ISA devices:
@@ -68,7 +54,7 @@ unsigned int cached_irq_mask = 0xffff;
  */
 unsigned long io_apic_irqs;
 
-static void disable_8259A_irq(unsigned int irq)
+static void mask_8259A_irq(unsigned int irq)
 {
 	unsigned int mask = 1 << irq;
 	unsigned long flags;
@@ -82,7 +68,12 @@ static void disable_8259A_irq(unsigned i
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-static void enable_8259A_irq(unsigned int irq)
+static void disable_8259A_irq(struct irq_data *data)
+{
+	mask_8259A_irq(data->irq);
+}
+
+static void unmask_8259A_irq(unsigned int irq)
 {
 	unsigned int mask = ~(1 << irq);
 	unsigned long flags;
@@ -96,6 +87,11 @@ static void enable_8259A_irq(unsigned in
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
+static void enable_8259A_irq(struct irq_data *data)
+{
+	unmask_8259A_irq(data->irq);
+}
+
 static int i8259A_irq_pending(unsigned int irq)
 {
 	unsigned int mask = 1<<irq;
@@ -117,7 +113,7 @@ static void make_8259A_irq(unsigned int 
 	disable_irq_nosync(irq);
 	io_apic_irqs &= ~(1<<irq);
 	set_irq_chip_and_handler_name(irq, &i8259A_chip, handle_level_irq,
-				      "XT");
+				      i8259A_chip.name);
 	enable_irq(irq);
 }
 
@@ -150,8 +146,9 @@ static inline int i8259A_irq_real(unsign
  * first, _then_ send the EOI, and the order of EOI
  * to the two 8259s is important!
  */
-static void mask_and_ack_8259A(unsigned int irq)
+static void mask_and_ack_8259A(struct irq_data *data)
 {
+	unsigned int irq = data->irq;
 	unsigned int irqmask = 1 << irq;
 	unsigned long flags;
 
@@ -223,6 +220,14 @@ spurious_8259A_irq:
 	}
 }
 
+struct irq_chip i8259A_chip = {
+	.name		= "XT-PIC",
+	.irq_mask	= disable_8259A_irq,
+	.irq_disable	= disable_8259A_irq,
+	.irq_unmask	= enable_8259A_irq,
+	.irq_mask_ack	= mask_and_ack_8259A,
+};
+
 static char irq_trigger[2];
 /**
  * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
@@ -342,9 +347,9 @@ static void init_8259A(int auto_eoi)
 		 * In AEOI mode we just have to mask the interrupt
 		 * when acking.
 		 */
-		i8259A_chip.mask_ack = disable_8259A_irq;
+		i8259A_chip.irq_mask_ack = disable_8259A_irq;
 	else
-		i8259A_chip.mask_ack = mask_and_ack_8259A;
+		i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
 
 	udelay(100);		/* wait for 8259A to initialize */
 
@@ -363,14 +368,6 @@ static void init_8259A(int auto_eoi)
 static void legacy_pic_noop(void) { };
 static void legacy_pic_uint_noop(unsigned int unused) { };
 static void legacy_pic_int_noop(int unused) { };
-
-static struct irq_chip dummy_pic_chip  = {
-	.name = "dummy pic",
-	.mask = legacy_pic_uint_noop,
-	.unmask = legacy_pic_uint_noop,
-	.disable = legacy_pic_uint_noop,
-	.mask_ack = legacy_pic_uint_noop,
-};
 static int legacy_pic_irq_pending_noop(unsigned int irq)
 {
 	return 0;
@@ -378,7 +375,9 @@ static int legacy_pic_irq_pending_noop(u
 
 struct legacy_pic null_legacy_pic = {
 	.nr_legacy_irqs = 0,
-	.chip = &dummy_pic_chip,
+	.chip = &dummy_irq_chip,
+	.mask = legacy_pic_uint_noop,
+	.unmask = legacy_pic_uint_noop,
 	.mask_all = legacy_pic_noop,
 	.restore_mask = legacy_pic_noop,
 	.init = legacy_pic_int_noop,
@@ -389,7 +388,9 @@ struct legacy_pic null_legacy_pic = {
 struct legacy_pic default_legacy_pic = {
 	.nr_legacy_irqs = NR_IRQS_LEGACY,
 	.chip  = &i8259A_chip,
-	.mask_all  = mask_8259A,
+	.mask = mask_8259A_irq,
+	.unmask = unmask_8259A_irq,
+	.mask_all = mask_8259A,
 	.restore_mask = unmask_8259A,
 	.init = init_8259A,
 	.irq_pending = i8259A_irq_pending,
Index: linux-2.6-tip/arch/x86/kernel/smpboot.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/smpboot.c
+++ linux-2.6-tip/arch/x86/kernel/smpboot.c
@@ -324,9 +324,9 @@ notrace static void __cpuinit start_seco
 	check_tsc_sync_target();
 
 	if (nmi_watchdog == NMI_IO_APIC) {
-		legacy_pic->chip->mask(0);
+		legacy_pic->mask(0);
 		enable_NMI_through_LVT0();
-		legacy_pic->chip->unmask(0);
+		legacy_pic->unmask(0);
 	}
 
 	/* This must be done before setting cpu_online_mask */

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

* [patch 24/47] x86: i8259: Convert to new irq_chip functions
  2010-09-30 23:16 ` [patch 24/47] x86: i8259: Convert to new irq_chip functions Thomas Gleixner
@ 2010-09-30 23:16   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-convert-i8259.patch --]
[-- Type: text/plain, Size: 8878 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/i8259.h   |    2 +
 arch/x86/kernel/apic/io_apic.c |   20 ++++++-------
 arch/x86/kernel/apic/nmi.c     |    2 -
 arch/x86/kernel/i8259.c        |   63 ++++++++++++++++++++---------------------
 arch/x86/kernel/smpboot.c      |    4 +-
 5 files changed, 47 insertions(+), 44 deletions(-)

Index: linux-2.6-tip/arch/x86/include/asm/i8259.h
===================================================================
--- linux-2.6-tip.orig/arch/x86/include/asm/i8259.h
+++ linux-2.6-tip/arch/x86/include/asm/i8259.h
@@ -55,6 +55,8 @@ extern struct irq_chip i8259A_chip;
 struct legacy_pic {
 	int nr_legacy_irqs;
 	struct irq_chip *chip;
+	void (*mask)(unsigned int irq);
+	void (*unmask)(unsigned int irq);
 	void (*mask_all)(void);
 	void (*restore_mask)(void);
 	void (*init)(int auto_eoi);
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -1474,7 +1474,7 @@ static void setup_IO_APIC_irq(int apic_i
 
 	ioapic_register_intr(irq, desc, trigger);
 	if (irq < legacy_pic->nr_legacy_irqs)
-		legacy_pic->chip->mask(irq);
+		legacy_pic->mask(irq);
 
 	ioapic_write_entry(apic_id, pin, entry);
 }
@@ -2248,7 +2248,7 @@ static unsigned int startup_ioapic_irq(u
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	if (irq < legacy_pic->nr_legacy_irqs) {
-		legacy_pic->chip->mask(irq);
+		legacy_pic->mask(irq);
 		if (legacy_pic->irq_pending(irq))
 			was_pending = 1;
 	}
@@ -2943,7 +2943,7 @@ static inline void __init check_timer(vo
 	/*
 	 * get/set the timer IRQ vector:
 	 */
-	legacy_pic->chip->mask(0);
+	legacy_pic->mask(0);
 	assign_irq_vector(0, cfg, apic->target_cpus());
 
 	/*
@@ -3015,7 +3015,7 @@ static inline void __init check_timer(vo
 		if (timer_irq_works()) {
 			if (nmi_watchdog == NMI_IO_APIC) {
 				setup_nmi();
-				legacy_pic->chip->unmask(0);
+				legacy_pic->unmask(0);
 			}
 			if (disable_timer_pin_1 > 0)
 				clear_IO_APIC_pin(0, pin1);
@@ -3038,14 +3038,14 @@ static inline void __init check_timer(vo
 		 */
 		replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2);
 		setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
-		legacy_pic->chip->unmask(0);
+		legacy_pic->unmask(0);
 		if (timer_irq_works()) {
 			apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
 			timer_through_8259 = 1;
 			if (nmi_watchdog == NMI_IO_APIC) {
-				legacy_pic->chip->mask(0);
+				legacy_pic->mask(0);
 				setup_nmi();
-				legacy_pic->chip->unmask(0);
+				legacy_pic->unmask(0);
 			}
 			goto out;
 		}
@@ -3053,7 +3053,7 @@ static inline void __init check_timer(vo
 		 * Cleanup, just in case ...
 		 */
 		local_irq_disable();
-		legacy_pic->chip->mask(0);
+		legacy_pic->mask(0);
 		clear_IO_APIC_pin(apic2, pin2);
 		apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
 	}
@@ -3072,14 +3072,14 @@ static inline void __init check_timer(vo
 
 	lapic_register_intr(0, desc);
 	apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);	/* Fixed mode */
-	legacy_pic->chip->unmask(0);
+	legacy_pic->unmask(0);
 
 	if (timer_irq_works()) {
 		apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
 		goto out;
 	}
 	local_irq_disable();
-	legacy_pic->chip->mask(0);
+	legacy_pic->mask(0);
 	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
 	apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
 
Index: linux-2.6-tip/arch/x86/kernel/apic/nmi.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/nmi.c
+++ linux-2.6-tip/arch/x86/kernel/apic/nmi.c
@@ -178,7 +178,7 @@ int __init check_nmi_watchdog(void)
 error:
 	if (nmi_watchdog == NMI_IO_APIC) {
 		if (!timer_through_8259)
-			legacy_pic->chip->mask(0);
+			legacy_pic->mask(0);
 		on_each_cpu(__acpi_nmi_disable, NULL, 1);
 	}
 
Index: linux-2.6-tip/arch/x86/kernel/i8259.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/i8259.c
+++ linux-2.6-tip/arch/x86/kernel/i8259.c
@@ -29,24 +29,10 @@
  * plus some generic x86 specific things if generic specifics makes
  * any sense at all.
  */
+static void init_8259A(int auto_eoi);
 
 static int i8259A_auto_eoi;
 DEFINE_RAW_SPINLOCK(i8259A_lock);
-static void mask_and_ack_8259A(unsigned int);
-static void mask_8259A(void);
-static void unmask_8259A(void);
-static void disable_8259A_irq(unsigned int irq);
-static void enable_8259A_irq(unsigned int irq);
-static void init_8259A(int auto_eoi);
-static int i8259A_irq_pending(unsigned int irq);
-
-struct irq_chip i8259A_chip = {
-	.name		= "XT-PIC",
-	.mask		= disable_8259A_irq,
-	.disable	= disable_8259A_irq,
-	.unmask		= enable_8259A_irq,
-	.mask_ack	= mask_and_ack_8259A,
-};
 
 /*
  * 8259A PIC functions to handle ISA devices:
@@ -68,7 +54,7 @@ unsigned int cached_irq_mask = 0xffff;
  */
 unsigned long io_apic_irqs;
 
-static void disable_8259A_irq(unsigned int irq)
+static void mask_8259A_irq(unsigned int irq)
 {
 	unsigned int mask = 1 << irq;
 	unsigned long flags;
@@ -82,7 +68,12 @@ static void disable_8259A_irq(unsigned i
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-static void enable_8259A_irq(unsigned int irq)
+static void disable_8259A_irq(struct irq_data *data)
+{
+	mask_8259A_irq(data->irq);
+}
+
+static void unmask_8259A_irq(unsigned int irq)
 {
 	unsigned int mask = ~(1 << irq);
 	unsigned long flags;
@@ -96,6 +87,11 @@ static void enable_8259A_irq(unsigned in
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
+static void enable_8259A_irq(struct irq_data *data)
+{
+	unmask_8259A_irq(data->irq);
+}
+
 static int i8259A_irq_pending(unsigned int irq)
 {
 	unsigned int mask = 1<<irq;
@@ -117,7 +113,7 @@ static void make_8259A_irq(unsigned int 
 	disable_irq_nosync(irq);
 	io_apic_irqs &= ~(1<<irq);
 	set_irq_chip_and_handler_name(irq, &i8259A_chip, handle_level_irq,
-				      "XT");
+				      i8259A_chip.name);
 	enable_irq(irq);
 }
 
@@ -150,8 +146,9 @@ static inline int i8259A_irq_real(unsign
  * first, _then_ send the EOI, and the order of EOI
  * to the two 8259s is important!
  */
-static void mask_and_ack_8259A(unsigned int irq)
+static void mask_and_ack_8259A(struct irq_data *data)
 {
+	unsigned int irq = data->irq;
 	unsigned int irqmask = 1 << irq;
 	unsigned long flags;
 
@@ -223,6 +220,14 @@ spurious_8259A_irq:
 	}
 }
 
+struct irq_chip i8259A_chip = {
+	.name		= "XT-PIC",
+	.irq_mask	= disable_8259A_irq,
+	.irq_disable	= disable_8259A_irq,
+	.irq_unmask	= enable_8259A_irq,
+	.irq_mask_ack	= mask_and_ack_8259A,
+};
+
 static char irq_trigger[2];
 /**
  * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
@@ -342,9 +347,9 @@ static void init_8259A(int auto_eoi)
 		 * In AEOI mode we just have to mask the interrupt
 		 * when acking.
 		 */
-		i8259A_chip.mask_ack = disable_8259A_irq;
+		i8259A_chip.irq_mask_ack = disable_8259A_irq;
 	else
-		i8259A_chip.mask_ack = mask_and_ack_8259A;
+		i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
 
 	udelay(100);		/* wait for 8259A to initialize */
 
@@ -363,14 +368,6 @@ static void init_8259A(int auto_eoi)
 static void legacy_pic_noop(void) { };
 static void legacy_pic_uint_noop(unsigned int unused) { };
 static void legacy_pic_int_noop(int unused) { };
-
-static struct irq_chip dummy_pic_chip  = {
-	.name = "dummy pic",
-	.mask = legacy_pic_uint_noop,
-	.unmask = legacy_pic_uint_noop,
-	.disable = legacy_pic_uint_noop,
-	.mask_ack = legacy_pic_uint_noop,
-};
 static int legacy_pic_irq_pending_noop(unsigned int irq)
 {
 	return 0;
@@ -378,7 +375,9 @@ static int legacy_pic_irq_pending_noop(u
 
 struct legacy_pic null_legacy_pic = {
 	.nr_legacy_irqs = 0,
-	.chip = &dummy_pic_chip,
+	.chip = &dummy_irq_chip,
+	.mask = legacy_pic_uint_noop,
+	.unmask = legacy_pic_uint_noop,
 	.mask_all = legacy_pic_noop,
 	.restore_mask = legacy_pic_noop,
 	.init = legacy_pic_int_noop,
@@ -389,7 +388,9 @@ struct legacy_pic null_legacy_pic = {
 struct legacy_pic default_legacy_pic = {
 	.nr_legacy_irqs = NR_IRQS_LEGACY,
 	.chip  = &i8259A_chip,
-	.mask_all  = mask_8259A,
+	.mask = mask_8259A_irq,
+	.unmask = unmask_8259A_irq,
+	.mask_all = mask_8259A,
 	.restore_mask = unmask_8259A,
 	.init = init_8259A,
 	.irq_pending = i8259A_irq_pending,
Index: linux-2.6-tip/arch/x86/kernel/smpboot.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/smpboot.c
+++ linux-2.6-tip/arch/x86/kernel/smpboot.c
@@ -324,9 +324,9 @@ notrace static void __cpuinit start_seco
 	check_tsc_sync_target();
 
 	if (nmi_watchdog == NMI_IO_APIC) {
-		legacy_pic->chip->mask(0);
+		legacy_pic->mask(0);
 		enable_NMI_through_LVT0();
-		legacy_pic->chip->unmask(0);
+		legacy_pic->unmask(0);
 	}
 
 	/* This must be done before setting cpu_online_mask */



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

* [patch 25/47] x86: Cleanup io_apic
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (23 preceding siblings ...)
  2010-09-30 23:16 ` [patch 24/47] x86: i8259: Convert to new irq_chip functions Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 26/47] x86: io_apic: Convert startup to new irq_chip function Thomas Gleixner
                   ` (25 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-cleanup-ioapic.patch --]
[-- Type: text/plain, Size: 7804 bytes --]

Sanitize functions. Remove irq_desc pointer magic.
Preparatory patch for further cleanups.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |  109 +++++++++++++++--------------------------
 1 file changed, 42 insertions(+), 67 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -572,11 +572,6 @@ static void __unmask_and_level_IO_APIC_i
 			     IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
 }
 
-static void __unmask_IO_APIC_irq(struct irq_cfg *cfg)
-{
-	io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL);
-}
-
 static void io_apic_sync(struct irq_pin_list *entry)
 {
 	/*
@@ -588,44 +583,41 @@ static void io_apic_sync(struct irq_pin_
 	readl(&io_apic->data);
 }
 
-static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
+static void mask_ioapic(struct irq_cfg *cfg)
 {
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-static void mask_IO_APIC_irq_desc(struct irq_desc *desc)
+static void mask_ioapic_irq(unsigned int irq)
 {
-	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
-	unsigned long flags;
+	struct irq_cfg *cfg = get_irq_chip_data(irq);
 
-	BUG_ON(!cfg);
+	mask_ioapic(cfg);
+}
 
-	raw_spin_lock_irqsave(&ioapic_lock, flags);
-	__mask_IO_APIC_irq(cfg);
-	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
+static void __unmask_ioapic(struct irq_cfg *cfg)
+{
+	io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL);
 }
 
-static void unmask_IO_APIC_irq_desc(struct irq_desc *desc)
+static void unmask_ioapic(struct irq_cfg *cfg)
 {
-	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
-	__unmask_IO_APIC_irq(cfg);
+	__unmask_ioapic(cfg);
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-static void mask_IO_APIC_irq(unsigned int irq)
+static void unmask_ioapic_irq(unsigned int irq)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg = get_irq_chip_data(irq);
 
-	mask_IO_APIC_irq_desc(desc);
-}
-static void unmask_IO_APIC_irq(unsigned int irq)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	unmask_IO_APIC_irq_desc(desc);
+	unmask_ioapic(cfg);
 }
 
 static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
@@ -2253,7 +2245,7 @@ static unsigned int startup_ioapic_irq(u
 			was_pending = 1;
 	}
 	cfg = irq_cfg(irq);
-	__unmask_IO_APIC_irq(cfg);
+	__unmask_ioapic(cfg);
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return was_pending;
@@ -2512,10 +2504,8 @@ unlock:
 	irq_exit();
 }
 
-static void __irq_complete_move(struct irq_desc **descp, unsigned vector)
+static void __irq_complete_move(struct irq_cfg *cfg, unsigned vector)
 {
-	struct irq_desc *desc = *descp;
-	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
 	unsigned me;
 
 	if (likely(!cfg->move_in_progress))
@@ -2527,30 +2517,29 @@ static void __irq_complete_move(struct i
 		send_cleanup_vector(cfg);
 }
 
-static void irq_complete_move(struct irq_desc **descp)
+static void irq_complete_move(struct irq_cfg *cfg)
 {
-	__irq_complete_move(descp, ~get_irq_regs()->orig_ax);
+	__irq_complete_move(cfg, ~get_irq_regs()->orig_ax);
 }
 
 void irq_force_complete_move(int irq)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
+	struct irq_cfg *cfg = get_irq_chip_data(irq);
 
 	if (!cfg)
 		return;
 
-	__irq_complete_move(&desc, cfg->vector);
+	__irq_complete_move(cfg, cfg->vector);
 }
 #else
-static inline void irq_complete_move(struct irq_desc **descp) {}
+static inline void irq_complete_move(struct irq_cfg *cfg) { }
 #endif
 
 static void ack_apic_edge(unsigned int irq)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg = get_irq_chip_data(irq);
 
-	irq_complete_move(&desc);
+	irq_complete_move(cfg);
 	move_native_irq(irq);
 	ack_APIC_irq();
 }
@@ -2573,10 +2562,12 @@ atomic_t irq_mis_count;
  * Otherwise, we simulate the EOI message manually by changing the trigger
  * mode to edge and then back to level, with RTE being masked during this.
 */
-static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
+static void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
 {
 	struct irq_pin_list *entry;
+	unsigned long flags;
 
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	for_each_irq_pin(entry, cfg->irq_2_pin) {
 		if (mp_ioapics[entry->apic].apicver >= 0x20) {
 			/*
@@ -2594,36 +2585,22 @@ static void __eoi_ioapic_irq(unsigned in
 			__unmask_and_level_IO_APIC_irq(entry);
 		}
 	}
-}
-
-static void eoi_ioapic_irq(struct irq_desc *desc)
-{
-	struct irq_cfg *cfg;
-	unsigned long flags;
-	unsigned int irq;
-
-	irq = desc->irq;
-	cfg = get_irq_desc_chip_data(desc);
-
-	raw_spin_lock_irqsave(&ioapic_lock, flags);
-	__eoi_ioapic_irq(irq, cfg);
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
 static void ack_apic_level(unsigned int irq)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
+	int i, do_unmask_irq = 0;
 	unsigned long v;
-	int i;
-	struct irq_cfg *cfg;
-	int do_unmask_irq = 0;
 
-	irq_complete_move(&desc);
+	irq_complete_move(cfg);
 #ifdef CONFIG_GENERIC_PENDING_IRQ
 	/* If we are moving the irq we need to mask it */
 	if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
 		do_unmask_irq = 1;
-		mask_IO_APIC_irq_desc(desc);
+		mask_ioapic(cfg);
 	}
 #endif
 
@@ -2659,7 +2636,6 @@ static void ack_apic_level(unsigned int 
 	 * we use the above logic (mask+edge followed by unmask+level) from
 	 * Manfred Spraul to clear the remote IRR.
 	 */
-	cfg = get_irq_desc_chip_data(desc);
 	i = cfg->vector;
 	v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
 
@@ -2679,7 +2655,7 @@ static void ack_apic_level(unsigned int 
 	if (!(v & (1 << (i & 0x1f)))) {
 		atomic_inc(&irq_mis_count);
 
-		eoi_ioapic_irq(desc);
+		eoi_ioapic_irq(irq, cfg);
 	}
 
 	/* Now we can move and renable the irq */
@@ -2710,10 +2686,9 @@ static void ack_apic_level(unsigned int 
 		 * accurate and is causing problems then it is a hardware bug
 		 * and you can go talk to the chipset vendor about it.
 		 */
-		cfg = get_irq_desc_chip_data(desc);
 		if (!io_apic_level_ack_pending(cfg))
 			move_masked_irq(irq);
-		unmask_IO_APIC_irq_desc(desc);
+		unmask_ioapic(cfg);
 	}
 }
 
@@ -2725,18 +2700,18 @@ static void ir_ack_apic_edge(unsigned in
 
 static void ir_ack_apic_level(unsigned int irq)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg = get_irq_chip_data(irq);
 
 	ack_APIC_irq();
-	eoi_ioapic_irq(desc);
+	eoi_ioapic_irq(irq, cfg);
 }
 #endif /* CONFIG_INTR_REMAP */
 
 static struct irq_chip ioapic_chip __read_mostly = {
 	.name		= "IO-APIC",
 	.startup	= startup_ioapic_irq,
-	.mask		= mask_IO_APIC_irq,
-	.unmask		= unmask_IO_APIC_irq,
+	.mask		= mask_ioapic_irq,
+	.unmask		= unmask_ioapic_irq,
 	.ack		= ack_apic_edge,
 	.eoi		= ack_apic_level,
 #ifdef CONFIG_SMP
@@ -2748,8 +2723,8 @@ static struct irq_chip ioapic_chip __rea
 static struct irq_chip ir_ioapic_chip __read_mostly = {
 	.name		= "IR-IO-APIC",
 	.startup	= startup_ioapic_irq,
-	.mask		= mask_IO_APIC_irq,
-	.unmask		= unmask_IO_APIC_irq,
+	.mask		= mask_ioapic_irq,
+	.unmask		= unmask_ioapic_irq,
 #ifdef CONFIG_INTR_REMAP
 	.ack		= ir_ack_apic_edge,
 	.eoi		= ir_ack_apic_level,
@@ -3010,7 +2985,7 @@ static inline void __init check_timer(vo
 			int idx;
 			idx = find_irq_entry(apic1, pin1, mp_INT);
 			if (idx != -1 && irq_trigger(idx))
-				unmask_IO_APIC_irq_desc(desc);
+				unmask_ioapic(cfg);
 		}
 		if (timer_irq_works()) {
 			if (nmi_watchdog == NMI_IO_APIC) {

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

* [patch 26/47] x86: io_apic: Convert startup to new irq_chip function
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (24 preceding siblings ...)
  2010-09-30 23:16 ` [patch 25/47] x86: Cleanup io_apic Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 27/47] x86: ioapic: Convert mask " Thomas Gleixner
                   ` (24 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-ioapic-convert-startup.patch --]
[-- Type: text/plain, Size: 1701 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -2232,11 +2232,10 @@ static int __init timer_irq_works(void)
  * an edge even if it isn't on the 8259A...
  */
 
-static unsigned int startup_ioapic_irq(unsigned int irq)
+static unsigned int startup_ioapic_irq(struct irq_data *data)
 {
-	int was_pending = 0;
+	int was_pending = 0, irq = data->irq;
 	unsigned long flags;
-	struct irq_cfg *cfg;
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	if (irq < legacy_pic->nr_legacy_irqs) {
@@ -2244,8 +2243,7 @@ static unsigned int startup_ioapic_irq(u
 		if (legacy_pic->irq_pending(irq))
 			was_pending = 1;
 	}
-	cfg = irq_cfg(irq);
-	__unmask_ioapic(cfg);
+	__unmask_ioapic(data->chip_data);
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return was_pending;
@@ -2709,7 +2707,7 @@ static void ir_ack_apic_level(unsigned i
 
 static struct irq_chip ioapic_chip __read_mostly = {
 	.name		= "IO-APIC",
-	.startup	= startup_ioapic_irq,
+	.irq_startup	= startup_ioapic_irq,
 	.mask		= mask_ioapic_irq,
 	.unmask		= unmask_ioapic_irq,
 	.ack		= ack_apic_edge,
@@ -2722,7 +2720,7 @@ static struct irq_chip ioapic_chip __rea
 
 static struct irq_chip ir_ioapic_chip __read_mostly = {
 	.name		= "IR-IO-APIC",
-	.startup	= startup_ioapic_irq,
+	.irq_startup	= startup_ioapic_irq,
 	.mask		= mask_ioapic_irq,
 	.unmask		= unmask_ioapic_irq,
 #ifdef CONFIG_INTR_REMAP

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

* [patch 26/47] x86: io_apic: Convert startup to new irq_chip function
  2010-09-30 23:16 ` [patch 26/47] x86: io_apic: Convert startup to new irq_chip function Thomas Gleixner
@ 2010-09-30 23:16   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-ioapic-convert-startup.patch --]
[-- Type: text/plain, Size: 1703 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -2232,11 +2232,10 @@ static int __init timer_irq_works(void)
  * an edge even if it isn't on the 8259A...
  */
 
-static unsigned int startup_ioapic_irq(unsigned int irq)
+static unsigned int startup_ioapic_irq(struct irq_data *data)
 {
-	int was_pending = 0;
+	int was_pending = 0, irq = data->irq;
 	unsigned long flags;
-	struct irq_cfg *cfg;
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	if (irq < legacy_pic->nr_legacy_irqs) {
@@ -2244,8 +2243,7 @@ static unsigned int startup_ioapic_irq(u
 		if (legacy_pic->irq_pending(irq))
 			was_pending = 1;
 	}
-	cfg = irq_cfg(irq);
-	__unmask_ioapic(cfg);
+	__unmask_ioapic(data->chip_data);
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return was_pending;
@@ -2709,7 +2707,7 @@ static void ir_ack_apic_level(unsigned i
 
 static struct irq_chip ioapic_chip __read_mostly = {
 	.name		= "IO-APIC",
-	.startup	= startup_ioapic_irq,
+	.irq_startup	= startup_ioapic_irq,
 	.mask		= mask_ioapic_irq,
 	.unmask		= unmask_ioapic_irq,
 	.ack		= ack_apic_edge,
@@ -2722,7 +2720,7 @@ static struct irq_chip ioapic_chip __rea
 
 static struct irq_chip ir_ioapic_chip __read_mostly = {
 	.name		= "IR-IO-APIC",
-	.startup	= startup_ioapic_irq,
+	.irq_startup	= startup_ioapic_irq,
 	.mask		= mask_ioapic_irq,
 	.unmask		= unmask_ioapic_irq,
 #ifdef CONFIG_INTR_REMAP



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

* [patch 27/47] x86: ioapic: Convert mask to new irq_chip function
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (25 preceding siblings ...)
  2010-09-30 23:16 ` [patch 26/47] x86: io_apic: Convert startup to new irq_chip function Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 28/47] x86: ioapic/hpet: Convert to new chip functions Thomas Gleixner
                   ` (23 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-ioapic-convert-mask.patch --]
[-- Type: text/plain, Size: 7379 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |   95 ++++++++++++++++++-----------------------
 1 file changed, 43 insertions(+), 52 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -592,11 +592,9 @@ static void mask_ioapic(struct irq_cfg *
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-static void mask_ioapic_irq(unsigned int irq)
+static void mask_ioapic_irq(struct irq_data *data)
 {
-	struct irq_cfg *cfg = get_irq_chip_data(irq);
-
-	mask_ioapic(cfg);
+	mask_ioapic(data->chip_data);
 }
 
 static void __unmask_ioapic(struct irq_cfg *cfg)
@@ -613,11 +611,9 @@ static void unmask_ioapic(struct irq_cfg
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-static void unmask_ioapic_irq(unsigned int irq)
+static void unmask_ioapic_irq(struct irq_data *data)
 {
-	struct irq_cfg *cfg = get_irq_chip_data(irq);
-
-	unmask_ioapic(cfg);
+	unmask_ioapic(data->chip_data);
 }
 
 static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
@@ -2249,10 +2245,9 @@ static unsigned int startup_ioapic_irq(s
 	return was_pending;
 }
 
-static int ioapic_retrigger_irq(unsigned int irq)
+static int ioapic_retrigger_irq(struct irq_data *data)
 {
-
-	struct irq_cfg *cfg = irq_cfg(irq);
+	struct irq_cfg *cfg = data->chip_data;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&vector_lock, flags);
@@ -2533,12 +2528,10 @@ void irq_force_complete_move(int irq)
 static inline void irq_complete_move(struct irq_cfg *cfg) { }
 #endif
 
-static void ack_apic_edge(unsigned int irq)
+static void ack_apic_edge(struct irq_data *data)
 {
-	struct irq_cfg *cfg = get_irq_chip_data(irq);
-
-	irq_complete_move(cfg);
-	move_native_irq(irq);
+	irq_complete_move(data->chip_data);
+	move_native_irq(data->irq);
 	ack_APIC_irq();
 }
 
@@ -2586,11 +2579,11 @@ static void eoi_ioapic_irq(unsigned int 
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-static void ack_apic_level(unsigned int irq)
+static void ack_apic_level(struct irq_data *data)
 {
+	struct irq_cfg *cfg = data->chip_data;
+	int i, do_unmask_irq = 0, irq = data->irq;
 	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
-	int i, do_unmask_irq = 0;
 	unsigned long v;
 
 	irq_complete_move(cfg);
@@ -2691,46 +2684,44 @@ static void ack_apic_level(unsigned int 
 }
 
 #ifdef CONFIG_INTR_REMAP
-static void ir_ack_apic_edge(unsigned int irq)
+static void ir_ack_apic_edge(struct irq_data *data)
 {
 	ack_APIC_irq();
 }
 
-static void ir_ack_apic_level(unsigned int irq)
+static void ir_ack_apic_level(struct irq_data *data)
 {
-	struct irq_cfg *cfg = get_irq_chip_data(irq);
-
 	ack_APIC_irq();
-	eoi_ioapic_irq(irq, cfg);
+	eoi_ioapic_irq(data->irq, data->chip_data);
 }
 #endif /* CONFIG_INTR_REMAP */
 
 static struct irq_chip ioapic_chip __read_mostly = {
 	.name		= "IO-APIC",
 	.irq_startup	= startup_ioapic_irq,
-	.mask		= mask_ioapic_irq,
-	.unmask		= unmask_ioapic_irq,
-	.ack		= ack_apic_edge,
-	.eoi		= ack_apic_level,
+	.irq_mask	= mask_ioapic_irq,
+	.irq_unmask	= unmask_ioapic_irq,
+	.irq_ack	= ack_apic_edge,
+	.irq_eoi	= ack_apic_level,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_ioapic_affinity_irq,
 #endif
-	.retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger	= ioapic_retrigger_irq,
 };
 
 static struct irq_chip ir_ioapic_chip __read_mostly = {
 	.name		= "IR-IO-APIC",
 	.irq_startup	= startup_ioapic_irq,
-	.mask		= mask_ioapic_irq,
-	.unmask		= unmask_ioapic_irq,
+	.irq_mask	= mask_ioapic_irq,
+	.irq_unmask	= unmask_ioapic_irq,
 #ifdef CONFIG_INTR_REMAP
-	.ack		= ir_ack_apic_edge,
-	.eoi		= ir_ack_apic_level,
+	.irq_ack	= ir_ack_apic_edge,
+	.irq_eoi	= ir_ack_apic_level,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_ir_ioapic_affinity_irq,
 #endif
 #endif
-	.retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger	= ioapic_retrigger_irq,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -2771,7 +2762,7 @@ static inline void init_IO_APIC_traps(vo
  * The local APIC irq-chip implementation:
  */
 
-static void mask_lapic_irq(unsigned int irq)
+static void mask_lapic_irq(struct irq_data *data)
 {
 	unsigned long v;
 
@@ -2779,7 +2770,7 @@ static void mask_lapic_irq(unsigned int 
 	apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
 }
 
-static void unmask_lapic_irq(unsigned int irq)
+static void unmask_lapic_irq(struct irq_data *data)
 {
 	unsigned long v;
 
@@ -2787,16 +2778,16 @@ static void unmask_lapic_irq(unsigned in
 	apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
 }
 
-static void ack_lapic_irq(unsigned int irq)
+static void ack_lapic_irq(struct irq_data *data)
 {
 	ack_APIC_irq();
 }
 
 static struct irq_chip lapic_chip __read_mostly = {
 	.name		= "local-APIC",
-	.mask		= mask_lapic_irq,
-	.unmask		= unmask_lapic_irq,
-	.ack		= ack_lapic_irq,
+	.irq_mask	= mask_lapic_irq,
+	.irq_unmask	= unmask_lapic_irq,
+	.irq_ack	= ack_lapic_irq,
 };
 
 static void lapic_register_intr(int irq, struct irq_desc *desc)
@@ -3438,11 +3429,11 @@ static struct irq_chip msi_chip = {
 	.name		= "PCI-MSI",
 	.unmask		= unmask_msi_irq,
 	.mask		= mask_msi_irq,
-	.ack		= ack_apic_edge,
+	.irq_ack	= ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_msi_irq_affinity,
 #endif
-	.retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger	= ioapic_retrigger_irq,
 };
 
 static struct irq_chip msi_ir_chip = {
@@ -3450,12 +3441,12 @@ static struct irq_chip msi_ir_chip = {
 	.unmask		= unmask_msi_irq,
 	.mask		= mask_msi_irq,
 #ifdef CONFIG_INTR_REMAP
-	.ack		= ir_ack_apic_edge,
+	.irq_ack	= ir_ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity	= ir_set_msi_irq_affinity,
 #endif
 #endif
-	.retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger	= ioapic_retrigger_irq,
 };
 
 /*
@@ -3610,11 +3601,11 @@ static struct irq_chip dmar_msi_type = {
 	.name = "DMAR_MSI",
 	.unmask = dmar_msi_unmask,
 	.mask = dmar_msi_mask,
-	.ack = ack_apic_edge,
+	.irq_ack = ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity = dmar_msi_set_affinity,
 #endif
-	.retrigger = ioapic_retrigger_irq,
+	.irq_retrigger = ioapic_retrigger_irq,
 };
 
 int arch_setup_dmar_msi(unsigned int irq)
@@ -3666,23 +3657,23 @@ static struct irq_chip ir_hpet_msi_type 
 	.unmask = hpet_msi_unmask,
 	.mask = hpet_msi_mask,
 #ifdef CONFIG_INTR_REMAP
-	.ack = ir_ack_apic_edge,
+	.irq_ack = ir_ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity = ir_set_msi_irq_affinity,
 #endif
 #endif
-	.retrigger = ioapic_retrigger_irq,
+	.irq_retrigger = ioapic_retrigger_irq,
 };
 
 static struct irq_chip hpet_msi_type = {
 	.name = "HPET_MSI",
 	.unmask = hpet_msi_unmask,
 	.mask = hpet_msi_mask,
-	.ack = ack_apic_edge,
+	.irq_ack = ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity = hpet_msi_set_affinity,
 #endif
-	.retrigger = ioapic_retrigger_irq,
+	.irq_retrigger = ioapic_retrigger_irq,
 };
 
 int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
@@ -3764,11 +3755,11 @@ static struct irq_chip ht_irq_chip = {
 	.name		= "PCI-HT",
 	.mask		= mask_ht_irq,
 	.unmask		= unmask_ht_irq,
-	.ack		= ack_apic_edge,
+	.irq_ack	= ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_ht_irq_affinity,
 #endif
-	.retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger	= ioapic_retrigger_irq,
 };
 
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)

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

* [patch 28/47] x86: ioapic/hpet: Convert to new chip functions
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (26 preceding siblings ...)
  2010-09-30 23:16 ` [patch 27/47] x86: ioapic: Convert mask " Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
  2010-09-30 23:16 ` [patch 29/47] pci: Convert msi to new irq_chip functions Thomas Gleixner
                   ` (22 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-hept-convert.patch --]
[-- Type: text/plain, Size: 5423 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/hpet.h    |   10 ++++++----
 arch/x86/kernel/apic/io_apic.c |   30 ++++++++++++++----------------
 arch/x86/kernel/hpet.c         |   16 ++++++----------
 3 files changed, 26 insertions(+), 30 deletions(-)

Index: linux-2.6-tip/arch/x86/include/asm/hpet.h
===================================================================
--- linux-2.6-tip.orig/arch/x86/include/asm/hpet.h
+++ linux-2.6-tip/arch/x86/include/asm/hpet.h
@@ -74,10 +74,12 @@ extern void hpet_disable(void);
 extern unsigned int hpet_readl(unsigned int a);
 extern void force_hpet_resume(void);
 
-extern void hpet_msi_unmask(unsigned int irq);
-extern void hpet_msi_mask(unsigned int irq);
-extern void hpet_msi_write(unsigned int irq, struct msi_msg *msg);
-extern void hpet_msi_read(unsigned int irq, struct msi_msg *msg);
+struct irq_data;
+extern void hpet_msi_unmask(struct irq_data *data);
+extern void hpet_msi_mask(struct irq_data *data);
+struct hpet_dev;
+extern void hpet_msi_write(struct hpet_dev *hdev, struct msi_msg *msg);
+extern void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg);
 
 #ifdef CONFIG_PCI_MSI
 extern int arch_setup_hpet_msi(unsigned int irq, unsigned int id);
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3626,26 +3626,25 @@ int arch_setup_dmar_msi(unsigned int irq
 #ifdef CONFIG_HPET_TIMER
 
 #ifdef CONFIG_SMP
-static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int hpet_msi_set_affinity(struct irq_data *data,
+				 const struct cpumask *mask, bool force)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
+	struct irq_desc *desc = irq_to_desc(data->irq);
+	struct irq_cfg *cfg = data->chip_data;
 	struct msi_msg msg;
 	unsigned int dest;
 
 	if (set_desc_affinity(desc, mask, &dest))
 		return -1;
 
-	cfg = get_irq_desc_chip_data(desc);
-
-	hpet_msi_read(irq, &msg);
+	hpet_msi_read(data->handler_data, &msg);
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
 	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
-	hpet_msi_write(irq, &msg);
+	hpet_msi_write(data->handler_data, &msg);
 
 	return 0;
 }
@@ -3654,8 +3653,8 @@ static int hpet_msi_set_affinity(unsigne
 
 static struct irq_chip ir_hpet_msi_type = {
 	.name = "IR-HPET_MSI",
-	.unmask = hpet_msi_unmask,
-	.mask = hpet_msi_mask,
+	.irq_unmask = hpet_msi_unmask,
+	.irq_mask = hpet_msi_mask,
 #ifdef CONFIG_INTR_REMAP
 	.irq_ack = ir_ack_apic_edge,
 #ifdef CONFIG_SMP
@@ -3667,20 +3666,19 @@ static struct irq_chip ir_hpet_msi_type 
 
 static struct irq_chip hpet_msi_type = {
 	.name = "HPET_MSI",
-	.unmask = hpet_msi_unmask,
-	.mask = hpet_msi_mask,
+	.irq_unmask = hpet_msi_unmask,
+	.irq_mask = hpet_msi_mask,
 	.irq_ack = ack_apic_edge,
 #ifdef CONFIG_SMP
-	.set_affinity = hpet_msi_set_affinity,
+	.irq_set_affinity = hpet_msi_set_affinity,
 #endif
 	.irq_retrigger = ioapic_retrigger_irq,
 };
 
 int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 {
-	int ret;
 	struct msi_msg msg;
-	struct irq_desc *desc = irq_to_desc(irq);
+	int ret;
 
 	if (intr_remapping_enabled) {
 		struct intel_iommu *iommu = map_hpet_to_ir(id);
@@ -3698,8 +3696,8 @@ int arch_setup_hpet_msi(unsigned int irq
 	if (ret < 0)
 		return ret;
 
-	hpet_msi_write(irq, &msg);
-	desc->status |= IRQ_MOVE_PCNTXT;
+	hpet_msi_write(get_irq_data(irq), &msg);
+	irq_set_status_flags(irq,IRQ_MOVE_PCNTXT);
 	if (irq_remapped(irq))
 		set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type,
 					      handle_edge_irq, "edge");
Index: linux-2.6-tip/arch/x86/kernel/hpet.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/hpet.c
+++ linux-2.6-tip/arch/x86/kernel/hpet.c
@@ -440,9 +440,9 @@ static int hpet_legacy_next_event(unsign
 static DEFINE_PER_CPU(struct hpet_dev *, cpu_hpet_dev);
 static struct hpet_dev	*hpet_devs;
 
-void hpet_msi_unmask(unsigned int irq)
+void hpet_msi_unmask(struct irq_data *data)
 {
-	struct hpet_dev *hdev = get_irq_data(irq);
+	struct hpet_dev *hdev = data->handler_data;
 	unsigned int cfg;
 
 	/* unmask it */
@@ -451,10 +451,10 @@ void hpet_msi_unmask(unsigned int irq)
 	hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
 }
 
-void hpet_msi_mask(unsigned int irq)
+void hpet_msi_mask(struct irq_data *data)
 {
+	struct hpet_dev *hdev = data->handler_data;
 	unsigned int cfg;
-	struct hpet_dev *hdev = get_irq_data(irq);
 
 	/* mask it */
 	cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
@@ -462,18 +462,14 @@ void hpet_msi_mask(unsigned int irq)
 	hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
 }
 
-void hpet_msi_write(unsigned int irq, struct msi_msg *msg)
+void hpet_msi_write(struct hpet_dev *hdev, struct msi_msg *msg)
 {
-	struct hpet_dev *hdev = get_irq_data(irq);
-
 	hpet_writel(msg->data, HPET_Tn_ROUTE(hdev->num));
 	hpet_writel(msg->address_lo, HPET_Tn_ROUTE(hdev->num) + 4);
 }
 
-void hpet_msi_read(unsigned int irq, struct msi_msg *msg)
+void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg)
 {
-	struct hpet_dev *hdev = get_irq_data(irq);
-
 	msg->data = hpet_readl(HPET_Tn_ROUTE(hdev->num));
 	msg->address_lo = hpet_readl(HPET_Tn_ROUTE(hdev->num) + 4);
 	msg->address_hi = 0;

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

* [patch 28/47] x86: ioapic/hpet: Convert to new chip functions
  2010-09-30 23:16 ` [patch 28/47] x86: ioapic/hpet: Convert to new chip functions Thomas Gleixner
@ 2010-09-30 23:16   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-hept-convert.patch --]
[-- Type: text/plain, Size: 5425 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/hpet.h    |   10 ++++++----
 arch/x86/kernel/apic/io_apic.c |   30 ++++++++++++++----------------
 arch/x86/kernel/hpet.c         |   16 ++++++----------
 3 files changed, 26 insertions(+), 30 deletions(-)

Index: linux-2.6-tip/arch/x86/include/asm/hpet.h
===================================================================
--- linux-2.6-tip.orig/arch/x86/include/asm/hpet.h
+++ linux-2.6-tip/arch/x86/include/asm/hpet.h
@@ -74,10 +74,12 @@ extern void hpet_disable(void);
 extern unsigned int hpet_readl(unsigned int a);
 extern void force_hpet_resume(void);
 
-extern void hpet_msi_unmask(unsigned int irq);
-extern void hpet_msi_mask(unsigned int irq);
-extern void hpet_msi_write(unsigned int irq, struct msi_msg *msg);
-extern void hpet_msi_read(unsigned int irq, struct msi_msg *msg);
+struct irq_data;
+extern void hpet_msi_unmask(struct irq_data *data);
+extern void hpet_msi_mask(struct irq_data *data);
+struct hpet_dev;
+extern void hpet_msi_write(struct hpet_dev *hdev, struct msi_msg *msg);
+extern void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg);
 
 #ifdef CONFIG_PCI_MSI
 extern int arch_setup_hpet_msi(unsigned int irq, unsigned int id);
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3626,26 +3626,25 @@ int arch_setup_dmar_msi(unsigned int irq
 #ifdef CONFIG_HPET_TIMER
 
 #ifdef CONFIG_SMP
-static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int hpet_msi_set_affinity(struct irq_data *data,
+				 const struct cpumask *mask, bool force)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
+	struct irq_desc *desc = irq_to_desc(data->irq);
+	struct irq_cfg *cfg = data->chip_data;
 	struct msi_msg msg;
 	unsigned int dest;
 
 	if (set_desc_affinity(desc, mask, &dest))
 		return -1;
 
-	cfg = get_irq_desc_chip_data(desc);
-
-	hpet_msi_read(irq, &msg);
+	hpet_msi_read(data->handler_data, &msg);
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
 	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
-	hpet_msi_write(irq, &msg);
+	hpet_msi_write(data->handler_data, &msg);
 
 	return 0;
 }
@@ -3654,8 +3653,8 @@ static int hpet_msi_set_affinity(unsigne
 
 static struct irq_chip ir_hpet_msi_type = {
 	.name = "IR-HPET_MSI",
-	.unmask = hpet_msi_unmask,
-	.mask = hpet_msi_mask,
+	.irq_unmask = hpet_msi_unmask,
+	.irq_mask = hpet_msi_mask,
 #ifdef CONFIG_INTR_REMAP
 	.irq_ack = ir_ack_apic_edge,
 #ifdef CONFIG_SMP
@@ -3667,20 +3666,19 @@ static struct irq_chip ir_hpet_msi_type 
 
 static struct irq_chip hpet_msi_type = {
 	.name = "HPET_MSI",
-	.unmask = hpet_msi_unmask,
-	.mask = hpet_msi_mask,
+	.irq_unmask = hpet_msi_unmask,
+	.irq_mask = hpet_msi_mask,
 	.irq_ack = ack_apic_edge,
 #ifdef CONFIG_SMP
-	.set_affinity = hpet_msi_set_affinity,
+	.irq_set_affinity = hpet_msi_set_affinity,
 #endif
 	.irq_retrigger = ioapic_retrigger_irq,
 };
 
 int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 {
-	int ret;
 	struct msi_msg msg;
-	struct irq_desc *desc = irq_to_desc(irq);
+	int ret;
 
 	if (intr_remapping_enabled) {
 		struct intel_iommu *iommu = map_hpet_to_ir(id);
@@ -3698,8 +3696,8 @@ int arch_setup_hpet_msi(unsigned int irq
 	if (ret < 0)
 		return ret;
 
-	hpet_msi_write(irq, &msg);
-	desc->status |= IRQ_MOVE_PCNTXT;
+	hpet_msi_write(get_irq_data(irq), &msg);
+	irq_set_status_flags(irq,IRQ_MOVE_PCNTXT);
 	if (irq_remapped(irq))
 		set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type,
 					      handle_edge_irq, "edge");
Index: linux-2.6-tip/arch/x86/kernel/hpet.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/hpet.c
+++ linux-2.6-tip/arch/x86/kernel/hpet.c
@@ -440,9 +440,9 @@ static int hpet_legacy_next_event(unsign
 static DEFINE_PER_CPU(struct hpet_dev *, cpu_hpet_dev);
 static struct hpet_dev	*hpet_devs;
 
-void hpet_msi_unmask(unsigned int irq)
+void hpet_msi_unmask(struct irq_data *data)
 {
-	struct hpet_dev *hdev = get_irq_data(irq);
+	struct hpet_dev *hdev = data->handler_data;
 	unsigned int cfg;
 
 	/* unmask it */
@@ -451,10 +451,10 @@ void hpet_msi_unmask(unsigned int irq)
 	hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
 }
 
-void hpet_msi_mask(unsigned int irq)
+void hpet_msi_mask(struct irq_data *data)
 {
+	struct hpet_dev *hdev = data->handler_data;
 	unsigned int cfg;
-	struct hpet_dev *hdev = get_irq_data(irq);
 
 	/* mask it */
 	cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
@@ -462,18 +462,14 @@ void hpet_msi_mask(unsigned int irq)
 	hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
 }
 
-void hpet_msi_write(unsigned int irq, struct msi_msg *msg)
+void hpet_msi_write(struct hpet_dev *hdev, struct msi_msg *msg)
 {
-	struct hpet_dev *hdev = get_irq_data(irq);
-
 	hpet_writel(msg->data, HPET_Tn_ROUTE(hdev->num));
 	hpet_writel(msg->address_lo, HPET_Tn_ROUTE(hdev->num) + 4);
 }
 
-void hpet_msi_read(unsigned int irq, struct msi_msg *msg)
+void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg)
 {
-	struct hpet_dev *hdev = get_irq_data(irq);
-
 	msg->data = hpet_readl(HPET_Tn_ROUTE(hdev->num));
 	msg->address_lo = hpet_readl(HPET_Tn_ROUTE(hdev->num) + 4);
 	msg->address_hi = 0;



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

* [patch 29/47] pci: Convert msi to new irq_chip functions
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (27 preceding siblings ...)
  2010-09-30 23:16 ` [patch 28/47] x86: ioapic/hpet: Convert to new chip functions Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
  2010-10-11 17:09   ` Jesse Barnes
  2010-09-30 23:16 ` [patch 30/47] dmar: Convert to new irq chip functions Thomas Gleixner
                   ` (21 subsequent siblings)
  50 siblings, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: pci-convert-msi.patch --]
[-- Type: text/plain, Size: 9873 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/mach-iop13xx/msi.c            |    8 ++++----
 arch/ia64/kernel/msi_ia64.c            |    4 ++--
 arch/ia64/sn/kernel/msi_sn.c           |    4 ++--
 arch/powerpc/platforms/cell/axon_msi.c |    6 +++---
 arch/powerpc/platforms/pseries/xics.c  |    2 +-
 arch/powerpc/sysdev/fsl_msi.c          |    4 ++--
 arch/powerpc/sysdev/mpic_pasemi_msi.c  |   22 +++++++++++-----------
 arch/powerpc/sysdev/mpic_u3msi.c       |   16 ++++++++--------
 arch/sparc/kernel/pci_msi.c            |    8 ++++----
 arch/x86/kernel/apic/io_apic.c         |    8 ++++----
 drivers/pci/msi.c                      |   14 +++++++-------
 include/linux/msi.h                    |    5 +++--
 12 files changed, 51 insertions(+), 50 deletions(-)

Index: linux-2.6-tip/arch/arm/mach-iop13xx/msi.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/mach-iop13xx/msi.c
+++ linux-2.6-tip/arch/arm/mach-iop13xx/msi.c
@@ -164,10 +164,10 @@ static void iop13xx_msi_nop(unsigned int
 static struct irq_chip iop13xx_msi_chip = {
 	.name = "PCI-MSI",
 	.ack = iop13xx_msi_nop,
-	.enable = unmask_msi_irq,
-	.disable = mask_msi_irq,
-	.mask = mask_msi_irq,
-	.unmask = unmask_msi_irq,
+	.irq_enable = unmask_msi_irq,
+	.irq_disable = mask_msi_irq,
+	.irq_mask = mask_msi_irq,
+	.irq_unmask = unmask_msi_irq,
 };
 
 int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
Index: linux-2.6-tip/arch/ia64/kernel/msi_ia64.c
===================================================================
--- linux-2.6-tip.orig/arch/ia64/kernel/msi_ia64.c
+++ linux-2.6-tip/arch/ia64/kernel/msi_ia64.c
@@ -104,8 +104,8 @@ static int ia64_msi_retrigger_irq(unsign
  */
 static struct irq_chip ia64_msi_chip = {
 	.name		= "PCI-MSI",
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
 	.ack		= ia64_ack_msi_irq,
 #ifdef CONFIG_SMP
 	.set_affinity	= ia64_set_msi_irq_affinity,
Index: linux-2.6-tip/arch/ia64/sn/kernel/msi_sn.c
===================================================================
--- linux-2.6-tip.orig/arch/ia64/sn/kernel/msi_sn.c
+++ linux-2.6-tip/arch/ia64/sn/kernel/msi_sn.c
@@ -228,8 +228,8 @@ static int sn_msi_retrigger_irq(unsigned
 
 static struct irq_chip sn_msi_chip = {
 	.name		= "PCI-MSI",
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
 	.ack		= sn_ack_msi_irq,
 #ifdef CONFIG_SMP
 	.set_affinity	= sn_set_msi_irq_affinity,
Index: linux-2.6-tip/arch/powerpc/platforms/cell/axon_msi.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/platforms/cell/axon_msi.c
+++ linux-2.6-tip/arch/powerpc/platforms/cell/axon_msi.c
@@ -310,9 +310,9 @@ static void axon_msi_teardown_msi_irqs(s
 }
 
 static struct irq_chip msic_irq_chip = {
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
-	.shutdown	= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
+	.irq_shutdown	= mask_msi_irq,
 	.name		= "AXON-MSI",
 };
 
Index: linux-2.6-tip/arch/powerpc/platforms/pseries/xics.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/platforms/pseries/xics.c
+++ linux-2.6-tip/arch/powerpc/platforms/pseries/xics.c
@@ -243,7 +243,7 @@ static unsigned int xics_startup(unsigne
 	 * at that level, so we do it here by hand.
 	 */
 	if (get_irq_msi(virq))
-		unmask_msi_irq(virq);
+		unmask_msi_irq(irq_get_irq_data(virq));
 
 	/* unmask it */
 	xics_unmask_irq(virq);
Index: linux-2.6-tip/arch/powerpc/sysdev/fsl_msi.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/sysdev/fsl_msi.c
+++ linux-2.6-tip/arch/powerpc/sysdev/fsl_msi.c
@@ -51,8 +51,8 @@ static void fsl_msi_end_irq(unsigned int
 }
 
 static struct irq_chip fsl_msi_chip = {
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
 	.ack		= fsl_msi_end_irq,
 	.name		= "FSL-MSI",
 };
Index: linux-2.6-tip/arch/powerpc/sysdev/mpic_pasemi_msi.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ linux-2.6-tip/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -39,24 +39,24 @@
 static struct mpic *msi_mpic;
 
 
-static void mpic_pasemi_msi_mask_irq(unsigned int irq)
+static void mpic_pasemi_msi_mask_irq(struct irq_chip *data)
 {
-	pr_debug("mpic_pasemi_msi_mask_irq %d\n", irq);
-	mask_msi_irq(irq);
-	mpic_mask_irq(irq);
+	pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq);
+	mask_msi_irq(data);
+	mpic_mask_irq(data->irq);
 }
 
-static void mpic_pasemi_msi_unmask_irq(unsigned int irq)
+static void mpic_pasemi_msi_unmask_irq(struct irq_chip *data)
 {
-	pr_debug("mpic_pasemi_msi_unmask_irq %d\n", irq);
-	mpic_unmask_irq(irq);
-	unmask_msi_irq(irq);
+	pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq);
+	mpic_unmask_irq(data->irq);
+	unmask_msi_irq(data);
 }
 
 static struct irq_chip mpic_pasemi_msi_chip = {
-	.shutdown	= mpic_pasemi_msi_mask_irq,
-	.mask		= mpic_pasemi_msi_mask_irq,
-	.unmask		= mpic_pasemi_msi_unmask_irq,
+	.irq_shutdown	= mpic_pasemi_msi_mask_irq,
+	.irq_mask	= mpic_pasemi_msi_mask_irq,
+	.irq_unmask	= mpic_pasemi_msi_unmask_irq,
 	.eoi		= mpic_end_irq,
 	.set_type	= mpic_set_irq_type,
 	.set_affinity	= mpic_set_affinity,
Index: linux-2.6-tip/arch/powerpc/sysdev/mpic_u3msi.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/sysdev/mpic_u3msi.c
+++ linux-2.6-tip/arch/powerpc/sysdev/mpic_u3msi.c
@@ -23,22 +23,22 @@
 /* A bit ugly, can we get this from the pci_dev somehow? */
 static struct mpic *msi_mpic;
 
-static void mpic_u3msi_mask_irq(unsigned int irq)
+static void mpic_u3msi_mask_irq(struct irq_data *data)
 {
-	mask_msi_irq(irq);
-	mpic_mask_irq(irq);
+	mask_msi_irq(data);
+	mpic_mask_irq(data->irq);
 }
 
-static void mpic_u3msi_unmask_irq(unsigned int irq)
+static void mpic_u3msi_unmask_irq(struct irq_data *data)
 {
-	mpic_unmask_irq(irq);
-	unmask_msi_irq(irq);
+	mpic_unmask_irq(data->irq);
+	unmask_msi_irq(data);
 }
 
 static struct irq_chip mpic_u3msi_chip = {
 	.shutdown	= mpic_u3msi_mask_irq,
-	.mask		= mpic_u3msi_mask_irq,
-	.unmask		= mpic_u3msi_unmask_irq,
+	.irq_mask	= mpic_u3msi_mask_irq,
+	.irq_unmask	= mpic_u3msi_unmask_irq,
 	.eoi		= mpic_end_irq,
 	.set_type	= mpic_set_irq_type,
 	.set_affinity	= mpic_set_affinity,
Index: linux-2.6-tip/arch/sparc/kernel/pci_msi.c
===================================================================
--- linux-2.6-tip.orig/arch/sparc/kernel/pci_msi.c
+++ linux-2.6-tip/arch/sparc/kernel/pci_msi.c
@@ -114,10 +114,10 @@ static void free_msi(struct pci_pbm_info
 
 static struct irq_chip msi_irq = {
 	.name		= "PCI-MSI",
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
-	.enable		= unmask_msi_irq,
-	.disable	= mask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
+	.irq_enable	= unmask_msi_irq,
+	.irq_disable	= mask_msi_irq,
 	/* XXX affinity XXX */
 };
 
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3427,8 +3427,8 @@ ir_set_msi_irq_affinity(unsigned int irq
  */
 static struct irq_chip msi_chip = {
 	.name		= "PCI-MSI",
-	.unmask		= unmask_msi_irq,
-	.mask		= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
 	.irq_ack	= ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_msi_irq_affinity,
@@ -3438,8 +3438,8 @@ static struct irq_chip msi_chip = {
 
 static struct irq_chip msi_ir_chip = {
 	.name		= "IR-PCI-MSI",
-	.unmask		= unmask_msi_irq,
-	.mask		= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
 #ifdef CONFIG_INTR_REMAP
 	.irq_ack	= ir_ack_apic_edge,
 #ifdef CONFIG_SMP
Index: linux-2.6-tip/drivers/pci/msi.c
===================================================================
--- linux-2.6-tip.orig/drivers/pci/msi.c
+++ linux-2.6-tip/drivers/pci/msi.c
@@ -170,27 +170,27 @@ static void msix_mask_irq(struct msi_des
 	desc->masked = __msix_mask_irq(desc, flag);
 }
 
-static void msi_set_mask_bit(unsigned irq, u32 flag)
+static void msi_set_mask_bit(struct irq_data *data, u32 flag)
 {
-	struct msi_desc *desc = get_irq_msi(irq);
+	struct msi_desc *desc = data->msi_desc;
 
 	if (desc->msi_attrib.is_msix) {
 		msix_mask_irq(desc, flag);
 		readl(desc->mask_base);		/* Flush write to device */
 	} else {
-		unsigned offset = irq - desc->dev->irq;
+		unsigned offset = data->irq - desc->dev->irq;
 		msi_mask_irq(desc, 1 << offset, flag << offset);
 	}
 }
 
-void mask_msi_irq(unsigned int irq)
+void mask_msi_irq(struct irq_data *data)
 {
-	msi_set_mask_bit(irq, 1);
+	msi_set_mask_bit(data, 1);
 }
 
-void unmask_msi_irq(unsigned int irq)
+void unmask_msi_irq(struct irq_data *data)
 {
-	msi_set_mask_bit(irq, 0);
+	msi_set_mask_bit(data, 0);
 }
 
 void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
Index: linux-2.6-tip/include/linux/msi.h
===================================================================
--- linux-2.6-tip.orig/include/linux/msi.h
+++ linux-2.6-tip/include/linux/msi.h
@@ -11,8 +11,9 @@ struct msi_msg {
 
 /* Helper functions */
 struct irq_desc;
-extern void mask_msi_irq(unsigned int irq);
-extern void unmask_msi_irq(unsigned int irq);
+struct irq_data;
+extern void mask_msi_irq(struct irq_data *data);
+extern void unmask_msi_irq(struct irq_data *data);
 extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
 extern void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
 extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);

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

* [patch 29/47] pci: Convert msi to new irq_chip functions
  2010-09-30 23:16 ` [patch 29/47] pci: Convert msi to new irq_chip functions Thomas Gleixner
@ 2010-09-30 23:16   ` Thomas Gleixner
  2010-10-11 17:09   ` Jesse Barnes
  1 sibling, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: pci-convert-msi.patch --]
[-- Type: text/plain, Size: 9875 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/mach-iop13xx/msi.c            |    8 ++++----
 arch/ia64/kernel/msi_ia64.c            |    4 ++--
 arch/ia64/sn/kernel/msi_sn.c           |    4 ++--
 arch/powerpc/platforms/cell/axon_msi.c |    6 +++---
 arch/powerpc/platforms/pseries/xics.c  |    2 +-
 arch/powerpc/sysdev/fsl_msi.c          |    4 ++--
 arch/powerpc/sysdev/mpic_pasemi_msi.c  |   22 +++++++++++-----------
 arch/powerpc/sysdev/mpic_u3msi.c       |   16 ++++++++--------
 arch/sparc/kernel/pci_msi.c            |    8 ++++----
 arch/x86/kernel/apic/io_apic.c         |    8 ++++----
 drivers/pci/msi.c                      |   14 +++++++-------
 include/linux/msi.h                    |    5 +++--
 12 files changed, 51 insertions(+), 50 deletions(-)

Index: linux-2.6-tip/arch/arm/mach-iop13xx/msi.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/mach-iop13xx/msi.c
+++ linux-2.6-tip/arch/arm/mach-iop13xx/msi.c
@@ -164,10 +164,10 @@ static void iop13xx_msi_nop(unsigned int
 static struct irq_chip iop13xx_msi_chip = {
 	.name = "PCI-MSI",
 	.ack = iop13xx_msi_nop,
-	.enable = unmask_msi_irq,
-	.disable = mask_msi_irq,
-	.mask = mask_msi_irq,
-	.unmask = unmask_msi_irq,
+	.irq_enable = unmask_msi_irq,
+	.irq_disable = mask_msi_irq,
+	.irq_mask = mask_msi_irq,
+	.irq_unmask = unmask_msi_irq,
 };
 
 int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
Index: linux-2.6-tip/arch/ia64/kernel/msi_ia64.c
===================================================================
--- linux-2.6-tip.orig/arch/ia64/kernel/msi_ia64.c
+++ linux-2.6-tip/arch/ia64/kernel/msi_ia64.c
@@ -104,8 +104,8 @@ static int ia64_msi_retrigger_irq(unsign
  */
 static struct irq_chip ia64_msi_chip = {
 	.name		= "PCI-MSI",
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
 	.ack		= ia64_ack_msi_irq,
 #ifdef CONFIG_SMP
 	.set_affinity	= ia64_set_msi_irq_affinity,
Index: linux-2.6-tip/arch/ia64/sn/kernel/msi_sn.c
===================================================================
--- linux-2.6-tip.orig/arch/ia64/sn/kernel/msi_sn.c
+++ linux-2.6-tip/arch/ia64/sn/kernel/msi_sn.c
@@ -228,8 +228,8 @@ static int sn_msi_retrigger_irq(unsigned
 
 static struct irq_chip sn_msi_chip = {
 	.name		= "PCI-MSI",
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
 	.ack		= sn_ack_msi_irq,
 #ifdef CONFIG_SMP
 	.set_affinity	= sn_set_msi_irq_affinity,
Index: linux-2.6-tip/arch/powerpc/platforms/cell/axon_msi.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/platforms/cell/axon_msi.c
+++ linux-2.6-tip/arch/powerpc/platforms/cell/axon_msi.c
@@ -310,9 +310,9 @@ static void axon_msi_teardown_msi_irqs(s
 }
 
 static struct irq_chip msic_irq_chip = {
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
-	.shutdown	= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
+	.irq_shutdown	= mask_msi_irq,
 	.name		= "AXON-MSI",
 };
 
Index: linux-2.6-tip/arch/powerpc/platforms/pseries/xics.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/platforms/pseries/xics.c
+++ linux-2.6-tip/arch/powerpc/platforms/pseries/xics.c
@@ -243,7 +243,7 @@ static unsigned int xics_startup(unsigne
 	 * at that level, so we do it here by hand.
 	 */
 	if (get_irq_msi(virq))
-		unmask_msi_irq(virq);
+		unmask_msi_irq(irq_get_irq_data(virq));
 
 	/* unmask it */
 	xics_unmask_irq(virq);
Index: linux-2.6-tip/arch/powerpc/sysdev/fsl_msi.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/sysdev/fsl_msi.c
+++ linux-2.6-tip/arch/powerpc/sysdev/fsl_msi.c
@@ -51,8 +51,8 @@ static void fsl_msi_end_irq(unsigned int
 }
 
 static struct irq_chip fsl_msi_chip = {
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
 	.ack		= fsl_msi_end_irq,
 	.name		= "FSL-MSI",
 };
Index: linux-2.6-tip/arch/powerpc/sysdev/mpic_pasemi_msi.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ linux-2.6-tip/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -39,24 +39,24 @@
 static struct mpic *msi_mpic;
 
 
-static void mpic_pasemi_msi_mask_irq(unsigned int irq)
+static void mpic_pasemi_msi_mask_irq(struct irq_chip *data)
 {
-	pr_debug("mpic_pasemi_msi_mask_irq %d\n", irq);
-	mask_msi_irq(irq);
-	mpic_mask_irq(irq);
+	pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq);
+	mask_msi_irq(data);
+	mpic_mask_irq(data->irq);
 }
 
-static void mpic_pasemi_msi_unmask_irq(unsigned int irq)
+static void mpic_pasemi_msi_unmask_irq(struct irq_chip *data)
 {
-	pr_debug("mpic_pasemi_msi_unmask_irq %d\n", irq);
-	mpic_unmask_irq(irq);
-	unmask_msi_irq(irq);
+	pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq);
+	mpic_unmask_irq(data->irq);
+	unmask_msi_irq(data);
 }
 
 static struct irq_chip mpic_pasemi_msi_chip = {
-	.shutdown	= mpic_pasemi_msi_mask_irq,
-	.mask		= mpic_pasemi_msi_mask_irq,
-	.unmask		= mpic_pasemi_msi_unmask_irq,
+	.irq_shutdown	= mpic_pasemi_msi_mask_irq,
+	.irq_mask	= mpic_pasemi_msi_mask_irq,
+	.irq_unmask	= mpic_pasemi_msi_unmask_irq,
 	.eoi		= mpic_end_irq,
 	.set_type	= mpic_set_irq_type,
 	.set_affinity	= mpic_set_affinity,
Index: linux-2.6-tip/arch/powerpc/sysdev/mpic_u3msi.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/sysdev/mpic_u3msi.c
+++ linux-2.6-tip/arch/powerpc/sysdev/mpic_u3msi.c
@@ -23,22 +23,22 @@
 /* A bit ugly, can we get this from the pci_dev somehow? */
 static struct mpic *msi_mpic;
 
-static void mpic_u3msi_mask_irq(unsigned int irq)
+static void mpic_u3msi_mask_irq(struct irq_data *data)
 {
-	mask_msi_irq(irq);
-	mpic_mask_irq(irq);
+	mask_msi_irq(data);
+	mpic_mask_irq(data->irq);
 }
 
-static void mpic_u3msi_unmask_irq(unsigned int irq)
+static void mpic_u3msi_unmask_irq(struct irq_data *data)
 {
-	mpic_unmask_irq(irq);
-	unmask_msi_irq(irq);
+	mpic_unmask_irq(data->irq);
+	unmask_msi_irq(data);
 }
 
 static struct irq_chip mpic_u3msi_chip = {
 	.shutdown	= mpic_u3msi_mask_irq,
-	.mask		= mpic_u3msi_mask_irq,
-	.unmask		= mpic_u3msi_unmask_irq,
+	.irq_mask	= mpic_u3msi_mask_irq,
+	.irq_unmask	= mpic_u3msi_unmask_irq,
 	.eoi		= mpic_end_irq,
 	.set_type	= mpic_set_irq_type,
 	.set_affinity	= mpic_set_affinity,
Index: linux-2.6-tip/arch/sparc/kernel/pci_msi.c
===================================================================
--- linux-2.6-tip.orig/arch/sparc/kernel/pci_msi.c
+++ linux-2.6-tip/arch/sparc/kernel/pci_msi.c
@@ -114,10 +114,10 @@ static void free_msi(struct pci_pbm_info
 
 static struct irq_chip msi_irq = {
 	.name		= "PCI-MSI",
-	.mask		= mask_msi_irq,
-	.unmask		= unmask_msi_irq,
-	.enable		= unmask_msi_irq,
-	.disable	= mask_msi_irq,
+	.irq_mask	= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
+	.irq_enable	= unmask_msi_irq,
+	.irq_disable	= mask_msi_irq,
 	/* XXX affinity XXX */
 };
 
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3427,8 +3427,8 @@ ir_set_msi_irq_affinity(unsigned int irq
  */
 static struct irq_chip msi_chip = {
 	.name		= "PCI-MSI",
-	.unmask		= unmask_msi_irq,
-	.mask		= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
 	.irq_ack	= ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_msi_irq_affinity,
@@ -3438,8 +3438,8 @@ static struct irq_chip msi_chip = {
 
 static struct irq_chip msi_ir_chip = {
 	.name		= "IR-PCI-MSI",
-	.unmask		= unmask_msi_irq,
-	.mask		= mask_msi_irq,
+	.irq_unmask	= unmask_msi_irq,
+	.irq_mask	= mask_msi_irq,
 #ifdef CONFIG_INTR_REMAP
 	.irq_ack	= ir_ack_apic_edge,
 #ifdef CONFIG_SMP
Index: linux-2.6-tip/drivers/pci/msi.c
===================================================================
--- linux-2.6-tip.orig/drivers/pci/msi.c
+++ linux-2.6-tip/drivers/pci/msi.c
@@ -170,27 +170,27 @@ static void msix_mask_irq(struct msi_des
 	desc->masked = __msix_mask_irq(desc, flag);
 }
 
-static void msi_set_mask_bit(unsigned irq, u32 flag)
+static void msi_set_mask_bit(struct irq_data *data, u32 flag)
 {
-	struct msi_desc *desc = get_irq_msi(irq);
+	struct msi_desc *desc = data->msi_desc;
 
 	if (desc->msi_attrib.is_msix) {
 		msix_mask_irq(desc, flag);
 		readl(desc->mask_base);		/* Flush write to device */
 	} else {
-		unsigned offset = irq - desc->dev->irq;
+		unsigned offset = data->irq - desc->dev->irq;
 		msi_mask_irq(desc, 1 << offset, flag << offset);
 	}
 }
 
-void mask_msi_irq(unsigned int irq)
+void mask_msi_irq(struct irq_data *data)
 {
-	msi_set_mask_bit(irq, 1);
+	msi_set_mask_bit(data, 1);
 }
 
-void unmask_msi_irq(unsigned int irq)
+void unmask_msi_irq(struct irq_data *data)
 {
-	msi_set_mask_bit(irq, 0);
+	msi_set_mask_bit(data, 0);
 }
 
 void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
Index: linux-2.6-tip/include/linux/msi.h
===================================================================
--- linux-2.6-tip.orig/include/linux/msi.h
+++ linux-2.6-tip/include/linux/msi.h
@@ -11,8 +11,9 @@ struct msi_msg {
 
 /* Helper functions */
 struct irq_desc;
-extern void mask_msi_irq(unsigned int irq);
-extern void unmask_msi_irq(unsigned int irq);
+struct irq_data;
+extern void mask_msi_irq(struct irq_data *data);
+extern void unmask_msi_irq(struct irq_data *data);
 extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
 extern void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
 extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);



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

* [patch 30/47] dmar: Convert to new irq chip functions
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (28 preceding siblings ...)
  2010-09-30 23:16 ` [patch 29/47] pci: Convert msi to new irq_chip functions Thomas Gleixner
@ 2010-09-30 23:16 ` Thomas Gleixner
  2010-09-30 23:17 ` [patch 31/47] ht: Convert to new irq_chip functions Thomas Gleixner
                   ` (20 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: dmar-convert-irq-functions.patch --]
[-- Type: text/plain, Size: 3009 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/ia64/kernel/msi_ia64.c    |    4 ++--
 arch/x86/kernel/apic/io_apic.c |    4 ++--
 drivers/pci/dmar.c             |    8 ++++----
 include/linux/dmar.h           |    5 +++--
 4 files changed, 11 insertions(+), 10 deletions(-)

Index: linux-2.6-tip/arch/ia64/kernel/msi_ia64.c
===================================================================
--- linux-2.6-tip.orig/arch/ia64/kernel/msi_ia64.c
+++ linux-2.6-tip/arch/ia64/kernel/msi_ia64.c
@@ -160,8 +160,8 @@ static int dmar_msi_set_affinity(unsigne
 
 static struct irq_chip dmar_msi_type = {
 	.name = "DMAR_MSI",
-	.unmask = dmar_msi_unmask,
-	.mask = dmar_msi_mask,
+	.irq_unmask = dmar_msi_unmask,
+	.irq_mask = dmar_msi_mask,
 	.ack = ia64_ack_msi_irq,
 #ifdef CONFIG_SMP
 	.set_affinity = dmar_msi_set_affinity,
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3599,8 +3599,8 @@ static int dmar_msi_set_affinity(unsigne
 
 static struct irq_chip dmar_msi_type = {
 	.name = "DMAR_MSI",
-	.unmask = dmar_msi_unmask,
-	.mask = dmar_msi_mask,
+	.irq_unmask = dmar_msi_unmask,
+	.irq_mask = dmar_msi_mask,
 	.irq_ack = ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity = dmar_msi_set_affinity,
Index: linux-2.6-tip/drivers/pci/dmar.c
===================================================================
--- linux-2.6-tip.orig/drivers/pci/dmar.c
+++ linux-2.6-tip/drivers/pci/dmar.c
@@ -1221,9 +1221,9 @@ const char *dmar_get_fault_reason(u8 fau
 	}
 }
 
-void dmar_msi_unmask(unsigned int irq)
+void dmar_msi_unmask(struct irq_data *data)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	struct intel_iommu *iommu = data->handler_data;
 	unsigned long flag;
 
 	/* unmask it */
@@ -1234,10 +1234,10 @@ void dmar_msi_unmask(unsigned int irq)
 	spin_unlock_irqrestore(&iommu->register_lock, flag);
 }
 
-void dmar_msi_mask(unsigned int irq)
+void dmar_msi_mask(struct irq_data *data)
 {
 	unsigned long flag;
-	struct intel_iommu *iommu = get_irq_data(irq);
+	struct intel_iommu *iommu = data->handler_data;
 
 	/* mask it */
 	spin_lock_irqsave(&iommu->register_lock, flag);
Index: linux-2.6-tip/include/linux/dmar.h
===================================================================
--- linux-2.6-tip.orig/include/linux/dmar.h
+++ linux-2.6-tip/include/linux/dmar.h
@@ -187,8 +187,9 @@ static inline int set_msi_sid(struct irt
 /* Can't use the common MSI interrupt functions
  * since DMAR is not a pci device
  */
-extern void dmar_msi_unmask(unsigned int irq);
-extern void dmar_msi_mask(unsigned int irq);
+struct irq_data;
+extern void dmar_msi_unmask(struct irq_data *data);
+extern void dmar_msi_mask(struct irq_data *data);
 extern void dmar_msi_read(int irq, struct msi_msg *msg);
 extern void dmar_msi_write(int irq, struct msi_msg *msg);
 extern int dmar_set_interrupt(struct intel_iommu *iommu);

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

* [patch 31/47] ht: Convert to new irq_chip functions
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (29 preceding siblings ...)
  2010-09-30 23:16 ` [patch 30/47] dmar: Convert to new irq chip functions Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-09-30 23:17   ` Thomas Gleixner
  2010-09-30 23:17 ` [patch 32/47] x86: ioapic: Clean up the direct access to irq_desc Thomas Gleixner
                   ` (19 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: ht-convert-irq-functions.patch --]
[-- Type: text/plain, Size: 2491 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |    4 ++--
 drivers/pci/htirq.c            |   22 ++++++++--------------
 include/linux/htirq.h          |    5 +++--
 3 files changed, 13 insertions(+), 18 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3751,8 +3751,8 @@ static int set_ht_irq_affinity(unsigned 
 
 static struct irq_chip ht_irq_chip = {
 	.name		= "PCI-HT",
-	.mask		= mask_ht_irq,
-	.unmask		= unmask_ht_irq,
+	.irq_mask	= mask_ht_irq,
+	.irq_unmask	= unmask_ht_irq,
 	.irq_ack	= ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_ht_irq_affinity,
Index: linux-2.6-tip/drivers/pci/htirq.c
===================================================================
--- linux-2.6-tip.orig/drivers/pci/htirq.c
+++ linux-2.6-tip/drivers/pci/htirq.c
@@ -57,28 +57,22 @@ void fetch_ht_irq_msg(unsigned int irq, 
 	*msg = cfg->msg;
 }
 
-void mask_ht_irq(unsigned int irq)
+void mask_ht_irq(struct irq_data *data)
 {
-	struct ht_irq_cfg *cfg;
-	struct ht_irq_msg msg;
-
-	cfg = get_irq_data(irq);
+	struct ht_irq_cfg *cfg = data->handler_data;
+	struct ht_irq_msg msg = cfg->msg;
 
-	msg = cfg->msg;
 	msg.address_lo |= 1;
-	write_ht_irq_msg(irq, &msg);
+	write_ht_irq_msg(data->irq, &msg);
 }
 
-void unmask_ht_irq(unsigned int irq)
+void unmask_ht_irq(struct irq_data *data)
 {
-	struct ht_irq_cfg *cfg;
-	struct ht_irq_msg msg;
-
-	cfg = get_irq_data(irq);
+	struct ht_irq_cfg *cfg = data->handler_data;
+	struct ht_irq_msg msg = cfg->msg;
 
-	msg = cfg->msg;
 	msg.address_lo &= ~1;
-	write_ht_irq_msg(irq, &msg);
+	write_ht_irq_msg(data->irq, &msg);
 }
 
 /**
Index: linux-2.6-tip/include/linux/htirq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/htirq.h
+++ linux-2.6-tip/include/linux/htirq.h
@@ -9,8 +9,9 @@ struct ht_irq_msg {
 /* Helper functions.. */
 void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
 void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
-void mask_ht_irq(unsigned int irq);
-void unmask_ht_irq(unsigned int irq);
+struct irq_data;
+void mask_ht_irq(struct irq_data *data);
+void unmask_ht_irq(struct irq_data *data);
 
 /* The arch hook for getting things started */
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev);

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

* [patch 31/47] ht: Convert to new irq_chip functions
  2010-09-30 23:17 ` [patch 31/47] ht: Convert to new irq_chip functions Thomas Gleixner
@ 2010-09-30 23:17   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: ht-convert-irq-functions.patch --]
[-- Type: text/plain, Size: 2493 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |    4 ++--
 drivers/pci/htirq.c            |   22 ++++++++--------------
 include/linux/htirq.h          |    5 +++--
 3 files changed, 13 insertions(+), 18 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3751,8 +3751,8 @@ static int set_ht_irq_affinity(unsigned 
 
 static struct irq_chip ht_irq_chip = {
 	.name		= "PCI-HT",
-	.mask		= mask_ht_irq,
-	.unmask		= unmask_ht_irq,
+	.irq_mask	= mask_ht_irq,
+	.irq_unmask	= unmask_ht_irq,
 	.irq_ack	= ack_apic_edge,
 #ifdef CONFIG_SMP
 	.set_affinity	= set_ht_irq_affinity,
Index: linux-2.6-tip/drivers/pci/htirq.c
===================================================================
--- linux-2.6-tip.orig/drivers/pci/htirq.c
+++ linux-2.6-tip/drivers/pci/htirq.c
@@ -57,28 +57,22 @@ void fetch_ht_irq_msg(unsigned int irq, 
 	*msg = cfg->msg;
 }
 
-void mask_ht_irq(unsigned int irq)
+void mask_ht_irq(struct irq_data *data)
 {
-	struct ht_irq_cfg *cfg;
-	struct ht_irq_msg msg;
-
-	cfg = get_irq_data(irq);
+	struct ht_irq_cfg *cfg = data->handler_data;
+	struct ht_irq_msg msg = cfg->msg;
 
-	msg = cfg->msg;
 	msg.address_lo |= 1;
-	write_ht_irq_msg(irq, &msg);
+	write_ht_irq_msg(data->irq, &msg);
 }
 
-void unmask_ht_irq(unsigned int irq)
+void unmask_ht_irq(struct irq_data *data)
 {
-	struct ht_irq_cfg *cfg;
-	struct ht_irq_msg msg;
-
-	cfg = get_irq_data(irq);
+	struct ht_irq_cfg *cfg = data->handler_data;
+	struct ht_irq_msg msg = cfg->msg;
 
-	msg = cfg->msg;
 	msg.address_lo &= ~1;
-	write_ht_irq_msg(irq, &msg);
+	write_ht_irq_msg(data->irq, &msg);
 }
 
 /**
Index: linux-2.6-tip/include/linux/htirq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/htirq.h
+++ linux-2.6-tip/include/linux/htirq.h
@@ -9,8 +9,9 @@ struct ht_irq_msg {
 /* Helper functions.. */
 void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
 void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
-void mask_ht_irq(unsigned int irq);
-void unmask_ht_irq(unsigned int irq);
+struct irq_data;
+void mask_ht_irq(struct irq_data *data);
+void unmask_ht_irq(struct irq_data *data);
 
 /* The arch hook for getting things started */
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev);



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

* [patch 32/47] x86: ioapic: Clean up the direct access to irq_desc
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (30 preceding siblings ...)
  2010-09-30 23:17 ` [patch 31/47] ht: Convert to new irq_chip functions Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-09-30 23:17   ` Thomas Gleixner
  2010-09-30 23:17 ` [patch 33/47] pci: Cleanup the irq_desc mess in msi Thomas Gleixner
                   ` (18 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-ioapic-fix-irq-desc-hackery.patch --]
[-- Type: text/plain, Size: 8036 bytes --]

Most of it is useless pseudo optimization.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |   81 ++++++++++++++---------------------------
 1 file changed, 29 insertions(+), 52 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -150,10 +150,7 @@ static struct irq_cfg irq_cfgx[NR_IRQS];
 int __init arch_early_irq_init(void)
 {
 	struct irq_cfg *cfg;
-	struct irq_desc *desc;
-	int count;
-	int node;
-	int i;
+	int count, node, i;
 
 	if (!legacy_pic->nr_legacy_irqs) {
 		nr_irqs_gsi = 0;
@@ -162,11 +159,10 @@ int __init arch_early_irq_init(void)
 
 	cfg = irq_cfgx;
 	count = ARRAY_SIZE(irq_cfgx);
-	node= cpu_to_node(boot_cpu_id);
+	node = cpu_to_node(boot_cpu_id);
 
 	for (i = 0; i < count; i++) {
-		desc = irq_to_desc(i);
-		set_irq_desc_chip_data(desc, &cfg[i]);
+		set_irq_chip_data(i, &cfg[i]);
 		zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
 		zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node);
 		/*
@@ -185,14 +181,7 @@ int __init arch_early_irq_init(void)
 #ifdef CONFIG_SPARSE_IRQ
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
-	struct irq_cfg *cfg = NULL;
-	struct irq_desc *desc;
-
-	desc = irq_to_desc(irq);
-	if (desc)
-		cfg = get_irq_desc_chip_data(desc);
-
-	return cfg;
+	return get_irq_chip_data(irq);
 }
 
 static struct irq_cfg *get_one_free_irq_cfg(int node)
@@ -1316,17 +1305,17 @@ static inline int IO_APIC_irq_trigger(in
 }
 #endif
 
-static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long trigger)
+static void ioapic_register_intr(unsigned int irq, unsigned long trigger)
 {
 
 	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
 	    trigger == IOAPIC_LEVEL)
-		desc->status |= IRQ_LEVEL;
+		irq_set_status_flags(irq, IRQ_LEVEL);
 	else
-		desc->status &= ~IRQ_LEVEL;
+		irq_clear_status_flags(irq, IRQ_LEVEL);
 
 	if (irq_remapped(irq)) {
-		desc->status |= IRQ_MOVE_PCNTXT;
+		irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
 		if (trigger)
 			set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
 						      handle_fasteoi_irq,
@@ -1420,18 +1409,14 @@ int setup_ioapic_entry(int apic_id, int 
 	return 0;
 }
 
-static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq_desc *desc,
-			      int trigger, int polarity)
+static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq,
+			     struct irq_cfg *cfg, int trigger, int polarity)
 {
-	struct irq_cfg *cfg;
 	struct IO_APIC_route_entry entry;
 	unsigned int dest;
 
 	if (!IO_APIC_IRQ(irq))
 		return;
-
-	cfg = get_irq_desc_chip_data(desc);
-
 	/*
 	 * For legacy irqs, cfg->domain starts with cpu 0 for legacy
 	 * controllers like 8259. Now that IO-APIC can handle this irq, update
@@ -1460,7 +1445,7 @@ static void setup_IO_APIC_irq(int apic_i
 		return;
 	}
 
-	ioapic_register_intr(irq, desc, trigger);
+	ioapic_register_intr(irq, trigger);
 	if (irq < legacy_pic->nr_legacy_irqs)
 		legacy_pic->mask(irq);
 
@@ -1525,8 +1510,8 @@ static void __init setup_IO_APIC_irqs(vo
 		 * don't mark it in pin_programmed, so later acpi could
 		 * set it correctly when irq < 16
 		 */
-		setup_IO_APIC_irq(apic_id, pin, irq, desc,
-				irq_trigger(idx), irq_polarity(idx));
+		setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx),
+				  irq_polarity(idx));
 	}
 
 	if (notcon)
@@ -1580,7 +1565,7 @@ void setup_IO_APIC_irq_extra(u32 gsi)
 	}
 	set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
 
-	setup_IO_APIC_irq(apic_id, pin, irq, desc,
+	setup_ioapic_irq(apic_id, pin, irq, cfg,
 			irq_trigger(idx), irq_polarity(idx));
 }
 
@@ -2790,9 +2775,9 @@ static struct irq_chip lapic_chip __read
 	.irq_ack	= ack_lapic_irq,
 };
 
-static void lapic_register_intr(int irq, struct irq_desc *desc)
+static void lapic_register_intr(int irq)
 {
-	desc->status &= ~IRQ_LEVEL;
+	irq_clear_status_flags(irq, IRQ_LEVEL);
 	set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
 				      "edge");
 }
@@ -2895,8 +2880,7 @@ int timer_through_8259 __initdata;
  */
 static inline void __init check_timer(void)
 {
-	struct irq_desc *desc = irq_to_desc(0);
-	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
+	struct irq_cfg *cfg = get_irq_chip_data(0);
 	int node = cpu_to_node(boot_cpu_id);
 	int apic1, pin1, apic2, pin2;
 	unsigned long flags;
@@ -2966,7 +2950,7 @@ static inline void __init check_timer(vo
 			add_pin_to_irq_node(cfg, node, apic1, pin1);
 			setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
 		} else {
-			/* for edge trigger, setup_IO_APIC_irq already
+			/* for edge trigger, setup_ioapic_irq already
 			 * leave it unmasked.
 			 * so only need to unmask if it is level-trigger
 			 * do we really have level trigger timer?
@@ -3034,7 +3018,7 @@ static inline void __init check_timer(vo
 	apic_printk(APIC_QUIET, KERN_INFO
 		    "...trying to set up timer as Virtual Wire IRQ...\n");
 
-	lapic_register_intr(0, desc);
+	lapic_register_intr(0);
 	apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);	/* Fixed mode */
 	legacy_pic->unmask(0);
 
@@ -3478,8 +3462,8 @@ static int msi_alloc_irte(struct pci_dev
 
 static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
 {
-	int ret;
 	struct msi_msg msg;
+	int ret;
 
 	ret = msi_compose_msg(dev, irq, &msg, -1);
 	if (ret < 0)
@@ -3489,11 +3473,7 @@ static int setup_msi_irq(struct pci_dev 
 	write_msi_msg(irq, &msg);
 
 	if (irq_remapped(irq)) {
-		struct irq_desc *desc = irq_to_desc(irq);
-		/*
-		 * irq migration in process context
-		 */
-		desc->status |= IRQ_MOVE_PCNTXT;
+		irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
 		set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge");
 	} else
 		set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
@@ -3505,13 +3485,10 @@ static int setup_msi_irq(struct pci_dev 
 
 int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
-	unsigned int irq;
-	int ret, sub_handle;
+	int node, ret, sub_handle, index = 0;
+	unsigned int irq, irq_want;
 	struct msi_desc *msidesc;
-	unsigned int irq_want;
 	struct intel_iommu *iommu = NULL;
-	int index = 0;
-	int node;
 
 	/* x86 doesn't support multiple MSI yet */
 	if (type == PCI_CAP_ID_MSI && nvec > 1)
@@ -3697,7 +3674,7 @@ int arch_setup_hpet_msi(unsigned int irq
 		return ret;
 
 	hpet_msi_write(get_irq_data(irq), &msg);
-	irq_set_status_flags(irq,IRQ_MOVE_PCNTXT);
+	irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
 	if (irq_remapped(irq))
 		set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type,
 					      handle_edge_irq, "edge");
@@ -3883,11 +3860,12 @@ static int __io_apic_set_pci_routing(str
 	trigger = irq_attr->trigger;
 	polarity = irq_attr->polarity;
 
+	cfg = get_irq_desc_chip_data(desc);
+
 	/*
 	 * IRQs < 16 are already in the irq_2_pin[] map
 	 */
 	if (irq >= legacy_pic->nr_legacy_irqs) {
-		cfg = get_irq_desc_chip_data(desc);
 		if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
 			printk(KERN_INFO "can not add pin %d for irq %d\n",
 				pin, irq);
@@ -3895,7 +3873,7 @@ static int __io_apic_set_pci_routing(str
 		}
 	}
 
-	setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity);
+	setup_ioapic_irq(ioapic, pin, irq, cfg, trigger, polarity);
 
 	return 0;
 }
@@ -4279,13 +4257,12 @@ void __init mp_register_ioapic(int id, u
 void __init pre_init_apic_IRQ0(void)
 {
 	struct irq_cfg *cfg;
-	struct irq_desc *desc;
 
 	printk(KERN_INFO "Early APIC setup for system timer0\n");
 #ifndef CONFIG_SMP
 	phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
 #endif
-	desc = irq_to_desc_alloc_node(0, 0);
+	irq_to_desc_alloc_node(0, 0);
 
 	setup_local_APIC();
 
@@ -4293,5 +4270,5 @@ void __init pre_init_apic_IRQ0(void)
 	add_pin_to_irq_node(cfg, 0, 0, 0);
 	set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
 
-	setup_IO_APIC_irq(0, 0, 0, desc, 0, 0);
+	setup_ioapic_irq(0, 0, 0, cfg, 0, 0);
 }

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

* [patch 32/47] x86: ioapic: Clean up the direct access to irq_desc
  2010-09-30 23:17 ` [patch 32/47] x86: ioapic: Clean up the direct access to irq_desc Thomas Gleixner
@ 2010-09-30 23:17   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-ioapic-fix-irq-desc-hackery.patch --]
[-- Type: text/plain, Size: 8038 bytes --]

Most of it is useless pseudo optimization.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |   81 ++++++++++++++---------------------------
 1 file changed, 29 insertions(+), 52 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -150,10 +150,7 @@ static struct irq_cfg irq_cfgx[NR_IRQS];
 int __init arch_early_irq_init(void)
 {
 	struct irq_cfg *cfg;
-	struct irq_desc *desc;
-	int count;
-	int node;
-	int i;
+	int count, node, i;
 
 	if (!legacy_pic->nr_legacy_irqs) {
 		nr_irqs_gsi = 0;
@@ -162,11 +159,10 @@ int __init arch_early_irq_init(void)
 
 	cfg = irq_cfgx;
 	count = ARRAY_SIZE(irq_cfgx);
-	node= cpu_to_node(boot_cpu_id);
+	node = cpu_to_node(boot_cpu_id);
 
 	for (i = 0; i < count; i++) {
-		desc = irq_to_desc(i);
-		set_irq_desc_chip_data(desc, &cfg[i]);
+		set_irq_chip_data(i, &cfg[i]);
 		zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
 		zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node);
 		/*
@@ -185,14 +181,7 @@ int __init arch_early_irq_init(void)
 #ifdef CONFIG_SPARSE_IRQ
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
-	struct irq_cfg *cfg = NULL;
-	struct irq_desc *desc;
-
-	desc = irq_to_desc(irq);
-	if (desc)
-		cfg = get_irq_desc_chip_data(desc);
-
-	return cfg;
+	return get_irq_chip_data(irq);
 }
 
 static struct irq_cfg *get_one_free_irq_cfg(int node)
@@ -1316,17 +1305,17 @@ static inline int IO_APIC_irq_trigger(in
 }
 #endif
 
-static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long trigger)
+static void ioapic_register_intr(unsigned int irq, unsigned long trigger)
 {
 
 	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
 	    trigger == IOAPIC_LEVEL)
-		desc->status |= IRQ_LEVEL;
+		irq_set_status_flags(irq, IRQ_LEVEL);
 	else
-		desc->status &= ~IRQ_LEVEL;
+		irq_clear_status_flags(irq, IRQ_LEVEL);
 
 	if (irq_remapped(irq)) {
-		desc->status |= IRQ_MOVE_PCNTXT;
+		irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
 		if (trigger)
 			set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
 						      handle_fasteoi_irq,
@@ -1420,18 +1409,14 @@ int setup_ioapic_entry(int apic_id, int 
 	return 0;
 }
 
-static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq_desc *desc,
-			      int trigger, int polarity)
+static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq,
+			     struct irq_cfg *cfg, int trigger, int polarity)
 {
-	struct irq_cfg *cfg;
 	struct IO_APIC_route_entry entry;
 	unsigned int dest;
 
 	if (!IO_APIC_IRQ(irq))
 		return;
-
-	cfg = get_irq_desc_chip_data(desc);
-
 	/*
 	 * For legacy irqs, cfg->domain starts with cpu 0 for legacy
 	 * controllers like 8259. Now that IO-APIC can handle this irq, update
@@ -1460,7 +1445,7 @@ static void setup_IO_APIC_irq(int apic_i
 		return;
 	}
 
-	ioapic_register_intr(irq, desc, trigger);
+	ioapic_register_intr(irq, trigger);
 	if (irq < legacy_pic->nr_legacy_irqs)
 		legacy_pic->mask(irq);
 
@@ -1525,8 +1510,8 @@ static void __init setup_IO_APIC_irqs(vo
 		 * don't mark it in pin_programmed, so later acpi could
 		 * set it correctly when irq < 16
 		 */
-		setup_IO_APIC_irq(apic_id, pin, irq, desc,
-				irq_trigger(idx), irq_polarity(idx));
+		setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx),
+				  irq_polarity(idx));
 	}
 
 	if (notcon)
@@ -1580,7 +1565,7 @@ void setup_IO_APIC_irq_extra(u32 gsi)
 	}
 	set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
 
-	setup_IO_APIC_irq(apic_id, pin, irq, desc,
+	setup_ioapic_irq(apic_id, pin, irq, cfg,
 			irq_trigger(idx), irq_polarity(idx));
 }
 
@@ -2790,9 +2775,9 @@ static struct irq_chip lapic_chip __read
 	.irq_ack	= ack_lapic_irq,
 };
 
-static void lapic_register_intr(int irq, struct irq_desc *desc)
+static void lapic_register_intr(int irq)
 {
-	desc->status &= ~IRQ_LEVEL;
+	irq_clear_status_flags(irq, IRQ_LEVEL);
 	set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
 				      "edge");
 }
@@ -2895,8 +2880,7 @@ int timer_through_8259 __initdata;
  */
 static inline void __init check_timer(void)
 {
-	struct irq_desc *desc = irq_to_desc(0);
-	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
+	struct irq_cfg *cfg = get_irq_chip_data(0);
 	int node = cpu_to_node(boot_cpu_id);
 	int apic1, pin1, apic2, pin2;
 	unsigned long flags;
@@ -2966,7 +2950,7 @@ static inline void __init check_timer(vo
 			add_pin_to_irq_node(cfg, node, apic1, pin1);
 			setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
 		} else {
-			/* for edge trigger, setup_IO_APIC_irq already
+			/* for edge trigger, setup_ioapic_irq already
 			 * leave it unmasked.
 			 * so only need to unmask if it is level-trigger
 			 * do we really have level trigger timer?
@@ -3034,7 +3018,7 @@ static inline void __init check_timer(vo
 	apic_printk(APIC_QUIET, KERN_INFO
 		    "...trying to set up timer as Virtual Wire IRQ...\n");
 
-	lapic_register_intr(0, desc);
+	lapic_register_intr(0);
 	apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);	/* Fixed mode */
 	legacy_pic->unmask(0);
 
@@ -3478,8 +3462,8 @@ static int msi_alloc_irte(struct pci_dev
 
 static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
 {
-	int ret;
 	struct msi_msg msg;
+	int ret;
 
 	ret = msi_compose_msg(dev, irq, &msg, -1);
 	if (ret < 0)
@@ -3489,11 +3473,7 @@ static int setup_msi_irq(struct pci_dev 
 	write_msi_msg(irq, &msg);
 
 	if (irq_remapped(irq)) {
-		struct irq_desc *desc = irq_to_desc(irq);
-		/*
-		 * irq migration in process context
-		 */
-		desc->status |= IRQ_MOVE_PCNTXT;
+		irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
 		set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge");
 	} else
 		set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
@@ -3505,13 +3485,10 @@ static int setup_msi_irq(struct pci_dev 
 
 int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
-	unsigned int irq;
-	int ret, sub_handle;
+	int node, ret, sub_handle, index = 0;
+	unsigned int irq, irq_want;
 	struct msi_desc *msidesc;
-	unsigned int irq_want;
 	struct intel_iommu *iommu = NULL;
-	int index = 0;
-	int node;
 
 	/* x86 doesn't support multiple MSI yet */
 	if (type == PCI_CAP_ID_MSI && nvec > 1)
@@ -3697,7 +3674,7 @@ int arch_setup_hpet_msi(unsigned int irq
 		return ret;
 
 	hpet_msi_write(get_irq_data(irq), &msg);
-	irq_set_status_flags(irq,IRQ_MOVE_PCNTXT);
+	irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
 	if (irq_remapped(irq))
 		set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type,
 					      handle_edge_irq, "edge");
@@ -3883,11 +3860,12 @@ static int __io_apic_set_pci_routing(str
 	trigger = irq_attr->trigger;
 	polarity = irq_attr->polarity;
 
+	cfg = get_irq_desc_chip_data(desc);
+
 	/*
 	 * IRQs < 16 are already in the irq_2_pin[] map
 	 */
 	if (irq >= legacy_pic->nr_legacy_irqs) {
-		cfg = get_irq_desc_chip_data(desc);
 		if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
 			printk(KERN_INFO "can not add pin %d for irq %d\n",
 				pin, irq);
@@ -3895,7 +3873,7 @@ static int __io_apic_set_pci_routing(str
 		}
 	}
 
-	setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity);
+	setup_ioapic_irq(ioapic, pin, irq, cfg, trigger, polarity);
 
 	return 0;
 }
@@ -4279,13 +4257,12 @@ void __init mp_register_ioapic(int id, u
 void __init pre_init_apic_IRQ0(void)
 {
 	struct irq_cfg *cfg;
-	struct irq_desc *desc;
 
 	printk(KERN_INFO "Early APIC setup for system timer0\n");
 #ifndef CONFIG_SMP
 	phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
 #endif
-	desc = irq_to_desc_alloc_node(0, 0);
+	irq_to_desc_alloc_node(0, 0);
 
 	setup_local_APIC();
 
@@ -4293,5 +4270,5 @@ void __init pre_init_apic_IRQ0(void)
 	add_pin_to_irq_node(cfg, 0, 0, 0);
 	set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
 
-	setup_IO_APIC_irq(0, 0, 0, desc, 0, 0);
+	setup_ioapic_irq(0, 0, 0, cfg, 0, 0);
 }



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

* [patch 33/47] pci: Cleanup the irq_desc mess in msi
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (31 preceding siblings ...)
  2010-09-30 23:17 ` [patch 32/47] x86: ioapic: Clean up the direct access to irq_desc Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-10-11 17:08   ` Jesse Barnes
  2010-09-30 23:17 ` [patch 34/47] x86: ioapic: Convert irq affinity to new chip functions Thomas Gleixner
                   ` (17 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: pci-cleanup-msi-irq-desc-mess.patch --]
[-- Type: text/plain, Size: 4420 bytes --]

Handing down irq_desc to msi just so that msi can access
irq_desc.irq_data.msi_desc is a pretty stupid idea. The calling code
can hand down a pointer to msi_desc so msi code does not need to know
about the irq descriptor at all.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |    4 ++--
 drivers/pci/msi.c              |   24 +++++++++---------------
 include/linux/msi.h            |    8 ++++----
 3 files changed, 15 insertions(+), 21 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -3353,14 +3353,14 @@ static int set_msi_irq_affinity(unsigned
 
 	cfg = get_irq_desc_chip_data(desc);
 
-	get_cached_msi_msg_desc(desc, &msg);
+	__get_cached_msi_msg(desc->irq_data.msi_desc, &msg);
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
 	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
-	write_msi_msg_desc(desc, &msg);
+	__write_msi_msg(desc->irq_data.msi_desc, &msg);
 
 	return 0;
 }
Index: linux-2.6-tip/drivers/pci/msi.c
===================================================================
--- linux-2.6-tip.orig/drivers/pci/msi.c
+++ linux-2.6-tip/drivers/pci/msi.c
@@ -193,10 +193,8 @@ void unmask_msi_irq(struct irq_data *dat
 	msi_set_mask_bit(data, 0);
 }
 
-void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
+void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
 {
-	struct msi_desc *entry = get_irq_desc_msi(desc);
-
 	BUG_ON(entry->dev->current_state != PCI_D0);
 
 	if (entry->msi_attrib.is_msix) {
@@ -227,15 +225,13 @@ void read_msi_msg_desc(struct irq_desc *
 
 void read_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	struct msi_desc *entry = get_irq_msi(irq);
 
-	read_msi_msg_desc(desc, msg);
+	__read_msi_msg(entry, msg);
 }
 
-void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
+void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
 {
-	struct msi_desc *entry = get_irq_desc_msi(desc);
-
 	/* Assert that the cache is valid, assuming that
 	 * valid messages are not all-zeroes. */
 	BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo |
@@ -246,15 +242,13 @@ void get_cached_msi_msg_desc(struct irq_
 
 void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	struct msi_desc *entry = get_irq_msi(irq);
 
-	get_cached_msi_msg_desc(desc, msg);
+	__get_cached_msi_msg(entry, msg);
 }
 
-void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
+void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
 {
-	struct msi_desc *entry = get_irq_desc_msi(desc);
-
 	if (entry->dev->current_state != PCI_D0) {
 		/* Don't touch the hardware now */
 	} else if (entry->msi_attrib.is_msix) {
@@ -292,9 +286,9 @@ void write_msi_msg_desc(struct irq_desc 
 
 void write_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	struct msi_desc *entry = get_irq_msi(irq);
 
-	write_msi_msg_desc(desc, msg);
+	__write_msi_msg(entry, msg);
 }
 
 static void free_msi_irqs(struct pci_dev *dev)
Index: linux-2.6-tip/include/linux/msi.h
===================================================================
--- linux-2.6-tip.orig/include/linux/msi.h
+++ linux-2.6-tip/include/linux/msi.h
@@ -10,13 +10,13 @@ struct msi_msg {
 };
 
 /* Helper functions */
-struct irq_desc;
 struct irq_data;
+struct msi_desc;
 extern void mask_msi_irq(struct irq_data *data);
 extern void unmask_msi_irq(struct irq_data *data);
-extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
-extern void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
-extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
+extern void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
+extern void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
+extern void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
 extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
 extern void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);
 extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);

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

* [patch 34/47] x86: ioapic: Convert irq affinity to new chip functions
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (32 preceding siblings ...)
  2010-09-30 23:17 ` [patch 33/47] pci: Cleanup the irq_desc mess in msi Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-09-30 23:17 ` [patch 35/47] x86: ioapic: Cleanup some more Thomas Gleixner
                   ` (16 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-ioapic-affinity.patch --]
[-- Type: text/plain, Size: 13147 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/hw_irq.h  |    6 -
 arch/x86/kernel/apic/io_apic.c |  215 ++++++++++++++++-------------------------
 arch/x86/kernel/uv_irq.c       |    2 
 3 files changed, 90 insertions(+), 133 deletions(-)

Index: linux-2.6-tip/arch/x86/include/asm/hw_irq.h
===================================================================
--- linux-2.6-tip.orig/arch/x86/include/asm/hw_irq.h
+++ linux-2.6-tip/arch/x86/include/asm/hw_irq.h
@@ -95,9 +95,9 @@ extern struct irq_cfg *irq_cfg(unsigned 
 extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
 extern void send_cleanup_vector(struct irq_cfg *);
 
-struct irq_desc;
-extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *,
-				      unsigned int *dest_id);
+struct irq_data;
+unsigned int __ioapic_set_affinity(struct irq_data *, const struct cpumask *,
+				   unsigned int *dest_id);
 extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr);
 extern void setup_ioapic_dest(void);
 
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -2293,65 +2293,47 @@ static void __target_IO_APIC_irq(unsigne
 }
 
 /*
- * Either sets desc->affinity to a valid value, and returns
+ * Either sets data->affinity to a valid value, and returns
  * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and
- * leaves desc->affinity untouched.
+ * leaves data->affinity untouched.
  */
 unsigned int
-set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask,
-		  unsigned int *dest_id)
+__ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+		      unsigned int *dest_id)
 {
-	struct irq_cfg *cfg;
-	unsigned int irq;
+	struct irq_cfg *cfg = data->chip_data;
 
 	if (!cpumask_intersects(mask, cpu_online_mask))
 		return -1;
 
-	irq = desc->irq;
-	cfg = get_irq_desc_chip_data(desc);
-	if (assign_irq_vector(irq, cfg, mask))
+	if (assign_irq_vector(data->irq, data->chip_data, mask))
 		return -1;
 
-	cpumask_copy(desc->affinity, mask);
+	cpumask_copy(*data->affinity, mask);
 
-	*dest_id = apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+	*dest_id = apic->cpu_mask_to_apicid_and(mask, cfg->domain);
 	return 0;
 }
 
 static int
-set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
+ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+			     bool force)
 {
-	struct irq_cfg *cfg;
+	unsigned int dest, irq = data->irq;
 	unsigned long flags;
-	unsigned int dest;
-	unsigned int irq;
-	int ret = -1;
-
-	irq = desc->irq;
-	cfg = get_irq_desc_chip_data(desc);
+	int ret;
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
-	ret = set_desc_affinity(desc, mask, &dest);
+	ret = __ioapic_set_affinity(data, mask, &dest);
 	if (!ret) {
 		/* Only the high 8 bits are valid. */
 		dest = SET_APIC_LOGICAL_ID(dest);
-		__target_IO_APIC_irq(irq, dest, cfg);
+		__target_IO_APIC_irq(irq, dest, data->chip_data);
 	}
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-
 	return ret;
 }
 
-static int
-set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
-{
-	struct irq_desc *desc;
-
-	desc = irq_to_desc(irq);
-
-	return set_ioapic_affinity_irq_desc(desc, mask);
-}
-
 #ifdef CONFIG_INTR_REMAP
 
 /*
@@ -2366,24 +2348,21 @@ set_ioapic_affinity_irq(unsigned int irq
  * the interrupt-remapping table entry.
  */
 static int
-migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
+ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+		       bool force)
 {
-	struct irq_cfg *cfg;
+	struct irq_cfg *cfg = data->chip_data;
+	unsigned int dest, irq = data->irq;
 	struct irte irte;
-	unsigned int dest;
-	unsigned int irq;
-	int ret = -1;
 
 	if (!cpumask_intersects(mask, cpu_online_mask))
-		return ret;
+		return -EINVAL;
 
-	irq = desc->irq;
 	if (get_irte(irq, &irte))
-		return ret;
+		return -EBUSY;
 
-	cfg = get_irq_desc_chip_data(desc);
 	if (assign_irq_vector(irq, cfg, mask))
-		return ret;
+		return -EBUSY;
 
 	dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
 
@@ -2398,29 +2377,14 @@ migrate_ioapic_irq_desc(struct irq_desc 
 	if (cfg->move_in_progress)
 		send_cleanup_vector(cfg);
 
-	cpumask_copy(desc->affinity, mask);
-
+	cpumask_copy(*data->affinity, mask);
 	return 0;
 }
 
-/*
- * Migrates the IRQ destination in the process context.
- */
-static int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
-					    const struct cpumask *mask)
-{
-	return migrate_ioapic_irq_desc(desc, mask);
-}
-static int set_ir_ioapic_affinity_irq(unsigned int irq,
-				       const struct cpumask *mask)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	return set_ir_ioapic_affinity_irq_desc(desc, mask);
-}
 #else
-static inline int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
-						   const struct cpumask *mask)
+static inline int
+ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+		       bool force)
 {
 	return 0;
 }
@@ -2682,31 +2646,31 @@ static void ir_ack_apic_level(struct irq
 #endif /* CONFIG_INTR_REMAP */
 
 static struct irq_chip ioapic_chip __read_mostly = {
-	.name		= "IO-APIC",
-	.irq_startup	= startup_ioapic_irq,
-	.irq_mask	= mask_ioapic_irq,
-	.irq_unmask	= unmask_ioapic_irq,
-	.irq_ack	= ack_apic_edge,
-	.irq_eoi	= ack_apic_level,
+	.name			= "IO-APIC",
+	.irq_startup		= startup_ioapic_irq,
+	.irq_mask		= mask_ioapic_irq,
+	.irq_unmask		= unmask_ioapic_irq,
+	.irq_ack		= ack_apic_edge,
+	.irq_eoi		= ack_apic_level,
 #ifdef CONFIG_SMP
-	.set_affinity	= set_ioapic_affinity_irq,
+	.irq_set_affinity	= ioapic_set_affinity,
 #endif
-	.irq_retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger		= ioapic_retrigger_irq,
 };
 
 static struct irq_chip ir_ioapic_chip __read_mostly = {
-	.name		= "IR-IO-APIC",
-	.irq_startup	= startup_ioapic_irq,
-	.irq_mask	= mask_ioapic_irq,
-	.irq_unmask	= unmask_ioapic_irq,
+	.name			= "IR-IO-APIC",
+	.irq_startup		= startup_ioapic_irq,
+	.irq_mask		= mask_ioapic_irq,
+	.irq_unmask		= unmask_ioapic_irq,
 #ifdef CONFIG_INTR_REMAP
-	.irq_ack	= ir_ack_apic_edge,
-	.irq_eoi	= ir_ack_apic_level,
+	.irq_ack		= ir_ack_apic_edge,
+	.irq_eoi		= ir_ack_apic_level,
 #ifdef CONFIG_SMP
-	.set_affinity	= set_ir_ioapic_affinity_irq,
+	.irq_set_affinity	= ir_ioapic_set_affinity,
 #endif
 #endif
-	.irq_retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger		= ioapic_retrigger_irq,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -3341,26 +3305,24 @@ static int msi_compose_msg(struct pci_de
 }
 
 #ifdef CONFIG_SMP
-static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
+	struct irq_cfg *cfg = data->chip_data;
 	struct msi_msg msg;
 	unsigned int dest;
 
-	if (set_desc_affinity(desc, mask, &dest))
+	if (__ioapic_set_affinity(data, mask, &dest))
 		return -1;
 
-	cfg = get_irq_desc_chip_data(desc);
-
-	__get_cached_msi_msg(desc->irq_data.msi_desc, &msg);
+	__get_cached_msi_msg(data->msi_desc, &msg);
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
 	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
-	__write_msi_msg(desc->irq_data.msi_desc, &msg);
+	__write_msi_msg(data->msi_desc, &msg);
 
 	return 0;
 }
@@ -3370,17 +3332,17 @@ static int set_msi_irq_affinity(unsigned
  * done in the process context using interrupt-remapping hardware.
  */
 static int
-ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
+ir_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
+		    bool force)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
-	unsigned int dest;
+	struct irq_cfg *cfg = data->chip_data;
+	unsigned int dest, irq = data->irq;
 	struct irte irte;
 
 	if (get_irte(irq, &irte))
 		return -1;
 
-	if (set_desc_affinity(desc, mask, &dest))
+	if (__ioapic_set_affinity(data, mask, &dest))
 		return -1;
 
 	irte.vector = cfg->vector;
@@ -3410,27 +3372,27 @@ ir_set_msi_irq_affinity(unsigned int irq
  * which implement the MSI or MSI-X Capability Structure.
  */
 static struct irq_chip msi_chip = {
-	.name		= "PCI-MSI",
-	.irq_unmask	= unmask_msi_irq,
-	.irq_mask	= mask_msi_irq,
-	.irq_ack	= ack_apic_edge,
+	.name			= "PCI-MSI",
+	.irq_unmask		= unmask_msi_irq,
+	.irq_mask		= mask_msi_irq,
+	.irq_ack		= ack_apic_edge,
 #ifdef CONFIG_SMP
-	.set_affinity	= set_msi_irq_affinity,
+	.irq_set_affinity	= msi_set_affinity,
 #endif
-	.irq_retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger		= ioapic_retrigger_irq,
 };
 
 static struct irq_chip msi_ir_chip = {
-	.name		= "IR-PCI-MSI",
-	.irq_unmask	= unmask_msi_irq,
-	.irq_mask	= mask_msi_irq,
+	.name			= "IR-PCI-MSI",
+	.irq_unmask		= unmask_msi_irq,
+	.irq_mask		= mask_msi_irq,
 #ifdef CONFIG_INTR_REMAP
-	.irq_ack	= ir_ack_apic_edge,
+	.irq_ack		= ir_ack_apic_edge,
 #ifdef CONFIG_SMP
-	.set_affinity	= ir_set_msi_irq_affinity,
+	.irq_set_affinity	= ir_msi_set_affinity,
 #endif
 #endif
-	.irq_retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger		= ioapic_retrigger_irq,
 };
 
 /*
@@ -3548,18 +3510,17 @@ void arch_teardown_msi_irq(unsigned int 
 
 #if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP)
 #ifdef CONFIG_SMP
-static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
+		      bool force)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
+	struct irq_cfg *cfg = data->chip_data;
+	unsigned int dest, irq = data->irq;
 	struct msi_msg msg;
-	unsigned int dest;
 
-	if (set_desc_affinity(desc, mask, &dest))
+	if (__ioapic_set_affinity(data, mask, &dest))
 		return -1;
 
-	cfg = get_irq_desc_chip_data(desc);
-
 	dmar_msi_read(irq, &msg);
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
@@ -3580,7 +3541,7 @@ static struct irq_chip dmar_msi_type = {
 	.irq_mask = dmar_msi_mask,
 	.irq_ack = ack_apic_edge,
 #ifdef CONFIG_SMP
-	.set_affinity = dmar_msi_set_affinity,
+	.irq_set_affinity = dmar_msi_set_affinity,
 #endif
 	.irq_retrigger = ioapic_retrigger_irq,
 };
@@ -3606,12 +3567,11 @@ int arch_setup_dmar_msi(unsigned int irq
 static int hpet_msi_set_affinity(struct irq_data *data,
 				 const struct cpumask *mask, bool force)
 {
-	struct irq_desc *desc = irq_to_desc(data->irq);
 	struct irq_cfg *cfg = data->chip_data;
 	struct msi_msg msg;
 	unsigned int dest;
 
-	if (set_desc_affinity(desc, mask, &dest))
+	if (__ioapic_set_affinity(data, mask, &dest))
 		return -1;
 
 	hpet_msi_read(data->handler_data, &msg);
@@ -3635,7 +3595,7 @@ static struct irq_chip ir_hpet_msi_type 
 #ifdef CONFIG_INTR_REMAP
 	.irq_ack = ir_ack_apic_edge,
 #ifdef CONFIG_SMP
-	.set_affinity = ir_set_msi_irq_affinity,
+	.irq_set_affinity = ir_msi_set_affinity,
 #endif
 #endif
 	.irq_retrigger = ioapic_retrigger_irq,
@@ -3708,33 +3668,30 @@ static void target_ht_irq(unsigned int i
 	write_ht_irq_msg(irq, &msg);
 }
 
-static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
+	struct irq_cfg *cfg = data->chip_data;
 	unsigned int dest;
 
-	if (set_desc_affinity(desc, mask, &dest))
+	if (__ioapic_set_affinity(data, mask, &dest))
 		return -1;
 
-	cfg = get_irq_desc_chip_data(desc);
-
-	target_ht_irq(irq, dest, cfg->vector);
-
+	target_ht_irq(data->irq, dest, cfg->vector);
 	return 0;
 }
 
 #endif
 
 static struct irq_chip ht_irq_chip = {
-	.name		= "PCI-HT",
-	.irq_mask	= mask_ht_irq,
-	.irq_unmask	= unmask_ht_irq,
-	.irq_ack	= ack_apic_edge,
+	.name			= "PCI-HT",
+	.irq_mask		= mask_ht_irq,
+	.irq_unmask		= unmask_ht_irq,
+	.irq_ack		= ack_apic_edge,
 #ifdef CONFIG_SMP
-	.set_affinity	= set_ht_irq_affinity,
+	.irq_set_affinity	= ht_set_affinity,
 #endif
-	.irq_retrigger	= ioapic_retrigger_irq,
+	.irq_retrigger		= ioapic_retrigger_irq,
 };
 
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
@@ -4071,9 +4028,9 @@ void __init setup_ioapic_dest(void)
 			mask = apic->target_cpus();
 
 		if (intr_remapping_enabled)
-			set_ir_ioapic_affinity_irq_desc(desc, mask);
+			ir_ioapic_set_affinity(&desc->irq_data, mask, false);
 		else
-			set_ioapic_affinity_irq_desc(desc, mask);
+			ioapic_set_affinity(&desc->irq_data, mask, false);
 	}
 
 }
Index: linux-2.6-tip/arch/x86/kernel/uv_irq.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/uv_irq.c
+++ linux-2.6-tip/arch/x86/kernel/uv_irq.c
@@ -216,7 +216,7 @@ static int uv_set_irq_affinity(unsigned 
 	unsigned long mmr_offset;
 	int mmr_pnode;
 
-	if (set_desc_affinity(desc, mask, &dest))
+	if (__ioapic_set_affinity(&desc->irq_data, mask, &dest))
 		return -1;
 
 	mmr_value = 0;

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

* [patch 35/47] x86: ioapic: Cleanup some more
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (33 preceding siblings ...)
  2010-09-30 23:17 ` [patch 34/47] x86: ioapic: Convert irq affinity to new chip functions Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-09-30 23:17 ` [patch 36/47] x86: ioapic: Cleanup sparse irq code Thomas Gleixner
                   ` (15 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-ioapic-clenaup-some-more.patch --]
[-- Type: text/plain, Size: 2635 bytes --]

Cleanup after the irq_chip conversion a bit.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |   20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -131,13 +131,9 @@ struct irq_pin_list {
 	struct irq_pin_list *next;
 };
 
-static struct irq_pin_list *get_one_free_irq_2_pin(int node)
+static struct irq_pin_list *alloc_irq_pin_list(int node)
 {
-	struct irq_pin_list *pin;
-
-	pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node);
-
-	return pin;
+	return kzalloc_node(sizeof(struct irq_pin_list), GFP_ATOMIC, node);
 }
 
 /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
@@ -232,7 +228,7 @@ init_copy_irq_2_pin(struct irq_cfg *old_
 	if (!old_entry)
 		return;
 
-	entry = get_one_free_irq_2_pin(node);
+	entry = alloc_irq_pin_list(node);
 	if (!entry)
 		return;
 
@@ -242,7 +238,7 @@ init_copy_irq_2_pin(struct irq_cfg *old_
 	tail		= entry;
 	old_entry	= old_entry->next;
 	while (old_entry) {
-		entry = get_one_free_irq_2_pin(node);
+		entry = alloc_irq_pin_list(node);
 		if (!entry) {
 			entry = head;
 			while (entry) {
@@ -471,7 +467,7 @@ static void ioapic_mask_entry(int apic, 
  * fast in the common case, and fast for shared ISA-space IRQs.
  */
 static int
-add_pin_to_irq_node_nopanic(struct irq_cfg *cfg, int node, int apic, int pin)
+__add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin)
 {
 	struct irq_pin_list **last, *entry;
 
@@ -483,7 +479,7 @@ add_pin_to_irq_node_nopanic(struct irq_c
 		last = &entry->next;
 	}
 
-	entry = get_one_free_irq_2_pin(node);
+	entry = alloc_irq_pin_list(node);
 	if (!entry) {
 		printk(KERN_ERR "can not alloc irq_pin_list (%d,%d,%d)\n",
 				node, apic, pin);
@@ -498,7 +494,7 @@ add_pin_to_irq_node_nopanic(struct irq_c
 
 static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin)
 {
-	if (add_pin_to_irq_node_nopanic(cfg, node, apic, pin))
+	if (__add_pin_to_irq_node(cfg, node, apic, pin))
 		panic("IO-APIC: failed to add irq-pin. Can not proceed\n");
 }
 
@@ -3823,7 +3819,7 @@ static int __io_apic_set_pci_routing(str
 	 * IRQs < 16 are already in the irq_2_pin[] map
 	 */
 	if (irq >= legacy_pic->nr_legacy_irqs) {
-		if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
+		if (__add_pin_to_irq_node(cfg, node, ioapic, pin)) {
 			printk(KERN_INFO "can not add pin %d for irq %d\n",
 				pin, irq);
 			return 0;

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

* [patch 36/47] x86: ioapic: Cleanup sparse irq code
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (34 preceding siblings ...)
  2010-09-30 23:17 ` [patch 35/47] x86: ioapic: Cleanup some more Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-09-30 23:17   ` Thomas Gleixner
  2010-09-30 23:17 ` [patch 37/47] x86: uv: Clean up the direct access to irq_desc Thomas Gleixner
                   ` (14 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-ioapic-cleanup-sparse.patch --]
[-- Type: text/plain, Size: 11610 bytes --]

Switch over to the new allocator and remove all the magic which was
caused by the unability to destroy irq descriptors. Get rid of the
create_irq_nr() loop for sparse and non sparse irq.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |  297 ++++++++++++++---------------------------
 1 file changed, 105 insertions(+), 192 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -174,164 +174,102 @@ int __init arch_early_irq_init(void)
 	return 0;
 }
 
+static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node);
+
 #ifdef CONFIG_SPARSE_IRQ
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
 	return get_irq_chip_data(irq);
 }
 
-static struct irq_cfg *get_one_free_irq_cfg(int node)
+static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node)
 {
 	struct irq_cfg *cfg;
 
 	cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node);
-	if (cfg) {
-		if (!zalloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node)) {
-			kfree(cfg);
-			cfg = NULL;
-		} else if (!zalloc_cpumask_var_node(&cfg->old_domain,
-							  GFP_ATOMIC, node)) {
-			free_cpumask_var(cfg->domain);
-			kfree(cfg);
-			cfg = NULL;
-		}
-	}
-
+	if (!cfg)
+		return NULL;
+	if (!zalloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node))
+		goto out_cfg;
+	if (!zalloc_cpumask_var_node(&cfg->old_domain, GFP_ATOMIC, node))
+		goto out_domain;
 	return cfg;
-}
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
-{
-	struct irq_cfg *cfg;
-
-	cfg = get_irq_desc_chip_data(desc);
-	if (!cfg) {
-		cfg = get_one_free_irq_cfg(node);
-		set_irq_desc_chip_data(desc, cfg);
-		if (!cfg) {
-			printk(KERN_ERR "can not alloc irq_cfg\n");
-			BUG_ON(1);
-		}
-	}
-
-	return 0;
+out_domain:
+	free_cpumask_var(cfg->domain);
+out_cfg:
+	kfree(cfg);
+	return NULL;
 }
 
-/* for move_irq_desc */
-static void
-init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int node)
+static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg)
 {
-	struct irq_pin_list *old_entry, *head, *tail, *entry;
-
-	cfg->irq_2_pin = NULL;
-	old_entry = old_cfg->irq_2_pin;
-	if (!old_entry)
-		return;
-
-	entry = alloc_irq_pin_list(node);
-	if (!entry)
+	if (!cfg)
 		return;
-
-	entry->apic	= old_entry->apic;
-	entry->pin	= old_entry->pin;
-	head		= entry;
-	tail		= entry;
-	old_entry	= old_entry->next;
-	while (old_entry) {
-		entry = alloc_irq_pin_list(node);
-		if (!entry) {
-			entry = head;
-			while (entry) {
-				head = entry->next;
-				kfree(entry);
-				entry = head;
-			}
-			/* still use the old one */
-			return;
-		}
-		entry->apic	= old_entry->apic;
-		entry->pin	= old_entry->pin;
-		tail->next	= entry;
-		tail		= entry;
-		old_entry	= old_entry->next;
-	}
-
-	tail->next = NULL;
-	cfg->irq_2_pin = head;
+	set_irq_chip_data(at, NULL);
+	free_cpumask_var(cfg->domain);
+	free_cpumask_var(cfg->old_domain);
+	kfree(cfg);
 }
 
-static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
+static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
 {
-	struct irq_pin_list *entry, *next;
-
-	if (old_cfg->irq_2_pin == cfg->irq_2_pin)
-		return;
+	int res = irq_alloc_desc_at(at, node);
+	struct irq_cfg *cfg;
 
-	entry = old_cfg->irq_2_pin;
+	if (res < 0)
+		return NULL;
 
-	while (entry) {
-		next = entry->next;
-		kfree(entry);
-		entry = next;
-	}
-	old_cfg->irq_2_pin = NULL;
+	cfg = alloc_irq_cfg(at, node);
+	if (cfg)
+		set_irq_chip_data(at, cfg);
+	else
+		irq_free_desc(at);
+	return cfg;
 }
-
-void arch_init_copy_chip_data(struct irq_desc *old_desc,
-				 struct irq_desc *desc, int node)
+#else
+struct irq_cfg *irq_cfg(unsigned int irq)
 {
-	struct irq_cfg *cfg;
-	struct irq_cfg *old_cfg;
-
-	cfg = get_one_free_irq_cfg(node);
-
-	if (!cfg)
-		return;
-
-	set_irq_desc_chip_data(desc, cfg);
-
-	old_cfg = get_irq_desc_chip_data(old_desc);
-
-	cfg->vector = old_cfg->vector;
-	cfg->move_in_progress = old_cfg->move_in_progress;
-	cpumask_copy(cfg->domain, old_cfg->domain);
-	cpumask_copy(cfg->old_domain, old_cfg->old_domain);
-
-	init_copy_irq_2_pin(old_cfg, cfg, node);
+	return irq < nr_irqs ? irq_cfgx + irq : NULL;
 }
 
-static void free_irq_cfg(struct irq_cfg *cfg)
+static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node)
 {
-	free_cpumask_var(cfg->domain);
-	free_cpumask_var(cfg->old_domain);
-	kfree(cfg);
+	return irq_cfgx + irq;
 }
 
-void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+static inline void free_irq_cfg(unsigned int at, struct irq_cfg *cfg) { }
+
+static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
 {
-	struct irq_cfg *old_cfg, *cfg;
+	return get_irq_cfg_at(at, node);
+}
+#endif
 
-	old_cfg = get_irq_desc_chip_data(old_desc);
-	cfg = get_irq_desc_chip_data(desc);
+/*
+ * Allocate a new descriptor at irq number @at. If the allocation
+ * succeeds or the descriptor exists already, return the irq_cfg.
+ */
+static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node)
+{
+	int res = irq_alloc_desc_at(at, node);
 
-	if (old_cfg == cfg)
-		return;
+	if (res < 0 && res != -EEXIST)
+		return NULL;
 
-	if (old_cfg) {
-		free_irq_2_pin(old_cfg, cfg);
-		free_irq_cfg(old_cfg);
-		set_irq_desc_chip_data(old_desc, NULL);
-	}
+	return get_irq_chip_data(at);
 }
-/* end for move_irq_desc */
 
-#else
-struct irq_cfg *irq_cfg(unsigned int irq)
+static int alloc_irq_from(unsigned int from, int node)
 {
-	return irq < nr_irqs ? irq_cfgx + irq : NULL;
+	return irq_alloc_desc_from(from, node);
 }
 
-#endif
+static void free_irq_at(unsigned int at, struct irq_cfg *cfg)
+{
+	free_irq_cfg(at, cfg);
+	irq_free_desc(at);
+}
 
 struct io_apic {
 	unsigned int index;
@@ -1233,7 +1171,6 @@ void __setup_vector_irq(int cpu)
 	/* Initialize vector_irq on a new cpu */
 	int irq, vector;
 	struct irq_cfg *cfg;
-	struct irq_desc *desc;
 
 	/*
 	 * vector_lock will make sure that we don't run into irq vector
@@ -1242,9 +1179,10 @@ void __setup_vector_irq(int cpu)
 	 */
 	raw_spin_lock(&vector_lock);
 	/* Mark the inuse vectors */
-	for_each_irq_desc(irq, desc) {
-		cfg = get_irq_desc_chip_data(desc);
-
+	for_each_irq_nr(irq) {
+		cfg = get_irq_chip_data(irq);
+		if (!cfg)
+			continue;
 		/*
 		 * If it is a legacy IRQ handled by the legacy PIC, this cpu
 		 * will be part of the irq_cfg's domain.
@@ -1454,11 +1392,9 @@ static struct {
 
 static void __init setup_IO_APIC_irqs(void)
 {
-	int apic_id, pin, idx, irq;
-	int notcon = 0;
-	struct irq_desc *desc;
-	struct irq_cfg *cfg;
+	int apic_id, pin, idx, irq, notcon = 0;
 	int node = cpu_to_node(boot_cpu_id);
+	struct irq_cfg *cfg;
 
 	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
@@ -1495,12 +1431,10 @@ static void __init setup_IO_APIC_irqs(vo
 				apic->multi_timer_check(apic_id, irq))
 			continue;
 
-		desc = irq_to_desc_alloc_node(irq, node);
-		if (!desc) {
-			printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+		cfg = get_irq_cfg_at(irq, node);
+		if (!cfg)
 			continue;
-		}
-		cfg = get_irq_desc_chip_data(desc);
+
 		add_pin_to_irq_node(cfg, node, apic_id, pin);
 		/*
 		 * don't mark it in pin_programmed, so later acpi could
@@ -1522,9 +1456,7 @@ static void __init setup_IO_APIC_irqs(vo
  */
 void setup_IO_APIC_irq_extra(u32 gsi)
 {
-	int apic_id = 0, pin, idx, irq;
-	int node = cpu_to_node(boot_cpu_id);
-	struct irq_desc *desc;
+	int apic_id = 0, pin, idx, irq, node = cpu_to_node(boot_cpu_id);
 	struct irq_cfg *cfg;
 
 	/*
@@ -1540,18 +1472,11 @@ void setup_IO_APIC_irq_extra(u32 gsi)
 		return;
 
 	irq = pin_2_irq(idx, apic_id, pin);
-#ifdef CONFIG_SPARSE_IRQ
-	desc = irq_to_desc(irq);
-	if (desc)
-		return;
-#endif
-	desc = irq_to_desc_alloc_node(irq, node);
-	if (!desc) {
-		printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+
+	cfg = alloc_irq_and_cfg_at(irq, node);
+	if (!cfg)
 		return;
-	}
 
-	cfg = get_irq_desc_chip_data(desc);
 	add_pin_to_irq_node(cfg, node, apic_id, pin);
 
 	if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
@@ -3153,44 +3078,37 @@ device_initcall(ioapic_init_sysfs);
 /*
  * Dynamic irq allocate and deallocation
  */
-unsigned int create_irq_nr(unsigned int irq_want, int node)
+unsigned int create_irq_nr(unsigned int from, int node)
 {
-	/* Allocate an unused irq */
-	unsigned int irq;
-	unsigned int new;
+	struct irq_cfg *cfg;
 	unsigned long flags;
-	struct irq_cfg *cfg_new = NULL;
-	struct irq_desc *desc_new = NULL;
-
-	irq = 0;
-	if (irq_want < nr_irqs_gsi)
-		irq_want = nr_irqs_gsi;
-
-	raw_spin_lock_irqsave(&vector_lock, flags);
-	for (new = irq_want; new < nr_irqs; new++) {
-		desc_new = irq_to_desc_alloc_node(new, node);
-		if (!desc_new) {
-			printk(KERN_INFO "can not get irq_desc for %d\n", new);
-			continue;
-		}
-		cfg_new = get_irq_desc_chip_data(desc_new);
-
-		if (cfg_new->vector != 0)
-			continue;
+	unsigned int ret = 0;
+	int irq;
 
-		desc_new = move_irq_desc(desc_new, node);
-		cfg_new = get_irq_desc_chip_data(desc_new);
+	if (from < nr_irqs_gsi)
+		from = nr_irqs_gsi;
 
-		if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
-			irq = new;
-		break;
+	irq = alloc_irq_from(from, node);
+	if (irq < 0)
+		return 0;
+	cfg = alloc_irq_cfg(irq, node);
+	if (!cfg) {
+		free_irq_at(irq, NULL);
+		return 0;
 	}
-	raw_spin_unlock_irqrestore(&vector_lock, flags);
 
-	if (irq > 0)
-		dynamic_irq_init_keep_chip_data(irq);
+	raw_spin_lock_irqsave(&vector_lock, flags);
+	if (!__assign_irq_vector(irq, cfg, apic->target_cpus()))
+		ret = irq;
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
 
-	return irq;
+	if (ret) {
+		set_irq_chip_data(irq, cfg);
+		irq_clear_status_flags(irq, IRQ_NOREQUEST);
+	} else {
+		free_irq_at(irq, cfg);
+	}
+	return ret;
 }
 
 int create_irq(void)
@@ -3210,14 +3128,16 @@ int create_irq(void)
 
 void destroy_irq(unsigned int irq)
 {
+	struct irq_cfg *cfg = get_irq_chip_data(irq);
 	unsigned long flags;
 
-	dynamic_irq_cleanup_keep_chip_data(irq);
+	irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE);
 
 	free_irte(irq);
 	raw_spin_lock_irqsave(&vector_lock, flags);
-	__clear_irq_vector(irq, get_irq_chip_data(irq));
+	__clear_irq_vector(irq, cfg);
 	raw_spin_unlock_irqrestore(&vector_lock, flags);
+	free_irq_at(irq, cfg);
 }
 
 /*
@@ -3785,11 +3705,8 @@ int __init arch_probe_nr_irqs(void)
 static int __io_apic_set_pci_routing(struct device *dev, int irq,
 				struct io_apic_irq_attr *irq_attr)
 {
-	struct irq_desc *desc;
+	int node, ioapic, pin, trigger, polarity;
 	struct irq_cfg *cfg;
-	int node;
-	int ioapic, pin;
-	int trigger, polarity;
 
 	ioapic = irq_attr->ioapic;
 	if (!IO_APIC_IRQ(irq)) {
@@ -3803,18 +3720,14 @@ static int __io_apic_set_pci_routing(str
 	else
 		node = cpu_to_node(boot_cpu_id);
 
-	desc = irq_to_desc_alloc_node(irq, node);
-	if (!desc) {
-		printk(KERN_INFO "can not get irq_desc %d\n", irq);
+	cfg = get_irq_cfg_at(irq, node);
+	if (!cfg)
 		return 0;
-	}
 
 	pin = irq_attr->ioapic_pin;
 	trigger = irq_attr->trigger;
 	polarity = irq_attr->polarity;
 
-	cfg = get_irq_desc_chip_data(desc);
-
 	/*
 	 * IRQs < 16 are already in the irq_2_pin[] map
 	 */
@@ -4215,11 +4128,11 @@ void __init pre_init_apic_IRQ0(void)
 #ifndef CONFIG_SMP
 	phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
 #endif
-	irq_to_desc_alloc_node(0, 0);
+	/* Make sure the irq descriptor is set up */
+	cfg = get_irq_cfg_at(0, 0);
 
 	setup_local_APIC();
 
-	cfg = irq_cfg(0);
 	add_pin_to_irq_node(cfg, 0, 0, 0);
 	set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
 

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

* [patch 36/47] x86: ioapic: Cleanup sparse irq code
  2010-09-30 23:17 ` [patch 36/47] x86: ioapic: Cleanup sparse irq code Thomas Gleixner
@ 2010-09-30 23:17   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-ioapic-cleanup-sparse.patch --]
[-- Type: text/plain, Size: 11612 bytes --]

Switch over to the new allocator and remove all the magic which was
caused by the unability to destroy irq descriptors. Get rid of the
create_irq_nr() loop for sparse and non sparse irq.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |  297 ++++++++++++++---------------------------
 1 file changed, 105 insertions(+), 192 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -174,164 +174,102 @@ int __init arch_early_irq_init(void)
 	return 0;
 }
 
+static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node);
+
 #ifdef CONFIG_SPARSE_IRQ
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
 	return get_irq_chip_data(irq);
 }
 
-static struct irq_cfg *get_one_free_irq_cfg(int node)
+static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node)
 {
 	struct irq_cfg *cfg;
 
 	cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node);
-	if (cfg) {
-		if (!zalloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node)) {
-			kfree(cfg);
-			cfg = NULL;
-		} else if (!zalloc_cpumask_var_node(&cfg->old_domain,
-							  GFP_ATOMIC, node)) {
-			free_cpumask_var(cfg->domain);
-			kfree(cfg);
-			cfg = NULL;
-		}
-	}
-
+	if (!cfg)
+		return NULL;
+	if (!zalloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node))
+		goto out_cfg;
+	if (!zalloc_cpumask_var_node(&cfg->old_domain, GFP_ATOMIC, node))
+		goto out_domain;
 	return cfg;
-}
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
-{
-	struct irq_cfg *cfg;
-
-	cfg = get_irq_desc_chip_data(desc);
-	if (!cfg) {
-		cfg = get_one_free_irq_cfg(node);
-		set_irq_desc_chip_data(desc, cfg);
-		if (!cfg) {
-			printk(KERN_ERR "can not alloc irq_cfg\n");
-			BUG_ON(1);
-		}
-	}
-
-	return 0;
+out_domain:
+	free_cpumask_var(cfg->domain);
+out_cfg:
+	kfree(cfg);
+	return NULL;
 }
 
-/* for move_irq_desc */
-static void
-init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int node)
+static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg)
 {
-	struct irq_pin_list *old_entry, *head, *tail, *entry;
-
-	cfg->irq_2_pin = NULL;
-	old_entry = old_cfg->irq_2_pin;
-	if (!old_entry)
-		return;
-
-	entry = alloc_irq_pin_list(node);
-	if (!entry)
+	if (!cfg)
 		return;
-
-	entry->apic	= old_entry->apic;
-	entry->pin	= old_entry->pin;
-	head		= entry;
-	tail		= entry;
-	old_entry	= old_entry->next;
-	while (old_entry) {
-		entry = alloc_irq_pin_list(node);
-		if (!entry) {
-			entry = head;
-			while (entry) {
-				head = entry->next;
-				kfree(entry);
-				entry = head;
-			}
-			/* still use the old one */
-			return;
-		}
-		entry->apic	= old_entry->apic;
-		entry->pin	= old_entry->pin;
-		tail->next	= entry;
-		tail		= entry;
-		old_entry	= old_entry->next;
-	}
-
-	tail->next = NULL;
-	cfg->irq_2_pin = head;
+	set_irq_chip_data(at, NULL);
+	free_cpumask_var(cfg->domain);
+	free_cpumask_var(cfg->old_domain);
+	kfree(cfg);
 }
 
-static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
+static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
 {
-	struct irq_pin_list *entry, *next;
-
-	if (old_cfg->irq_2_pin == cfg->irq_2_pin)
-		return;
+	int res = irq_alloc_desc_at(at, node);
+	struct irq_cfg *cfg;
 
-	entry = old_cfg->irq_2_pin;
+	if (res < 0)
+		return NULL;
 
-	while (entry) {
-		next = entry->next;
-		kfree(entry);
-		entry = next;
-	}
-	old_cfg->irq_2_pin = NULL;
+	cfg = alloc_irq_cfg(at, node);
+	if (cfg)
+		set_irq_chip_data(at, cfg);
+	else
+		irq_free_desc(at);
+	return cfg;
 }
-
-void arch_init_copy_chip_data(struct irq_desc *old_desc,
-				 struct irq_desc *desc, int node)
+#else
+struct irq_cfg *irq_cfg(unsigned int irq)
 {
-	struct irq_cfg *cfg;
-	struct irq_cfg *old_cfg;
-
-	cfg = get_one_free_irq_cfg(node);
-
-	if (!cfg)
-		return;
-
-	set_irq_desc_chip_data(desc, cfg);
-
-	old_cfg = get_irq_desc_chip_data(old_desc);
-
-	cfg->vector = old_cfg->vector;
-	cfg->move_in_progress = old_cfg->move_in_progress;
-	cpumask_copy(cfg->domain, old_cfg->domain);
-	cpumask_copy(cfg->old_domain, old_cfg->old_domain);
-
-	init_copy_irq_2_pin(old_cfg, cfg, node);
+	return irq < nr_irqs ? irq_cfgx + irq : NULL;
 }
 
-static void free_irq_cfg(struct irq_cfg *cfg)
+static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node)
 {
-	free_cpumask_var(cfg->domain);
-	free_cpumask_var(cfg->old_domain);
-	kfree(cfg);
+	return irq_cfgx + irq;
 }
 
-void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+static inline void free_irq_cfg(unsigned int at, struct irq_cfg *cfg) { }
+
+static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
 {
-	struct irq_cfg *old_cfg, *cfg;
+	return get_irq_cfg_at(at, node);
+}
+#endif
 
-	old_cfg = get_irq_desc_chip_data(old_desc);
-	cfg = get_irq_desc_chip_data(desc);
+/*
+ * Allocate a new descriptor at irq number @at. If the allocation
+ * succeeds or the descriptor exists already, return the irq_cfg.
+ */
+static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node)
+{
+	int res = irq_alloc_desc_at(at, node);
 
-	if (old_cfg == cfg)
-		return;
+	if (res < 0 && res != -EEXIST)
+		return NULL;
 
-	if (old_cfg) {
-		free_irq_2_pin(old_cfg, cfg);
-		free_irq_cfg(old_cfg);
-		set_irq_desc_chip_data(old_desc, NULL);
-	}
+	return get_irq_chip_data(at);
 }
-/* end for move_irq_desc */
 
-#else
-struct irq_cfg *irq_cfg(unsigned int irq)
+static int alloc_irq_from(unsigned int from, int node)
 {
-	return irq < nr_irqs ? irq_cfgx + irq : NULL;
+	return irq_alloc_desc_from(from, node);
 }
 
-#endif
+static void free_irq_at(unsigned int at, struct irq_cfg *cfg)
+{
+	free_irq_cfg(at, cfg);
+	irq_free_desc(at);
+}
 
 struct io_apic {
 	unsigned int index;
@@ -1233,7 +1171,6 @@ void __setup_vector_irq(int cpu)
 	/* Initialize vector_irq on a new cpu */
 	int irq, vector;
 	struct irq_cfg *cfg;
-	struct irq_desc *desc;
 
 	/*
 	 * vector_lock will make sure that we don't run into irq vector
@@ -1242,9 +1179,10 @@ void __setup_vector_irq(int cpu)
 	 */
 	raw_spin_lock(&vector_lock);
 	/* Mark the inuse vectors */
-	for_each_irq_desc(irq, desc) {
-		cfg = get_irq_desc_chip_data(desc);
-
+	for_each_irq_nr(irq) {
+		cfg = get_irq_chip_data(irq);
+		if (!cfg)
+			continue;
 		/*
 		 * If it is a legacy IRQ handled by the legacy PIC, this cpu
 		 * will be part of the irq_cfg's domain.
@@ -1454,11 +1392,9 @@ static struct {
 
 static void __init setup_IO_APIC_irqs(void)
 {
-	int apic_id, pin, idx, irq;
-	int notcon = 0;
-	struct irq_desc *desc;
-	struct irq_cfg *cfg;
+	int apic_id, pin, idx, irq, notcon = 0;
 	int node = cpu_to_node(boot_cpu_id);
+	struct irq_cfg *cfg;
 
 	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
@@ -1495,12 +1431,10 @@ static void __init setup_IO_APIC_irqs(vo
 				apic->multi_timer_check(apic_id, irq))
 			continue;
 
-		desc = irq_to_desc_alloc_node(irq, node);
-		if (!desc) {
-			printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+		cfg = get_irq_cfg_at(irq, node);
+		if (!cfg)
 			continue;
-		}
-		cfg = get_irq_desc_chip_data(desc);
+
 		add_pin_to_irq_node(cfg, node, apic_id, pin);
 		/*
 		 * don't mark it in pin_programmed, so later acpi could
@@ -1522,9 +1456,7 @@ static void __init setup_IO_APIC_irqs(vo
  */
 void setup_IO_APIC_irq_extra(u32 gsi)
 {
-	int apic_id = 0, pin, idx, irq;
-	int node = cpu_to_node(boot_cpu_id);
-	struct irq_desc *desc;
+	int apic_id = 0, pin, idx, irq, node = cpu_to_node(boot_cpu_id);
 	struct irq_cfg *cfg;
 
 	/*
@@ -1540,18 +1472,11 @@ void setup_IO_APIC_irq_extra(u32 gsi)
 		return;
 
 	irq = pin_2_irq(idx, apic_id, pin);
-#ifdef CONFIG_SPARSE_IRQ
-	desc = irq_to_desc(irq);
-	if (desc)
-		return;
-#endif
-	desc = irq_to_desc_alloc_node(irq, node);
-	if (!desc) {
-		printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+
+	cfg = alloc_irq_and_cfg_at(irq, node);
+	if (!cfg)
 		return;
-	}
 
-	cfg = get_irq_desc_chip_data(desc);
 	add_pin_to_irq_node(cfg, node, apic_id, pin);
 
 	if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
@@ -3153,44 +3078,37 @@ device_initcall(ioapic_init_sysfs);
 /*
  * Dynamic irq allocate and deallocation
  */
-unsigned int create_irq_nr(unsigned int irq_want, int node)
+unsigned int create_irq_nr(unsigned int from, int node)
 {
-	/* Allocate an unused irq */
-	unsigned int irq;
-	unsigned int new;
+	struct irq_cfg *cfg;
 	unsigned long flags;
-	struct irq_cfg *cfg_new = NULL;
-	struct irq_desc *desc_new = NULL;
-
-	irq = 0;
-	if (irq_want < nr_irqs_gsi)
-		irq_want = nr_irqs_gsi;
-
-	raw_spin_lock_irqsave(&vector_lock, flags);
-	for (new = irq_want; new < nr_irqs; new++) {
-		desc_new = irq_to_desc_alloc_node(new, node);
-		if (!desc_new) {
-			printk(KERN_INFO "can not get irq_desc for %d\n", new);
-			continue;
-		}
-		cfg_new = get_irq_desc_chip_data(desc_new);
-
-		if (cfg_new->vector != 0)
-			continue;
+	unsigned int ret = 0;
+	int irq;
 
-		desc_new = move_irq_desc(desc_new, node);
-		cfg_new = get_irq_desc_chip_data(desc_new);
+	if (from < nr_irqs_gsi)
+		from = nr_irqs_gsi;
 
-		if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
-			irq = new;
-		break;
+	irq = alloc_irq_from(from, node);
+	if (irq < 0)
+		return 0;
+	cfg = alloc_irq_cfg(irq, node);
+	if (!cfg) {
+		free_irq_at(irq, NULL);
+		return 0;
 	}
-	raw_spin_unlock_irqrestore(&vector_lock, flags);
 
-	if (irq > 0)
-		dynamic_irq_init_keep_chip_data(irq);
+	raw_spin_lock_irqsave(&vector_lock, flags);
+	if (!__assign_irq_vector(irq, cfg, apic->target_cpus()))
+		ret = irq;
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
 
-	return irq;
+	if (ret) {
+		set_irq_chip_data(irq, cfg);
+		irq_clear_status_flags(irq, IRQ_NOREQUEST);
+	} else {
+		free_irq_at(irq, cfg);
+	}
+	return ret;
 }
 
 int create_irq(void)
@@ -3210,14 +3128,16 @@ int create_irq(void)
 
 void destroy_irq(unsigned int irq)
 {
+	struct irq_cfg *cfg = get_irq_chip_data(irq);
 	unsigned long flags;
 
-	dynamic_irq_cleanup_keep_chip_data(irq);
+	irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE);
 
 	free_irte(irq);
 	raw_spin_lock_irqsave(&vector_lock, flags);
-	__clear_irq_vector(irq, get_irq_chip_data(irq));
+	__clear_irq_vector(irq, cfg);
 	raw_spin_unlock_irqrestore(&vector_lock, flags);
+	free_irq_at(irq, cfg);
 }
 
 /*
@@ -3785,11 +3705,8 @@ int __init arch_probe_nr_irqs(void)
 static int __io_apic_set_pci_routing(struct device *dev, int irq,
 				struct io_apic_irq_attr *irq_attr)
 {
-	struct irq_desc *desc;
+	int node, ioapic, pin, trigger, polarity;
 	struct irq_cfg *cfg;
-	int node;
-	int ioapic, pin;
-	int trigger, polarity;
 
 	ioapic = irq_attr->ioapic;
 	if (!IO_APIC_IRQ(irq)) {
@@ -3803,18 +3720,14 @@ static int __io_apic_set_pci_routing(str
 	else
 		node = cpu_to_node(boot_cpu_id);
 
-	desc = irq_to_desc_alloc_node(irq, node);
-	if (!desc) {
-		printk(KERN_INFO "can not get irq_desc %d\n", irq);
+	cfg = get_irq_cfg_at(irq, node);
+	if (!cfg)
 		return 0;
-	}
 
 	pin = irq_attr->ioapic_pin;
 	trigger = irq_attr->trigger;
 	polarity = irq_attr->polarity;
 
-	cfg = get_irq_desc_chip_data(desc);
-
 	/*
 	 * IRQs < 16 are already in the irq_2_pin[] map
 	 */
@@ -4215,11 +4128,11 @@ void __init pre_init_apic_IRQ0(void)
 #ifndef CONFIG_SMP
 	phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
 #endif
-	irq_to_desc_alloc_node(0, 0);
+	/* Make sure the irq descriptor is set up */
+	cfg = get_irq_cfg_at(0, 0);
 
 	setup_local_APIC();
 
-	cfg = irq_cfg(0);
 	add_pin_to_irq_node(cfg, 0, 0, 0);
 	set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
 



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

* [patch 37/47] x86: uv: Clean up the direct access to irq_desc
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (35 preceding siblings ...)
  2010-09-30 23:17 ` [patch 36/47] x86: ioapic: Cleanup sparse irq code Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-09-30 23:17 ` [patch 38/47] x86: Use sane enumeration Thomas Gleixner
                   ` (13 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-uv-cleanup-irq-desc-mess.patch --]
[-- Type: text/plain, Size: 4469 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/hw_irq.h  |    1 
 arch/x86/kernel/apic/io_apic.c |    2 -
 arch/x86/kernel/uv_irq.c       |   55 ++++++++++++++---------------------------
 3 files changed, 20 insertions(+), 38 deletions(-)

Index: linux-2.6-tip/arch/x86/include/asm/hw_irq.h
===================================================================
--- linux-2.6-tip.orig/arch/x86/include/asm/hw_irq.h
+++ linux-2.6-tip/arch/x86/include/asm/hw_irq.h
@@ -91,7 +91,6 @@ struct irq_cfg {
 	u8			move_in_progress : 1;
 };
 
-extern struct irq_cfg *irq_cfg(unsigned int);
 extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
 extern void send_cleanup_vector(struct irq_cfg *);
 
Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -177,7 +177,7 @@ int __init arch_early_irq_init(void)
 static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node);
 
 #ifdef CONFIG_SPARSE_IRQ
-struct irq_cfg *irq_cfg(unsigned int irq)
+static struct irq_cfg *irq_cfg(unsigned int irq)
 {
 	return get_irq_chip_data(irq);
 }
Index: linux-2.6-tip/arch/x86/kernel/uv_irq.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/uv_irq.c
+++ linux-2.6-tip/arch/x86/kernel/uv_irq.c
@@ -28,34 +28,21 @@ struct uv_irq_2_mmr_pnode{
 static spinlock_t		uv_irq_lock;
 static struct rb_root		uv_irq_root;
 
-static int uv_set_irq_affinity(unsigned int, const struct cpumask *);
+static int uv_set_irq_affinity(struct irq_data *, const struct cpumask *, bool);
 
-static void uv_noop(unsigned int irq)
-{
-}
-
-static unsigned int uv_noop_ret(unsigned int irq)
-{
-	return 0;
-}
+static void uv_noop(struct irq_data *data) { }
 
-static void uv_ack_apic(unsigned int irq)
+static void uv_ack_apic(struct irq_data *data)
 {
 	ack_APIC_irq();
 }
 
 static struct irq_chip uv_irq_chip = {
-	.name		= "UV-CORE",
-	.startup	= uv_noop_ret,
-	.shutdown	= uv_noop,
-	.enable		= uv_noop,
-	.disable	= uv_noop,
-	.ack		= uv_noop,
-	.mask		= uv_noop,
-	.unmask		= uv_noop,
-	.eoi		= uv_ack_apic,
-	.end		= uv_noop,
-	.set_affinity	= uv_set_irq_affinity,
+	.name			= "UV-CORE",
+	.irq_mask		= uv_noop,
+	.irq_unmask		= uv_noop,
+	.irq_eoi		= uv_ack_apic,
+	.irq_set_affinity	= uv_set_irq_affinity,
 };
 
 /*
@@ -144,26 +131,22 @@ arch_enable_uv_irq(char *irq_name, unsig
 		       unsigned long mmr_offset, int limit)
 {
 	const struct cpumask *eligible_cpu = cpumask_of(cpu);
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
-	int mmr_pnode;
+	struct irq_cfg *cfg = get_irq_chip_data(irq);
 	unsigned long mmr_value;
 	struct uv_IO_APIC_route_entry *entry;
-	int err;
+	int mmr_pnode, err;
 
 	BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) !=
 			sizeof(unsigned long));
 
-	cfg = irq_cfg(irq);
-
 	err = assign_irq_vector(irq, cfg, eligible_cpu);
 	if (err != 0)
 		return err;
 
 	if (limit == UV_AFFINITY_CPU)
-		desc->status |= IRQ_NO_BALANCING;
+		irq_set_status_flags(irq, IRQ_NO_BALANCING);
 	else
-		desc->status |= IRQ_MOVE_PCNTXT;
+		irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
 
 	set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
 				      irq_name);
@@ -206,17 +189,17 @@ static void arch_disable_uv_irq(int mmr_
 	uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
 }
 
-static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask,
+		    bool force)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg = get_irq_desc_chip_data(desc);
+	struct irq_cfg *cfg = data->chip_data;
 	unsigned int dest;
-	unsigned long mmr_value;
+	unsigned long mmr_value, mmr_offset;
 	struct uv_IO_APIC_route_entry *entry;
-	unsigned long mmr_offset;
 	int mmr_pnode;
 
-	if (__ioapic_set_affinity(&desc->irq_data, mask, &dest))
+	if (__ioapic_set_affinity(data, mask, &dest))
 		return -1;
 
 	mmr_value = 0;
@@ -231,7 +214,7 @@ static int uv_set_irq_affinity(unsigned 
 	entry->dest		= dest;
 
 	/* Get previously stored MMR and pnode of hub sourcing interrupts */
-	if (uv_irq_2_mmr_info(irq, &mmr_offset, &mmr_pnode))
+	if (uv_irq_2_mmr_info(data->irq, &mmr_offset, &mmr_pnode))
 		return -1;
 
 	uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);

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

* [patch 38/47] x86: Use sane enumeration
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (36 preceding siblings ...)
  2010-09-30 23:17 ` [patch 37/47] x86: uv: Clean up the direct access to irq_desc Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-09-30 23:17 ` [patch 39/47] genirq: Remove arch_init_chip_data() Thomas Gleixner
                   ` (12 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-use-sane-enumeration.patch --]
[-- Type: text/plain, Size: 2195 bytes --]

Instead of looping through all interrupts, use the bitmap lookup to
find the next.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

Index: linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6-tip/arch/x86/kernel/apic/io_apic.c
@@ -1179,7 +1179,7 @@ void __setup_vector_irq(int cpu)
 	 */
 	raw_spin_lock(&vector_lock);
 	/* Mark the inuse vectors */
-	for_each_irq_nr(irq) {
+	for_each_active_irq(irq) {
 		cfg = get_irq_chip_data(irq);
 		if (!cfg)
 			continue;
@@ -1537,7 +1537,6 @@ __apicdebuginit(void) print_IO_APIC(void
 	union IO_APIC_reg_03 reg_03;
 	unsigned long flags;
 	struct irq_cfg *cfg;
-	struct irq_desc *desc;
 	unsigned int irq;
 
 	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
@@ -1624,10 +1623,10 @@ __apicdebuginit(void) print_IO_APIC(void
 	}
 	}
 	printk(KERN_DEBUG "IRQ to pin mappings:\n");
-	for_each_irq_desc(irq, desc) {
+	for_each_active_irq(irq) {
 		struct irq_pin_list *entry;
 
-		cfg = get_irq_desc_chip_data(desc);
+		cfg = get_irq_chip_data(irq);
 		if (!cfg)
 			continue;
 		entry = cfg->irq_2_pin;
@@ -2596,9 +2595,8 @@ static struct irq_chip ir_ioapic_chip __
 
 static inline void init_IO_APIC_traps(void)
 {
-	int irq;
-	struct irq_desc *desc;
 	struct irq_cfg *cfg;
+	unsigned int irq;
 
 	/*
 	 * NOTE! The local APIC isn't very good at handling
@@ -2611,8 +2609,8 @@ static inline void init_IO_APIC_traps(vo
 	 * Also, we've got to be careful not to trash gate
 	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
 	 */
-	for_each_irq_desc(irq, desc) {
-		cfg = get_irq_desc_chip_data(desc);
+	for_each_active_irq(irq) {
+		cfg = get_irq_chip_data(irq);
 		if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) {
 			/*
 			 * Hmm.. We don't have an entry for this,
@@ -2623,7 +2621,7 @@ static inline void init_IO_APIC_traps(vo
 				legacy_pic->make_irq(irq);
 			else
 				/* Strange. Oh, well.. */
-				desc->chip = &no_irq_chip;
+				set_irq_chip(irq, &no_irq_chip);
 		}
 	}
 }

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

* [patch 39/47] genirq: Remove arch_init_chip_data()
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (37 preceding siblings ...)
  2010-09-30 23:17 ` [patch 38/47] x86: Use sane enumeration Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-09-30 23:17 ` [patch 40/47] genirq: Sanitize dynamic irq handling Thomas Gleixner
                   ` (11 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-remove-arch_init_chip_data.patch --]
[-- Type: text/plain, Size: 1705 bytes --]

This function should have not been there in the first place.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/interrupt.h |    3 ---
 kernel/irq/irqdesc.c      |    2 --
 kernel/softirq.c          |    5 -----
 3 files changed, 10 deletions(-)

Index: linux-2.6-tip/include/linux/interrupt.h
===================================================================
--- linux-2.6-tip.orig/include/linux/interrupt.h
+++ linux-2.6-tip/include/linux/interrupt.h
@@ -641,11 +641,8 @@ static inline void init_irq_proc(void)
 struct seq_file;
 int show_interrupts(struct seq_file *p, void *v);
 
-struct irq_desc;
-
 extern int early_irq_init(void);
 extern int arch_probe_nr_irqs(void);
 extern int arch_early_irq_init(void);
-extern int arch_init_chip_data(struct irq_desc *desc, int node);
 
 #endif
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -196,8 +196,6 @@ static int alloc_descs(unsigned int star
 		desc = alloc_desc(start + i, node);
 		if (!desc)
 			goto err;
-		/* temporary until I fixed x86 madness */
-		arch_init_chip_data(desc, node);
 		raw_spin_lock_irqsave(&sparse_irq_lock, flags);
 		irq_insert_desc(start + i, desc);
 		raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
Index: linux-2.6-tip/kernel/softirq.c
===================================================================
--- linux-2.6-tip.orig/kernel/softirq.c
+++ linux-2.6-tip/kernel/softirq.c
@@ -895,8 +895,3 @@ int __init __weak arch_early_irq_init(vo
 {
 	return 0;
 }
-
-int __weak arch_init_chip_data(struct irq_desc *desc, int node)
-{
-	return 0;
-}

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

* [patch 40/47] genirq: Sanitize dynamic irq handling
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (38 preceding siblings ...)
  2010-09-30 23:17 ` [patch 39/47] genirq: Remove arch_init_chip_data() Thomas Gleixner
@ 2010-09-30 23:17 ` Thomas Gleixner
  2010-09-30 23:17   ` Thomas Gleixner
  2010-10-01  5:47   ` Yinghai Lu
  2010-09-30 23:18 ` [patch 41/47] arm: davinci: Cleanup irq_desc access Thomas Gleixner
                   ` (10 subsequent siblings)
  50 siblings, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: generiq-sanitize-dynamic-irq-handling.patch --]
[-- Type: text/plain, Size: 7110 bytes --]

Use the cleanup functions of the dynamic allocator. No need to have
separate implementations.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h    |   12 +++--
 kernel/irq/chip.c      |  104 -------------------------------------------------
 kernel/irq/internals.h |    1 
 kernel/irq/irqdesc.c   |   37 +++++++++++------
 4 files changed, 33 insertions(+), 121 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -497,11 +497,15 @@ static inline int irq_has_action(unsigne
 	return desc->action != NULL;
 }
 
-/* Dynamic irq helper functions */
-extern void dynamic_irq_init(unsigned int irq);
-void dynamic_irq_init_keep_chip_data(unsigned int irq);
+/*
+ * Dynamic irq helper functions. Obsolete. Use irq_alloc_desc* and
+ * irq_free_desc instead.
+ */
 extern void dynamic_irq_cleanup(unsigned int irq);
-void dynamic_irq_cleanup_keep_chip_data(unsigned int irq);
+static inline void dynamic_irq_init(unsigned int irq)
+{
+	dynamic_irq_cleanup(irq);
+}
 
 /* Set/get chip/data for an IRQ: */
 extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -18,110 +18,6 @@
 
 #include "internals.h"
 
-static void dynamic_irq_init_x(unsigned int irq, bool keep_chip_data)
-{
-	struct irq_desc *desc;
-	unsigned long flags;
-
-	desc = irq_to_desc(irq);
-	if (!desc) {
-		WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
-		return;
-	}
-
-	/* Ensure we don't have left over values from a previous use of this irq */
-	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status = IRQ_DEFAULT_INIT_FLAGS;
-	desc->chip = &no_irq_chip;
-	desc->irq_data.chip = &no_irq_chip;
-	desc->handle_irq = handle_bad_irq;
-	desc->depth = 1;
-	desc->irq_data.msi_desc = NULL;
-	desc->irq_data.handler_data = NULL;
-	if (!keep_chip_data)
-		desc->irq_data.chip_data = NULL;
-	desc->action = NULL;
-	desc->irq_count = 0;
-	desc->irqs_unhandled = 0;
-#ifdef CONFIG_SMP
-	cpumask_setall(desc->affinity);
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	cpumask_clear(desc->pending_mask);
-#endif
-#endif
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/**
- *	dynamic_irq_init - initialize a dynamically allocated irq
- *	@irq:	irq number to initialize
- */
-void dynamic_irq_init(unsigned int irq)
-{
-	dynamic_irq_init_x(irq, false);
-}
-
-/**
- *	dynamic_irq_init_keep_chip_data - initialize a dynamically allocated irq
- *	@irq:	irq number to initialize
- *
- *	does not set irq_to_desc(irq)->chip_data to NULL
- */
-void dynamic_irq_init_keep_chip_data(unsigned int irq)
-{
-	dynamic_irq_init_x(irq, true);
-}
-
-static void dynamic_irq_cleanup_x(unsigned int irq, bool keep_chip_data)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	unsigned long flags;
-
-	if (!desc) {
-		WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
-		return;
-	}
-
-	raw_spin_lock_irqsave(&desc->lock, flags);
-	if (desc->action) {
-		raw_spin_unlock_irqrestore(&desc->lock, flags);
-		WARN(1, KERN_ERR "Destroying IRQ%d without calling free_irq\n",
-			irq);
-		return;
-	}
-	desc->irq_data.msi_desc = NULL;
-	desc->irq_data.handler_data = NULL;
-	if (!keep_chip_data)
-		desc->irq_data.chip_data = NULL;
-	desc->handle_irq = handle_bad_irq;
-	desc->chip = &no_irq_chip;
-	desc->irq_data.chip = &no_irq_chip;
-	desc->name = NULL;
-	clear_kstat_irqs(desc);
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/**
- *	dynamic_irq_cleanup - cleanup a dynamically allocated irq
- *	@irq:	irq number to initialize
- */
-void dynamic_irq_cleanup(unsigned int irq)
-{
-	dynamic_irq_cleanup_x(irq, false);
-}
-
-/**
- *	dynamic_irq_cleanup_keep_chip_data - cleanup a dynamically allocated irq
- *	@irq:	irq number to initialize
- *
- *	does not set irq_to_desc(irq)->chip_data to NULL
- */
-void dynamic_irq_cleanup_keep_chip_data(unsigned int irq)
-{
-	dynamic_irq_cleanup_x(irq, true);
-}
-
-
 /**
  *	set_irq_chip - set the irq chip for an irq
  *	@irq:	irq number
Index: linux-2.6-tip/kernel/irq/internals.h
===================================================================
--- linux-2.6-tip.orig/kernel/irq/internals.h
+++ linux-2.6-tip/kernel/irq/internals.h
@@ -17,7 +17,6 @@ extern void __enable_irq(struct irq_desc
 
 extern struct lock_class_key irq_desc_lock_class;
 extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
-extern void clear_kstat_irqs(struct irq_desc *desc);
 extern raw_spinlock_t sparse_irq_lock;
 
 #ifdef CONFIG_SPARSE_IRQ
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -54,10 +54,13 @@ static void desc_smp_init(struct irq_des
 	desc->node = node;
 	desc->irq_data.affinity = &desc->affinity;
 	cpumask_copy(desc->affinity, irq_default_affinity);
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	cpumask_clear(desc->pending_mask);
+#endif
 }
-
+static inline int desc_node(struct irq_desc *desc) { return desc->node; }
 #else
-static inline int
+static inline int desc_node(struct irq_desc *desc) { return 0; }
 alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
 static inline void desc_smp_init(struct irq_desc *desc, int node) { }
 #endif
@@ -72,6 +75,8 @@ static void desc_set_defaults(unsigned i
 	desc->irq_data.chip = &no_irq_chip;
 	desc->handle_irq = handle_bad_irq;
 	desc->depth = 1;
+	desc->irq_count = 0;
+	desc->irqs_unhandled = 0;
 	desc->name = NULL;
 	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
 	desc_smp_init(desc, node);
@@ -136,6 +141,7 @@ static void free_masks(struct irq_desc *
 #endif
 	free_cpumask_var(desc->affinity);
 }
+static int node
 #else
 static inline void free_masks(struct irq_desc *desc) { }
 #endif
@@ -290,16 +296,7 @@ struct irq_desc *irq_to_desc_alloc_node(
 
 static void free_desc(unsigned int irq)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&desc->lock, flags);
-#ifdef CONFIG_SMP
-	desc_set_defaults(irq, desc, desc->node);
-#else
-	desc_set_defaults(irq, desc, 0);
-#endif
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
+	dynamic_irq_cleanup(irq);
 }
 
 static inline int alloc_descs(unsigned int start, unsigned int cnt, int node)
@@ -386,6 +383,22 @@ unsigned int irq_get_next_irq(unsigned i
 	return res;
 }
 
+/**
+ * dynamic_irq_cleanup - cleanup a dynamically allocated irq
+ * @irq:	irq number to initialize
+ */
+void dynamic_irq_cleanup(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&desc->lock, flags);
+	desc_set_defaults(irq, desc, desc_node(desc));
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+ unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
+
 /* Statistics access */
 void clear_kstat_irqs(struct irq_desc *desc)
 {

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

* [patch 40/47] genirq: Sanitize dynamic irq handling
  2010-09-30 23:17 ` [patch 40/47] genirq: Sanitize dynamic irq handling Thomas Gleixner
@ 2010-09-30 23:17   ` Thomas Gleixner
  2010-10-01  5:47   ` Yinghai Lu
  1 sibling, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:17 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: generiq-sanitize-dynamic-irq-handling.patch --]
[-- Type: text/plain, Size: 7112 bytes --]

Use the cleanup functions of the dynamic allocator. No need to have
separate implementations.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h    |   12 +++--
 kernel/irq/chip.c      |  104 -------------------------------------------------
 kernel/irq/internals.h |    1 
 kernel/irq/irqdesc.c   |   37 +++++++++++------
 4 files changed, 33 insertions(+), 121 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -497,11 +497,15 @@ static inline int irq_has_action(unsigne
 	return desc->action != NULL;
 }
 
-/* Dynamic irq helper functions */
-extern void dynamic_irq_init(unsigned int irq);
-void dynamic_irq_init_keep_chip_data(unsigned int irq);
+/*
+ * Dynamic irq helper functions. Obsolete. Use irq_alloc_desc* and
+ * irq_free_desc instead.
+ */
 extern void dynamic_irq_cleanup(unsigned int irq);
-void dynamic_irq_cleanup_keep_chip_data(unsigned int irq);
+static inline void dynamic_irq_init(unsigned int irq)
+{
+	dynamic_irq_cleanup(irq);
+}
 
 /* Set/get chip/data for an IRQ: */
 extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -18,110 +18,6 @@
 
 #include "internals.h"
 
-static void dynamic_irq_init_x(unsigned int irq, bool keep_chip_data)
-{
-	struct irq_desc *desc;
-	unsigned long flags;
-
-	desc = irq_to_desc(irq);
-	if (!desc) {
-		WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
-		return;
-	}
-
-	/* Ensure we don't have left over values from a previous use of this irq */
-	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->status = IRQ_DEFAULT_INIT_FLAGS;
-	desc->chip = &no_irq_chip;
-	desc->irq_data.chip = &no_irq_chip;
-	desc->handle_irq = handle_bad_irq;
-	desc->depth = 1;
-	desc->irq_data.msi_desc = NULL;
-	desc->irq_data.handler_data = NULL;
-	if (!keep_chip_data)
-		desc->irq_data.chip_data = NULL;
-	desc->action = NULL;
-	desc->irq_count = 0;
-	desc->irqs_unhandled = 0;
-#ifdef CONFIG_SMP
-	cpumask_setall(desc->affinity);
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	cpumask_clear(desc->pending_mask);
-#endif
-#endif
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/**
- *	dynamic_irq_init - initialize a dynamically allocated irq
- *	@irq:	irq number to initialize
- */
-void dynamic_irq_init(unsigned int irq)
-{
-	dynamic_irq_init_x(irq, false);
-}
-
-/**
- *	dynamic_irq_init_keep_chip_data - initialize a dynamically allocated irq
- *	@irq:	irq number to initialize
- *
- *	does not set irq_to_desc(irq)->chip_data to NULL
- */
-void dynamic_irq_init_keep_chip_data(unsigned int irq)
-{
-	dynamic_irq_init_x(irq, true);
-}
-
-static void dynamic_irq_cleanup_x(unsigned int irq, bool keep_chip_data)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	unsigned long flags;
-
-	if (!desc) {
-		WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
-		return;
-	}
-
-	raw_spin_lock_irqsave(&desc->lock, flags);
-	if (desc->action) {
-		raw_spin_unlock_irqrestore(&desc->lock, flags);
-		WARN(1, KERN_ERR "Destroying IRQ%d without calling free_irq\n",
-			irq);
-		return;
-	}
-	desc->irq_data.msi_desc = NULL;
-	desc->irq_data.handler_data = NULL;
-	if (!keep_chip_data)
-		desc->irq_data.chip_data = NULL;
-	desc->handle_irq = handle_bad_irq;
-	desc->chip = &no_irq_chip;
-	desc->irq_data.chip = &no_irq_chip;
-	desc->name = NULL;
-	clear_kstat_irqs(desc);
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/**
- *	dynamic_irq_cleanup - cleanup a dynamically allocated irq
- *	@irq:	irq number to initialize
- */
-void dynamic_irq_cleanup(unsigned int irq)
-{
-	dynamic_irq_cleanup_x(irq, false);
-}
-
-/**
- *	dynamic_irq_cleanup_keep_chip_data - cleanup a dynamically allocated irq
- *	@irq:	irq number to initialize
- *
- *	does not set irq_to_desc(irq)->chip_data to NULL
- */
-void dynamic_irq_cleanup_keep_chip_data(unsigned int irq)
-{
-	dynamic_irq_cleanup_x(irq, true);
-}
-
-
 /**
  *	set_irq_chip - set the irq chip for an irq
  *	@irq:	irq number
Index: linux-2.6-tip/kernel/irq/internals.h
===================================================================
--- linux-2.6-tip.orig/kernel/irq/internals.h
+++ linux-2.6-tip/kernel/irq/internals.h
@@ -17,7 +17,6 @@ extern void __enable_irq(struct irq_desc
 
 extern struct lock_class_key irq_desc_lock_class;
 extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
-extern void clear_kstat_irqs(struct irq_desc *desc);
 extern raw_spinlock_t sparse_irq_lock;
 
 #ifdef CONFIG_SPARSE_IRQ
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -54,10 +54,13 @@ static void desc_smp_init(struct irq_des
 	desc->node = node;
 	desc->irq_data.affinity = &desc->affinity;
 	cpumask_copy(desc->affinity, irq_default_affinity);
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	cpumask_clear(desc->pending_mask);
+#endif
 }
-
+static inline int desc_node(struct irq_desc *desc) { return desc->node; }
 #else
-static inline int
+static inline int desc_node(struct irq_desc *desc) { return 0; }
 alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
 static inline void desc_smp_init(struct irq_desc *desc, int node) { }
 #endif
@@ -72,6 +75,8 @@ static void desc_set_defaults(unsigned i
 	desc->irq_data.chip = &no_irq_chip;
 	desc->handle_irq = handle_bad_irq;
 	desc->depth = 1;
+	desc->irq_count = 0;
+	desc->irqs_unhandled = 0;
 	desc->name = NULL;
 	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
 	desc_smp_init(desc, node);
@@ -136,6 +141,7 @@ static void free_masks(struct irq_desc *
 #endif
 	free_cpumask_var(desc->affinity);
 }
+static int node
 #else
 static inline void free_masks(struct irq_desc *desc) { }
 #endif
@@ -290,16 +296,7 @@ struct irq_desc *irq_to_desc_alloc_node(
 
 static void free_desc(unsigned int irq)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&desc->lock, flags);
-#ifdef CONFIG_SMP
-	desc_set_defaults(irq, desc, desc->node);
-#else
-	desc_set_defaults(irq, desc, 0);
-#endif
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
+	dynamic_irq_cleanup(irq);
 }
 
 static inline int alloc_descs(unsigned int start, unsigned int cnt, int node)
@@ -386,6 +383,22 @@ unsigned int irq_get_next_irq(unsigned i
 	return res;
 }
 
+/**
+ * dynamic_irq_cleanup - cleanup a dynamically allocated irq
+ * @irq:	irq number to initialize
+ */
+void dynamic_irq_cleanup(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&desc->lock, flags);
+	desc_set_defaults(irq, desc, desc_node(desc));
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+ unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
+
 /* Statistics access */
 void clear_kstat_irqs(struct irq_desc *desc)
 {



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

* [patch 41/47] arm: davinci: Cleanup irq_desc access
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (39 preceding siblings ...)
  2010-09-30 23:17 ` [patch 40/47] genirq: Sanitize dynamic irq handling Thomas Gleixner
@ 2010-09-30 23:18 ` Thomas Gleixner
  2010-09-30 23:18   ` Thomas Gleixner
  2010-09-30 23:18 ` [patch 42/47] genirq: Remove the now unused sparse irq leftovers Thomas Gleixner
                   ` (9 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: arm-davinci-cleanup-irq-desc-access.patch --]
[-- Type: text/plain, Size: 733 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/mach-davinci/gpio.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6-tip/arch/arm/mach-davinci/gpio.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/mach-davinci/gpio.c
+++ linux-2.6-tip/arch/arm/mach-davinci/gpio.c
@@ -395,7 +395,7 @@ static int __init davinci_gpio_irq_setup
 
 		/* AINTC handles mask/unmask; GPIO handles triggering */
 		irq = bank_irq;
-		gpio_irqchip_unbanked = *get_irq_desc_chip(irq_to_desc(irq));
+		gpio_irqchip_unbanked = *irq_get_irq_data(irq)->chip;
 		gpio_irqchip_unbanked.name = "GPIO-AINTC";
 		gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked;
 

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

* [patch 41/47] arm: davinci: Cleanup irq_desc access
  2010-09-30 23:18 ` [patch 41/47] arm: davinci: Cleanup irq_desc access Thomas Gleixner
@ 2010-09-30 23:18   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: arm-davinci-cleanup-irq-desc-access.patch --]
[-- Type: text/plain, Size: 735 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/mach-davinci/gpio.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6-tip/arch/arm/mach-davinci/gpio.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/mach-davinci/gpio.c
+++ linux-2.6-tip/arch/arm/mach-davinci/gpio.c
@@ -395,7 +395,7 @@ static int __init davinci_gpio_irq_setup
 
 		/* AINTC handles mask/unmask; GPIO handles triggering */
 		irq = bank_irq;
-		gpio_irqchip_unbanked = *get_irq_desc_chip(irq_to_desc(irq));
+		gpio_irqchip_unbanked = *irq_get_irq_data(irq)->chip;
 		gpio_irqchip_unbanked.name = "GPIO-AINTC";
 		gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked;
 



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

* [patch 42/47] genirq: Remove the now unused sparse irq leftovers
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (40 preceding siblings ...)
  2010-09-30 23:18 ` [patch 41/47] arm: davinci: Cleanup irq_desc access Thomas Gleixner
@ 2010-09-30 23:18 ` Thomas Gleixner
  2010-09-30 23:18   ` Thomas Gleixner
  2010-09-30 23:18 ` [patch 43/47] x86: xen: Sanitise sparse_irq handling Thomas Gleixner
                   ` (8 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-remove-the-gunk.patch --]
[-- Type: text/plain, Size: 11555 bytes --]

The move_irq_desc() function was only used due to the problem that the
allocator did not free the old descriptors. So the descriptors had to
be moved in create_irq_nr(). That's history.

The code would have never been able to move active interrupt
descriptors on affinity settings. That can be done in a completely
different way w/o all this horror.

Remove all of it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/Kconfig          |    1 
 include/linux/irq.h       |   19 -------
 kernel/irq/Kconfig        |    5 -
 kernel/irq/Makefile       |    1 
 kernel/irq/internals.h    |   86 --------------------------------
 kernel/irq/irqdesc.c      |   30 -----------
 kernel/irq/numa_migrate.c |  120 ----------------------------------------------
 7 files changed, 2 insertions(+), 260 deletions(-)

Index: linux-2.6-tip/arch/x86/Kconfig
===================================================================
--- linux-2.6-tip.orig/arch/x86/Kconfig
+++ linux-2.6-tip/arch/x86/Kconfig
@@ -61,7 +61,6 @@ config X86
 	select HAVE_USER_RETURN_NOTIFIER
 	select HAVE_GENERIC_HARDIRQS
 	select HAVE_SPARSE_IRQ
-	select NUMA_IRQ_DESC if (SPARSE_IRQ && NUMA)
 	select GENERIC_IRQ_PROBE
 	select GENERIC_PENDING_IRQ if SMP
 
Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -257,23 +257,10 @@ struct irq_desc {
 	const char		*name;
 } ____cacheline_internodealigned_in_smp;
 
-extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
-					struct irq_desc *desc, int node);
-extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
-
 #ifndef CONFIG_SPARSE_IRQ
 extern struct irq_desc irq_desc[NR_IRQS];
 #endif
 
-#ifdef CONFIG_NUMA_IRQ_DESC
-extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int node);
-#else
-static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
-{
-	return desc;
-}
-#endif
-
 extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
 
 int irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node);
@@ -539,12 +526,6 @@ static inline struct msi_desc *get_irq_m
 	return d ? d->msi_desc : NULL;
 }
 
-/* Needs to die ! */
-static inline void set_irq_desc_chip_data(struct irq_desc *desc, void *data)
-{
-	desc->irq_data.chip_data = data;
-}
-
 #define get_irq_desc_chip(desc)		((desc)->irq_data.chip)
 #define get_irq_desc_chip_data(desc)	((desc)->irq_data.chip_data)
 #define get_irq_desc_data(desc)		((desc)->irq_data.handler_data)
Index: linux-2.6-tip/kernel/irq/Kconfig
===================================================================
--- linux-2.6-tip.orig/kernel/irq/Kconfig
+++ linux-2.6-tip/kernel/irq/Kconfig
@@ -22,11 +22,6 @@ config GENERIC_IRQ_PROBE
 config GENERIC_PENDING_IRQ
 	def_bool n
 
-if SPARSE_IRQ && NUMA
-config NUMA_IRQ_DESC
-	def_bool n
-endif
-
 config AUTO_IRQ_AFFINITY
        def_bool n
 
Index: linux-2.6-tip/kernel/irq/Makefile
===================================================================
--- linux-2.6-tip.orig/kernel/irq/Makefile
+++ linux-2.6-tip/kernel/irq/Makefile
@@ -3,5 +3,4 @@ obj-y := irqdesc.o handle.o manage.o spu
 obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
-obj-$(CONFIG_NUMA_IRQ_DESC) += numa_migrate.o
 obj-$(CONFIG_PM_SLEEP) += pm.o
Index: linux-2.6-tip/kernel/irq/internals.h
===================================================================
--- linux-2.6-tip.orig/kernel/irq/internals.h
+++ linux-2.6-tip/kernel/irq/internals.h
@@ -15,14 +15,6 @@ extern int __irq_set_trigger(struct irq_
 extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
 extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
 
-extern struct lock_class_key irq_desc_lock_class;
-extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
-extern raw_spinlock_t sparse_irq_lock;
-
-#ifdef CONFIG_SPARSE_IRQ
-void replace_irq_desc(unsigned int irq, struct irq_desc *desc);
-#endif
-
 #ifdef CONFIG_PROC_FS
 extern void register_irq_proc(unsigned int irq, struct irq_desc *desc);
 extern void unregister_irq_proc(unsigned int irq, struct irq_desc *desc);
@@ -59,84 +51,6 @@ static inline struct irq_desc *irq_data_
 	return container_of(data, struct irq_desc, irq_data);
 }
 
-#ifdef CONFIG_SMP
-/**
- * alloc_desc_masks - allocate cpumasks for irq_desc
- * @desc:	pointer to irq_desc struct
- * @node:	node which will be handling the cpumasks
- * @boot:	true if need bootmem
- *
- * Allocates affinity and pending_mask cpumask if required.
- * Returns true if successful (or not required).
- */
-static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
-							bool boot)
-{
-#ifdef CONFIG_CPUMASK_OFFSTACK
-	gfp_t gfp = boot ? GFP_NOWAIT : GFP_ATOMIC;
-
-	if (!alloc_cpumask_var_node(&desc->affinity, gfp, node))
-		return false;
-
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	if (!alloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
-		free_cpumask_var(desc->affinity);
-		return false;
-	}
-#endif
-#endif
-	return true;
-}
-
-static inline void init_desc_masks(struct irq_desc *desc)
-{
-	cpumask_setall(desc->affinity);
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	cpumask_clear(desc->pending_mask);
-#endif
-}
-
-/**
- * init_copy_desc_masks - copy cpumasks for irq_desc
- * @old_desc:	pointer to old irq_desc struct
- * @new_desc:	pointer to new irq_desc struct
- *
- * Insures affinity and pending_masks are copied to new irq_desc.
- * If !CONFIG_CPUMASKS_OFFSTACK the cpumasks are embedded in the
- * irq_desc struct so the copy is redundant.
- */
-
-static inline void init_copy_desc_masks(struct irq_desc *old_desc,
-					struct irq_desc *new_desc)
-{
-#ifdef CONFIG_CPUMASK_OFFSTACK
-	cpumask_copy(new_desc->affinity, old_desc->affinity);
-
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	cpumask_copy(new_desc->pending_mask, old_desc->pending_mask);
-#endif
-#endif
-}
-
-static inline void free_desc_masks(struct irq_desc *old_desc,
-				   struct irq_desc *new_desc)
-{
-	free_cpumask_var(old_desc->affinity);
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	free_cpumask_var(old_desc->pending_mask);
-#endif
-}
-
-#else /* !CONFIG_SMP */
-static inline bool alloc_desc_masks(struct irq_desc *desc, int node, bool boot)
-{
-	return true;
-}
-static inline void init_desc_masks(struct irq_desc *desc) { }
-static inline void init_copy_desc_masks(struct irq_desc *o, struct irq_desc *n) { }
-static inline void free_desc_masks(struct irq_desc *o, struct irq_desc *n) { }
-#endif	/* CONFIG_SMP */
-
 /*
  * Debugging printout:
  */
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -20,7 +20,7 @@
 /*
  * lockdep: we want to handle all irq_desc locks as a single lock-class:
  */
-struct lock_class_key irq_desc_lock_class;
+static struct lock_class_key irq_desc_lock_class;
 
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
 static void __init init_irq_default_affinity(void)
@@ -85,28 +85,11 @@ static void desc_set_defaults(unsigned i
 int nr_irqs = NR_IRQS;
 EXPORT_SYMBOL_GPL(nr_irqs);
 
-DEFINE_RAW_SPINLOCK(sparse_irq_lock);
+static DEFINE_RAW_SPINLOCK(sparse_irq_lock);
 static DECLARE_BITMAP(allocated_irqs, NR_IRQS);
 
 #ifdef CONFIG_SPARSE_IRQ
 
-void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
-{
-	void *ptr;
-
-	ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
-			   GFP_ATOMIC, node);
-
-	/*
-	 * don't overwite if can not get new one
-	 * init_copy_kstat_irqs() could still use old one
-	 */
-	if (ptr) {
-		printk(KERN_DEBUG "  alloc kstat_irqs on node %d\n", node);
-		desc->kstat_irqs = ptr;
-	}
-}
-
 static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
 
 static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
@@ -119,15 +102,6 @@ struct irq_desc *irq_to_desc(unsigned in
 	return radix_tree_lookup(&irq_desc_tree, irq);
 }
 
-void replace_irq_desc(unsigned int irq, struct irq_desc *desc)
-{
-	void **ptr;
-
-	ptr = radix_tree_lookup_slot(&irq_desc_tree, irq);
-	if (ptr)
-		radix_tree_replace_slot(ptr, desc);
-}
-
 static void delete_irq_desc(unsigned int irq)
 {
 	radix_tree_delete(&irq_desc_tree, irq);
Index: linux-2.6-tip/kernel/irq/numa_migrate.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/numa_migrate.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * NUMA irq-desc migration code
- *
- * Migrate IRQ data structures (irq_desc, chip_data, etc.) over to
- * the new "home node" of the IRQ.
- */
-
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/random.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-
-#include "internals.h"
-
-static void init_copy_kstat_irqs(struct irq_desc *old_desc,
-				 struct irq_desc *desc,
-				 int node, int nr)
-{
-	init_kstat_irqs(desc, node, nr);
-
-	if (desc->kstat_irqs != old_desc->kstat_irqs)
-		memcpy(desc->kstat_irqs, old_desc->kstat_irqs,
-			 nr * sizeof(*desc->kstat_irqs));
-}
-
-static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)
-{
-	if (old_desc->kstat_irqs == desc->kstat_irqs)
-		return;
-
-	kfree(old_desc->kstat_irqs);
-	old_desc->kstat_irqs = NULL;
-}
-
-static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
-		 struct irq_desc *desc, int node)
-{
-	memcpy(desc, old_desc, sizeof(struct irq_desc));
-	if (!alloc_desc_masks(desc, node, false)) {
-		printk(KERN_ERR "irq %d: can not get new irq_desc cpumask "
-				"for migration.\n", irq);
-		return false;
-	}
-	raw_spin_lock_init(&desc->lock);
-	desc->node = node;
-	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	init_copy_kstat_irqs(old_desc, desc, node, nr_cpu_ids);
-	init_copy_desc_masks(old_desc, desc);
-	arch_init_copy_chip_data(old_desc, desc, node);
-	return true;
-}
-
-static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc)
-{
-	free_kstat_irqs(old_desc, desc);
-	free_desc_masks(old_desc, desc);
-	arch_free_chip_data(old_desc, desc);
-}
-
-static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
-						int node)
-{
-	struct irq_desc *desc;
-	unsigned int irq;
-	unsigned long flags;
-
-	irq = old_desc->irq;
-
-	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
-
-	/* We have to check it to avoid races with another CPU */
-	desc = irq_to_desc(irq);
-
-	if (desc && old_desc != desc)
-		goto out_unlock;
-
-	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
-	if (!desc) {
-		printk(KERN_ERR "irq %d: can not get new irq_desc "
-				"for migration.\n", irq);
-		/* still use old one */
-		desc = old_desc;
-		goto out_unlock;
-	}
-	if (!init_copy_one_irq_desc(irq, old_desc, desc, node)) {
-		/* still use old one */
-		kfree(desc);
-		desc = old_desc;
-		goto out_unlock;
-	}
-
-	replace_irq_desc(irq, desc);
-	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
-
-	/* free the old one */
-	free_one_irq_desc(old_desc, desc);
-	kfree(old_desc);
-
-	return desc;
-
-out_unlock:
-	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
-
-	return desc;
-}
-
-struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
-{
-	/* those static or target node is -1, do not move them */
-	if (desc->irq < NR_IRQS_LEGACY || node == -1)
-		return desc;
-
-	if (desc->node != node)
-		desc = __real_move_irq_desc(desc, node);
-
-	return desc;
-}
-

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

* [patch 42/47] genirq: Remove the now unused sparse irq leftovers
  2010-09-30 23:18 ` [patch 42/47] genirq: Remove the now unused sparse irq leftovers Thomas Gleixner
@ 2010-09-30 23:18   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-remove-the-gunk.patch --]
[-- Type: text/plain, Size: 11557 bytes --]

The move_irq_desc() function was only used due to the problem that the
allocator did not free the old descriptors. So the descriptors had to
be moved in create_irq_nr(). That's history.

The code would have never been able to move active interrupt
descriptors on affinity settings. That can be done in a completely
different way w/o all this horror.

Remove all of it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/Kconfig          |    1 
 include/linux/irq.h       |   19 -------
 kernel/irq/Kconfig        |    5 -
 kernel/irq/Makefile       |    1 
 kernel/irq/internals.h    |   86 --------------------------------
 kernel/irq/irqdesc.c      |   30 -----------
 kernel/irq/numa_migrate.c |  120 ----------------------------------------------
 7 files changed, 2 insertions(+), 260 deletions(-)

Index: linux-2.6-tip/arch/x86/Kconfig
===================================================================
--- linux-2.6-tip.orig/arch/x86/Kconfig
+++ linux-2.6-tip/arch/x86/Kconfig
@@ -61,7 +61,6 @@ config X86
 	select HAVE_USER_RETURN_NOTIFIER
 	select HAVE_GENERIC_HARDIRQS
 	select HAVE_SPARSE_IRQ
-	select NUMA_IRQ_DESC if (SPARSE_IRQ && NUMA)
 	select GENERIC_IRQ_PROBE
 	select GENERIC_PENDING_IRQ if SMP
 
Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -257,23 +257,10 @@ struct irq_desc {
 	const char		*name;
 } ____cacheline_internodealigned_in_smp;
 
-extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
-					struct irq_desc *desc, int node);
-extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
-
 #ifndef CONFIG_SPARSE_IRQ
 extern struct irq_desc irq_desc[NR_IRQS];
 #endif
 
-#ifdef CONFIG_NUMA_IRQ_DESC
-extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int node);
-#else
-static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
-{
-	return desc;
-}
-#endif
-
 extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
 
 int irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node);
@@ -539,12 +526,6 @@ static inline struct msi_desc *get_irq_m
 	return d ? d->msi_desc : NULL;
 }
 
-/* Needs to die ! */
-static inline void set_irq_desc_chip_data(struct irq_desc *desc, void *data)
-{
-	desc->irq_data.chip_data = data;
-}
-
 #define get_irq_desc_chip(desc)		((desc)->irq_data.chip)
 #define get_irq_desc_chip_data(desc)	((desc)->irq_data.chip_data)
 #define get_irq_desc_data(desc)		((desc)->irq_data.handler_data)
Index: linux-2.6-tip/kernel/irq/Kconfig
===================================================================
--- linux-2.6-tip.orig/kernel/irq/Kconfig
+++ linux-2.6-tip/kernel/irq/Kconfig
@@ -22,11 +22,6 @@ config GENERIC_IRQ_PROBE
 config GENERIC_PENDING_IRQ
 	def_bool n
 
-if SPARSE_IRQ && NUMA
-config NUMA_IRQ_DESC
-	def_bool n
-endif
-
 config AUTO_IRQ_AFFINITY
        def_bool n
 
Index: linux-2.6-tip/kernel/irq/Makefile
===================================================================
--- linux-2.6-tip.orig/kernel/irq/Makefile
+++ linux-2.6-tip/kernel/irq/Makefile
@@ -3,5 +3,4 @@ obj-y := irqdesc.o handle.o manage.o spu
 obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
-obj-$(CONFIG_NUMA_IRQ_DESC) += numa_migrate.o
 obj-$(CONFIG_PM_SLEEP) += pm.o
Index: linux-2.6-tip/kernel/irq/internals.h
===================================================================
--- linux-2.6-tip.orig/kernel/irq/internals.h
+++ linux-2.6-tip/kernel/irq/internals.h
@@ -15,14 +15,6 @@ extern int __irq_set_trigger(struct irq_
 extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
 extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
 
-extern struct lock_class_key irq_desc_lock_class;
-extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
-extern raw_spinlock_t sparse_irq_lock;
-
-#ifdef CONFIG_SPARSE_IRQ
-void replace_irq_desc(unsigned int irq, struct irq_desc *desc);
-#endif
-
 #ifdef CONFIG_PROC_FS
 extern void register_irq_proc(unsigned int irq, struct irq_desc *desc);
 extern void unregister_irq_proc(unsigned int irq, struct irq_desc *desc);
@@ -59,84 +51,6 @@ static inline struct irq_desc *irq_data_
 	return container_of(data, struct irq_desc, irq_data);
 }
 
-#ifdef CONFIG_SMP
-/**
- * alloc_desc_masks - allocate cpumasks for irq_desc
- * @desc:	pointer to irq_desc struct
- * @node:	node which will be handling the cpumasks
- * @boot:	true if need bootmem
- *
- * Allocates affinity and pending_mask cpumask if required.
- * Returns true if successful (or not required).
- */
-static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
-							bool boot)
-{
-#ifdef CONFIG_CPUMASK_OFFSTACK
-	gfp_t gfp = boot ? GFP_NOWAIT : GFP_ATOMIC;
-
-	if (!alloc_cpumask_var_node(&desc->affinity, gfp, node))
-		return false;
-
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	if (!alloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
-		free_cpumask_var(desc->affinity);
-		return false;
-	}
-#endif
-#endif
-	return true;
-}
-
-static inline void init_desc_masks(struct irq_desc *desc)
-{
-	cpumask_setall(desc->affinity);
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	cpumask_clear(desc->pending_mask);
-#endif
-}
-
-/**
- * init_copy_desc_masks - copy cpumasks for irq_desc
- * @old_desc:	pointer to old irq_desc struct
- * @new_desc:	pointer to new irq_desc struct
- *
- * Insures affinity and pending_masks are copied to new irq_desc.
- * If !CONFIG_CPUMASKS_OFFSTACK the cpumasks are embedded in the
- * irq_desc struct so the copy is redundant.
- */
-
-static inline void init_copy_desc_masks(struct irq_desc *old_desc,
-					struct irq_desc *new_desc)
-{
-#ifdef CONFIG_CPUMASK_OFFSTACK
-	cpumask_copy(new_desc->affinity, old_desc->affinity);
-
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	cpumask_copy(new_desc->pending_mask, old_desc->pending_mask);
-#endif
-#endif
-}
-
-static inline void free_desc_masks(struct irq_desc *old_desc,
-				   struct irq_desc *new_desc)
-{
-	free_cpumask_var(old_desc->affinity);
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	free_cpumask_var(old_desc->pending_mask);
-#endif
-}
-
-#else /* !CONFIG_SMP */
-static inline bool alloc_desc_masks(struct irq_desc *desc, int node, bool boot)
-{
-	return true;
-}
-static inline void init_desc_masks(struct irq_desc *desc) { }
-static inline void init_copy_desc_masks(struct irq_desc *o, struct irq_desc *n) { }
-static inline void free_desc_masks(struct irq_desc *o, struct irq_desc *n) { }
-#endif	/* CONFIG_SMP */
-
 /*
  * Debugging printout:
  */
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -20,7 +20,7 @@
 /*
  * lockdep: we want to handle all irq_desc locks as a single lock-class:
  */
-struct lock_class_key irq_desc_lock_class;
+static struct lock_class_key irq_desc_lock_class;
 
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
 static void __init init_irq_default_affinity(void)
@@ -85,28 +85,11 @@ static void desc_set_defaults(unsigned i
 int nr_irqs = NR_IRQS;
 EXPORT_SYMBOL_GPL(nr_irqs);
 
-DEFINE_RAW_SPINLOCK(sparse_irq_lock);
+static DEFINE_RAW_SPINLOCK(sparse_irq_lock);
 static DECLARE_BITMAP(allocated_irqs, NR_IRQS);
 
 #ifdef CONFIG_SPARSE_IRQ
 
-void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
-{
-	void *ptr;
-
-	ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
-			   GFP_ATOMIC, node);
-
-	/*
-	 * don't overwite if can not get new one
-	 * init_copy_kstat_irqs() could still use old one
-	 */
-	if (ptr) {
-		printk(KERN_DEBUG "  alloc kstat_irqs on node %d\n", node);
-		desc->kstat_irqs = ptr;
-	}
-}
-
 static RADIX_TREE(irq_desc_tree, GFP_ATOMIC);
 
 static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
@@ -119,15 +102,6 @@ struct irq_desc *irq_to_desc(unsigned in
 	return radix_tree_lookup(&irq_desc_tree, irq);
 }
 
-void replace_irq_desc(unsigned int irq, struct irq_desc *desc)
-{
-	void **ptr;
-
-	ptr = radix_tree_lookup_slot(&irq_desc_tree, irq);
-	if (ptr)
-		radix_tree_replace_slot(ptr, desc);
-}
-
 static void delete_irq_desc(unsigned int irq)
 {
 	radix_tree_delete(&irq_desc_tree, irq);
Index: linux-2.6-tip/kernel/irq/numa_migrate.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/numa_migrate.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * NUMA irq-desc migration code
- *
- * Migrate IRQ data structures (irq_desc, chip_data, etc.) over to
- * the new "home node" of the IRQ.
- */
-
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/random.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-
-#include "internals.h"
-
-static void init_copy_kstat_irqs(struct irq_desc *old_desc,
-				 struct irq_desc *desc,
-				 int node, int nr)
-{
-	init_kstat_irqs(desc, node, nr);
-
-	if (desc->kstat_irqs != old_desc->kstat_irqs)
-		memcpy(desc->kstat_irqs, old_desc->kstat_irqs,
-			 nr * sizeof(*desc->kstat_irqs));
-}
-
-static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)
-{
-	if (old_desc->kstat_irqs == desc->kstat_irqs)
-		return;
-
-	kfree(old_desc->kstat_irqs);
-	old_desc->kstat_irqs = NULL;
-}
-
-static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
-		 struct irq_desc *desc, int node)
-{
-	memcpy(desc, old_desc, sizeof(struct irq_desc));
-	if (!alloc_desc_masks(desc, node, false)) {
-		printk(KERN_ERR "irq %d: can not get new irq_desc cpumask "
-				"for migration.\n", irq);
-		return false;
-	}
-	raw_spin_lock_init(&desc->lock);
-	desc->node = node;
-	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-	init_copy_kstat_irqs(old_desc, desc, node, nr_cpu_ids);
-	init_copy_desc_masks(old_desc, desc);
-	arch_init_copy_chip_data(old_desc, desc, node);
-	return true;
-}
-
-static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc)
-{
-	free_kstat_irqs(old_desc, desc);
-	free_desc_masks(old_desc, desc);
-	arch_free_chip_data(old_desc, desc);
-}
-
-static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
-						int node)
-{
-	struct irq_desc *desc;
-	unsigned int irq;
-	unsigned long flags;
-
-	irq = old_desc->irq;
-
-	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
-
-	/* We have to check it to avoid races with another CPU */
-	desc = irq_to_desc(irq);
-
-	if (desc && old_desc != desc)
-		goto out_unlock;
-
-	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
-	if (!desc) {
-		printk(KERN_ERR "irq %d: can not get new irq_desc "
-				"for migration.\n", irq);
-		/* still use old one */
-		desc = old_desc;
-		goto out_unlock;
-	}
-	if (!init_copy_one_irq_desc(irq, old_desc, desc, node)) {
-		/* still use old one */
-		kfree(desc);
-		desc = old_desc;
-		goto out_unlock;
-	}
-
-	replace_irq_desc(irq, desc);
-	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
-
-	/* free the old one */
-	free_one_irq_desc(old_desc, desc);
-	kfree(old_desc);
-
-	return desc;
-
-out_unlock:
-	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
-
-	return desc;
-}
-
-struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
-{
-	/* those static or target node is -1, do not move them */
-	if (desc->irq < NR_IRQS_LEGACY || node == -1)
-		return desc;
-
-	if (desc->node != node)
-		desc = __real_move_irq_desc(desc, node);
-
-	return desc;
-}
-



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

* [patch 43/47] x86: xen: Sanitise sparse_irq handling
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (41 preceding siblings ...)
  2010-09-30 23:18 ` [patch 42/47] genirq: Remove the now unused sparse irq leftovers Thomas Gleixner
@ 2010-09-30 23:18 ` Thomas Gleixner
  2010-09-30 23:18   ` Thomas Gleixner
  2010-09-30 23:18 ` [patch 44/47] sh: Sanitize sparse irq Thomas Gleixner
                   ` (7 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: xen-sanitise-sparse.patch --]
[-- Type: text/plain, Size: 1615 bytes --]

There seems to be more cleanups possible, but that's left to the xen
experts :)

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/xen/events.c |   23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

Index: linux-2.6-tip/drivers/xen/events.c
===================================================================
--- linux-2.6-tip.orig/drivers/xen/events.c
+++ linux-2.6-tip/drivers/xen/events.c
@@ -338,30 +338,29 @@ static void unmask_evtchn(int port)
 
 static int find_unbound_irq(void)
 {
-	int irq;
-	struct irq_desc *desc;
+	struct irq_data *data;
+	int irq, res;
 
 	for (irq = 0; irq < nr_irqs; irq++) {
-		desc = irq_to_desc(irq);
+		data = irq_get_irq_data(irq);
 		/* only 0->15 have init'd desc; handle irq > 16 */
-		if (desc == NULL)
+		if (!data)
 			break;
-		if (desc->chip == &no_irq_chip)
+		if (data->chip == &no_irq_chip)
 			break;
-		if (desc->chip != &xen_dynamic_chip)
+		if (data->chip != &xen_dynamic_chip)
 			continue;
 		if (irq_info[irq].type == IRQT_UNBOUND)
-			break;
+			return irq;
 	}
 
 	if (irq == nr_irqs)
 		panic("No available IRQ to bind to: increase nr_irqs!\n");
 
-	desc = irq_to_desc_alloc_node(irq, 0);
-	if (WARN_ON(desc == NULL))
-		return -1;
+	res = irq_alloc_desc_at(irq, 0);
 
-	dynamic_irq_init_keep_chip_data(irq);
+	if (WARN_ON(res != irq))
+		return -1;
 
 	return irq;
 }
@@ -495,7 +494,7 @@ static void unbind_from_irq(unsigned int
 	if (irq_info[irq].type != IRQT_UNBOUND) {
 		irq_info[irq] = mk_unbound_info();
 
-		dynamic_irq_cleanup(irq);
+		irq_free_desc(irq);
 	}
 
 	spin_unlock(&irq_mapping_update_lock);

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

* [patch 43/47] x86: xen: Sanitise sparse_irq handling
  2010-09-30 23:18 ` [patch 43/47] x86: xen: Sanitise sparse_irq handling Thomas Gleixner
@ 2010-09-30 23:18   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: xen-sanitise-sparse.patch --]
[-- Type: text/plain, Size: 1617 bytes --]

There seems to be more cleanups possible, but that's left to the xen
experts :)

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/xen/events.c |   23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

Index: linux-2.6-tip/drivers/xen/events.c
===================================================================
--- linux-2.6-tip.orig/drivers/xen/events.c
+++ linux-2.6-tip/drivers/xen/events.c
@@ -338,30 +338,29 @@ static void unmask_evtchn(int port)
 
 static int find_unbound_irq(void)
 {
-	int irq;
-	struct irq_desc *desc;
+	struct irq_data *data;
+	int irq, res;
 
 	for (irq = 0; irq < nr_irqs; irq++) {
-		desc = irq_to_desc(irq);
+		data = irq_get_irq_data(irq);
 		/* only 0->15 have init'd desc; handle irq > 16 */
-		if (desc == NULL)
+		if (!data)
 			break;
-		if (desc->chip == &no_irq_chip)
+		if (data->chip == &no_irq_chip)
 			break;
-		if (desc->chip != &xen_dynamic_chip)
+		if (data->chip != &xen_dynamic_chip)
 			continue;
 		if (irq_info[irq].type == IRQT_UNBOUND)
-			break;
+			return irq;
 	}
 
 	if (irq == nr_irqs)
 		panic("No available IRQ to bind to: increase nr_irqs!\n");
 
-	desc = irq_to_desc_alloc_node(irq, 0);
-	if (WARN_ON(desc == NULL))
-		return -1;
+	res = irq_alloc_desc_at(irq, 0);
 
-	dynamic_irq_init_keep_chip_data(irq);
+	if (WARN_ON(res != irq))
+		return -1;
 
 	return irq;
 }
@@ -495,7 +494,7 @@ static void unbind_from_irq(unsigned int
 	if (irq_info[irq].type != IRQT_UNBOUND) {
 		irq_info[irq] = mk_unbound_info();
 
-		dynamic_irq_cleanup(irq);
+		irq_free_desc(irq);
 	}
 
 	spin_unlock(&irq_mapping_update_lock);



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

* [patch 44/47] sh: Sanitize sparse irq
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (42 preceding siblings ...)
  2010-09-30 23:18 ` [patch 43/47] x86: xen: Sanitise sparse_irq handling Thomas Gleixner
@ 2010-09-30 23:18 ` Thomas Gleixner
  2010-09-30 23:18 ` [patch 45/47] x86: lguest: Use new irq allocator Thomas Gleixner
                   ` (6 subsequent siblings)
  50 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: sh-sanitize-sparse-irq.patch --]
[-- Type: text/plain, Size: 3392 bytes --]

Switch over to the new allocator functions.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/sh/kernel/cpu/irq/ipr.c |    6 +++---
 drivers/sh/intc.c            |   37 ++++++++++++++++---------------------
 2 files changed, 19 insertions(+), 24 deletions(-)

Index: linux-2.6-tip/arch/sh/kernel/cpu/irq/ipr.c
===================================================================
--- linux-2.6-tip.orig/arch/sh/kernel/cpu/irq/ipr.c
+++ linux-2.6-tip/arch/sh/kernel/cpu/irq/ipr.c
@@ -62,13 +62,13 @@ void register_ipr_controller(struct ipr_
 
 	for (i = 0; i < desc->nr_irqs; i++) {
 		struct ipr_data *p = desc->ipr_data + i;
-		struct irq_desc *irq_desc;
+		int res;
 
 		BUG_ON(p->ipr_idx >= desc->nr_offsets);
 		BUG_ON(!desc->ipr_offsets[p->ipr_idx]);
 
-		irq_desc = irq_to_desc_alloc_node(p->irq, numa_node_id());
-		if (unlikely(!irq_desc)) {
+		res = irq_alloc_desc_at(p->irq, numa_node_id());
+		if (unlikely(res != p->irq && res != -EEXIST))
 			printk(KERN_INFO "can not get irq_desc for %d\n",
 			       p->irq);
 			continue;
Index: linux-2.6-tip/drivers/sh/intc.c
===================================================================
--- linux-2.6-tip.orig/drivers/sh/intc.c
+++ linux-2.6-tip/drivers/sh/intc.c
@@ -1071,13 +1071,13 @@ int __init register_intc_controller(stru
 	for (i = 0; i < hw->nr_vectors; i++) {
 		struct intc_vect *vect = hw->vectors + i;
 		unsigned int irq = evt2irq(vect->vect);
-		struct irq_desc *irq_desc;
+		int res;
 
 		if (!vect->enum_id)
 			continue;
 
-		irq_desc = irq_to_desc_alloc_node(irq, numa_node_id());
-		if (unlikely(!irq_desc)) {
+		res = irq_alloc_desc_at(irq, numa_node_id());
+		if (res != irq && res != -EEXIST) {
 			pr_err("can't get irq_desc for %d\n", irq);
 			continue;
 		}
@@ -1096,8 +1096,8 @@ int __init register_intc_controller(stru
 			 * IRQ support, each vector still needs to have
 			 * its own backing irq_desc.
 			 */
-			irq_desc = irq_to_desc_alloc_node(irq2, numa_node_id());
-			if (unlikely(!irq_desc)) {
+			res = irq_alloc_desc_at(irq2, numa_node_id());
+			if (res != irq2 && res != -EEXIST) {
 				pr_err("can't get irq_desc for %d\n", irq2);
 				continue;
 			}
@@ -1301,7 +1301,6 @@ unsigned int create_irq_nr(unsigned int 
 {
 	unsigned int irq = 0, new;
 	unsigned long flags;
-	struct irq_desc *desc;
 
 	spin_lock_irqsave(&vector_lock, flags);
 
@@ -1319,26 +1318,22 @@ unsigned int create_irq_nr(unsigned int 
 		__set_bit(new, intc_irq_map);
 	}
 
-	desc = irq_to_desc_alloc_node(new, node);
-	if (unlikely(!desc)) {
+	spin_unlock_irqrestore(&vector_lock, flags);
+
+	irq = irq_alloc_desc_at(new, node);
+	if (unlikely(irq != new)) {
 		pr_err("can't get irq_desc for %d\n", new);
-		goto out_unlock;
+		return 0;
 	}
 
-	desc = move_irq_desc(desc, node);
-	irq = new;
-
-out_unlock:
-	spin_unlock_irqrestore(&vector_lock, flags);
-
-	if (irq > 0) {
-		dynamic_irq_init(irq);
 #ifdef CONFIG_ARM
-		set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */
+	set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */
 #endif
-	}
+	return 0;
 
-	return irq;
+out_unlock:
+	spin_unlock_irqrestore(&vector_lock, flags);
+	return 0;
 }
 
 int create_irq(void)
@@ -1357,7 +1352,7 @@ void destroy_irq(unsigned int irq)
 {
 	unsigned long flags;
 
-	dynamic_irq_cleanup(irq);
+	irq_free_desc(irq);
 
 	spin_lock_irqsave(&vector_lock, flags);
 	__clear_bit(irq, intc_irq_map);

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

* [patch 45/47] x86: lguest: Use new irq allocator
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (43 preceding siblings ...)
  2010-09-30 23:18 ` [patch 44/47] sh: Sanitize sparse irq Thomas Gleixner
@ 2010-09-30 23:18 ` Thomas Gleixner
  2010-09-30 23:18   ` Thomas Gleixner
  2010-09-30 23:18 ` [patch 46/47] powerpc: " Thomas Gleixner
                   ` (5 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-lguest-use-new-allocator.patch --]
[-- Type: text/plain, Size: 907 bytes --]

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

Index: linux-2.6-tip/arch/x86/lguest/boot.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/lguest/boot.c
+++ linux-2.6-tip/arch/x86/lguest/boot.c
@@ -835,12 +835,12 @@ static void __init lguest_init_IRQ(void)
  * rather than set them in lguest_init_IRQ we are called here every time an
  * lguest device needs an interrupt.
  *
- * FIXME: irq_to_desc_alloc_node() can fail due to lack of memory, we should
+ * FIXME: irq_alloc_desc_at() can fail due to lack of memory, we should
  * pass that up!
  */
 void lguest_setup_irq(unsigned int irq)
 {
-	irq_to_desc_alloc_node(irq, 0);
+	irq_alloc_desc_at(irq, 0);
 	set_irq_chip_and_handler_name(irq, &lguest_irq_controller,
 				      handle_level_irq, "level");
 }

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

* [patch 45/47] x86: lguest: Use new irq allocator
  2010-09-30 23:18 ` [patch 45/47] x86: lguest: Use new irq allocator Thomas Gleixner
@ 2010-09-30 23:18   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: x86-lguest-use-new-allocator.patch --]
[-- Type: text/plain, Size: 909 bytes --]

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

Index: linux-2.6-tip/arch/x86/lguest/boot.c
===================================================================
--- linux-2.6-tip.orig/arch/x86/lguest/boot.c
+++ linux-2.6-tip/arch/x86/lguest/boot.c
@@ -835,12 +835,12 @@ static void __init lguest_init_IRQ(void)
  * rather than set them in lguest_init_IRQ we are called here every time an
  * lguest device needs an interrupt.
  *
- * FIXME: irq_to_desc_alloc_node() can fail due to lack of memory, we should
+ * FIXME: irq_alloc_desc_at() can fail due to lack of memory, we should
  * pass that up!
  */
 void lguest_setup_irq(unsigned int irq)
 {
-	irq_to_desc_alloc_node(irq, 0);
+	irq_alloc_desc_at(irq, 0);
 	set_irq_chip_and_handler_name(irq, &lguest_irq_controller,
 				      handle_level_irq, "level");
 }



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

* [patch 46/47] powerpc: Use new irq allocator
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (44 preceding siblings ...)
  2010-09-30 23:18 ` [patch 45/47] x86: lguest: Use new irq allocator Thomas Gleixner
@ 2010-09-30 23:18 ` Thomas Gleixner
  2010-09-30 23:18   ` Thomas Gleixner
  2010-10-01  0:42   ` Benjamin Herrenschmidt
  2010-09-30 23:18 ` [patch 47/47] genirq: Remove the old sparse irq allocator function Thomas Gleixner
                   ` (4 subsequent siblings)
  50 siblings, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: powerpc-use-new-allocator.patch --]
[-- Type: text/plain, Size: 1571 bytes --]

Use the new functions and free the descriptor when the virq is
destroyed.

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

Index: linux-2.6-tip/arch/powerpc/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/kernel/irq.c
+++ linux-2.6-tip/arch/powerpc/kernel/irq.c
@@ -676,16 +676,15 @@ void irq_set_virq_count(unsigned int cou
 static int irq_setup_virq(struct irq_host *host, unsigned int virq,
 			    irq_hw_number_t hwirq)
 {
-	struct irq_desc *desc;
+	int res;
 
-	desc = irq_to_desc_alloc_node(virq, 0);
-	if (!desc) {
+	res = irq_alloc_desc_at(virq, 0);
+	if (res != virq) {
 		pr_debug("irq: -> allocating desc failed\n");
 		goto error;
 	}
 
-	/* Clear IRQ_NOREQUEST flag */
-	desc->status &= ~IRQ_NOREQUEST;
+	irq_clear_status_flags(virq, IRQ_NOREQUEST);
 
 	/* map it */
 	smp_wmb();
@@ -694,11 +693,13 @@ static int irq_setup_virq(struct irq_hos
 
 	if (host->ops->map(host, virq, hwirq)) {
 		pr_debug("irq: -> mapping failed, freeing\n");
-		goto error;
+		goto errdesc;
 	}
 
 	return 0;
 
+errdesc:
+	irq_free_descs(virq, 1);
 error:
 	irq_free_virt(virq, 1);
 	return -1;
@@ -877,9 +878,9 @@ void irq_dispose_mapping(unsigned int vi
 	smp_mb();
 	irq_map[virq].hwirq = host->inval_irq;
 
-	/* Set some flags */
-	irq_to_desc(virq)->status |= IRQ_NOREQUEST;
+	irq_set_status_flags(virq, IRQ_NOREQUEST);
 
+	irq_free_descs(virq, 1);
 	/* Free it */
 	irq_free_virt(virq, 1);
 }

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

* [patch 46/47] powerpc: Use new irq allocator
  2010-09-30 23:18 ` [patch 46/47] powerpc: " Thomas Gleixner
@ 2010-09-30 23:18   ` Thomas Gleixner
  2010-10-01  0:42   ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: powerpc-use-new-allocator.patch --]
[-- Type: text/plain, Size: 1573 bytes --]

Use the new functions and free the descriptor when the virq is
destroyed.

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

Index: linux-2.6-tip/arch/powerpc/kernel/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/kernel/irq.c
+++ linux-2.6-tip/arch/powerpc/kernel/irq.c
@@ -676,16 +676,15 @@ void irq_set_virq_count(unsigned int cou
 static int irq_setup_virq(struct irq_host *host, unsigned int virq,
 			    irq_hw_number_t hwirq)
 {
-	struct irq_desc *desc;
+	int res;
 
-	desc = irq_to_desc_alloc_node(virq, 0);
-	if (!desc) {
+	res = irq_alloc_desc_at(virq, 0);
+	if (res != virq) {
 		pr_debug("irq: -> allocating desc failed\n");
 		goto error;
 	}
 
-	/* Clear IRQ_NOREQUEST flag */
-	desc->status &= ~IRQ_NOREQUEST;
+	irq_clear_status_flags(virq, IRQ_NOREQUEST);
 
 	/* map it */
 	smp_wmb();
@@ -694,11 +693,13 @@ static int irq_setup_virq(struct irq_hos
 
 	if (host->ops->map(host, virq, hwirq)) {
 		pr_debug("irq: -> mapping failed, freeing\n");
-		goto error;
+		goto errdesc;
 	}
 
 	return 0;
 
+errdesc:
+	irq_free_descs(virq, 1);
 error:
 	irq_free_virt(virq, 1);
 	return -1;
@@ -877,9 +878,9 @@ void irq_dispose_mapping(unsigned int vi
 	smp_mb();
 	irq_map[virq].hwirq = host->inval_irq;
 
-	/* Set some flags */
-	irq_to_desc(virq)->status |= IRQ_NOREQUEST;
+	irq_set_status_flags(virq, IRQ_NOREQUEST);
 
+	irq_free_descs(virq, 1);
 	/* Free it */
 	irq_free_virt(virq, 1);
 }



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

* [patch 47/47] genirq: Remove the old sparse irq allocator function
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (45 preceding siblings ...)
  2010-09-30 23:18 ` [patch 46/47] powerpc: " Thomas Gleixner
@ 2010-09-30 23:18 ` Thomas Gleixner
  2010-09-30 23:18   ` Thomas Gleixner
  2010-10-01  3:32 ` [patch 00/47] Sparse irq rework Linus Torvalds
                   ` (3 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-remove-craplocator.patch --]
[-- Type: text/plain, Size: 1221 bytes --]

Last user is gone. Remove it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h  |    2 --
 kernel/irq/irqdesc.c |    9 ---------
 2 files changed, 11 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -261,8 +261,6 @@ struct irq_desc {
 extern struct irq_desc irq_desc[NR_IRQS];
 #endif
 
-extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
-
 int irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node);
 
 static inline int irq_alloc_desc(int node)
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -192,15 +192,6 @@ err:
 	return -ENOMEM;
 }
 
-struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
-{
-	int res = irq_alloc_descs(irq, irq, 1, node);
-
-	if (res == -EEXIST || res == irq)
-		return irq_to_desc(irq);
-	return NULL;
-}
-
 int __init early_irq_init(void)
 {
 	int i, initcnt, node = first_online_node;

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

* [patch 47/47] genirq: Remove the old sparse irq allocator function
  2010-09-30 23:18 ` [patch 47/47] genirq: Remove the old sparse irq allocator function Thomas Gleixner
@ 2010-09-30 23:18   ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-09-30 23:18 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

[-- Attachment #1: genirq-remove-craplocator.patch --]
[-- Type: text/plain, Size: 1223 bytes --]

Last user is gone. Remove it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h  |    2 --
 kernel/irq/irqdesc.c |    9 ---------
 2 files changed, 11 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -261,8 +261,6 @@ struct irq_desc {
 extern struct irq_desc irq_desc[NR_IRQS];
 #endif
 
-extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
-
 int irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node);
 
 static inline int irq_alloc_desc(int node)
Index: linux-2.6-tip/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/irqdesc.c
+++ linux-2.6-tip/kernel/irq/irqdesc.c
@@ -192,15 +192,6 @@ err:
 	return -ENOMEM;
 }
 
-struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
-{
-	int res = irq_alloc_descs(irq, irq, 1, node);
-
-	if (res == -EEXIST || res == irq)
-		return irq_to_desc(irq);
-	return NULL;
-}
-
 int __init early_irq_init(void)
 {
 	int i, initcnt, node = first_online_node;



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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-09-30 23:18 ` [patch 46/47] powerpc: " Thomas Gleixner
  2010-09-30 23:18   ` Thomas Gleixner
@ 2010-10-01  0:42   ` Benjamin Herrenschmidt
  2010-10-01 13:07     ` Thomas Gleixner
  1 sibling, 1 reply; 158+ messages in thread
From: Benjamin Herrenschmidt @ 2010-10-01  0:42 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

On Thu, 2010-09-30 at 23:18 +0000, Thomas Gleixner wrote:
> plain text document attachment (powerpc-use-new-allocator.patch)
> Use the new functions and free the descriptor when the virq is
> destroyed.

Looks ok as a first pass, but we should go further and replace the
allocator we have in powerpc to use yours instead.

Then I should get rid of my big irq_map that maps virq to HW number &
domain pointers and instead put those in the irq data. Any objection to
me sticking some archdata there for that purpose ?

That would make things much cleaner and in fact move one large step
toward being able to make powerpc virq scheme generic, which seems to be
a good idea from what I've heard :-)

Cheers,
Ben.

> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  arch/powerpc/kernel/irq.c |   17 +++++++++--------
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> Index: linux-2.6-tip/arch/powerpc/kernel/irq.c
> ===================================================================
> --- linux-2.6-tip.orig/arch/powerpc/kernel/irq.c
> +++ linux-2.6-tip/arch/powerpc/kernel/irq.c
> @@ -676,16 +676,15 @@ void irq_set_virq_count(unsigned int cou
>  static int irq_setup_virq(struct irq_host *host, unsigned int virq,
>  			    irq_hw_number_t hwirq)
>  {
> -	struct irq_desc *desc;
> +	int res;
>  
> -	desc = irq_to_desc_alloc_node(virq, 0);
> -	if (!desc) {
> +	res = irq_alloc_desc_at(virq, 0);
> +	if (res != virq) {
>  		pr_debug("irq: -> allocating desc failed\n");
>  		goto error;
>  	}
>  
> -	/* Clear IRQ_NOREQUEST flag */
> -	desc->status &= ~IRQ_NOREQUEST;
> +	irq_clear_status_flags(virq, IRQ_NOREQUEST);
>  
>  	/* map it */
>  	smp_wmb();
> @@ -694,11 +693,13 @@ static int irq_setup_virq(struct irq_hos
>  
>  	if (host->ops->map(host, virq, hwirq)) {
>  		pr_debug("irq: -> mapping failed, freeing\n");
> -		goto error;
> +		goto errdesc;
>  	}
>  
>  	return 0;
>  
> +errdesc:
> +	irq_free_descs(virq, 1);
>  error:
>  	irq_free_virt(virq, 1);
>  	return -1;
> @@ -877,9 +878,9 @@ void irq_dispose_mapping(unsigned int vi
>  	smp_mb();
>  	irq_map[virq].hwirq = host->inval_irq;
>  
> -	/* Set some flags */
> -	irq_to_desc(virq)->status |= IRQ_NOREQUEST;
> +	irq_set_status_flags(virq, IRQ_NOREQUEST);
>  
> +	irq_free_descs(virq, 1);
>  	/* Free it */
>  	irq_free_virt(virq, 1);
>  }
> 

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

* Re: [patch 00/47] Sparse irq rework
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (46 preceding siblings ...)
  2010-09-30 23:18 ` [patch 47/47] genirq: Remove the old sparse irq allocator function Thomas Gleixner
@ 2010-10-01  3:32 ` Linus Torvalds
  2010-10-01  3:32   ` Linus Torvalds
  2010-10-01  5:54 ` Yinghai Lu
                   ` (2 subsequent siblings)
  50 siblings, 1 reply; 158+ messages in thread
From: Linus Torvalds @ 2010-10-01  3:32 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

On Thu, Sep 30, 2010 at 4:14 PM, Thomas Gleixner <tglx@linutronix.de> wrote:
>
> The overall changes are (full changelog below):
>    56 files changed, 1229 insertions(+), 1682 deletions(-)

I can't really argue with those numbers. And the patches I looked at
(which was not all of them, but maybe half) looked reasonable.

Assuming it all _works_ ...

                Linus

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-01  3:32 ` [patch 00/47] Sparse irq rework Linus Torvalds
@ 2010-10-01  3:32   ` Linus Torvalds
  0 siblings, 0 replies; 158+ messages in thread
From: Linus Torvalds @ 2010-10-01  3:32 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

On Thu, Sep 30, 2010 at 4:14 PM, Thomas Gleixner <tglx@linutronix.de> wrote:
>
> The overall changes are (full changelog below):
>    56 files changed, 1229 insertions(+), 1682 deletions(-)

I can't really argue with those numbers. And the patches I looked at
(which was not all of them, but maybe half) looked reasonable.

Assuming it all _works_ ...

                Linus

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

* Re: [patch 14/47] genirq: Implement a sane sparse_irq allocator
  2010-09-30 23:15 ` [patch 14/47] genirq: Implement a sane sparse_irq allocator Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
@ 2010-10-01  5:28   ` Yinghai Lu
  2010-10-01 20:36     ` Thomas Gleixner
  1 sibling, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-01  5:28 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Grant Likely, Eric W. Biederman

On 09/30/2010 04:15 PM, Thomas Gleixner wrote:
......
> ---
>  include/linux/irq.h  |   25 +++++
>  kernel/irq/irqdesc.c |  226 +++++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 243 insertions(+), 8 deletions(-)
> 
> Index: linux-2.6-tip/include/linux/irq.h
> ===================================================================
> --- linux-2.6-tip.orig/include/linux/irq.h
> +++ linux-2.6-tip/include/linux/irq.h
> @@ -276,6 +276,31 @@ static inline struct irq_desc *move_irq_
>  
>  extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
>  
> +int irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node);
> +
> +static inline int irq_alloc_desc(int node)
> +{
> +	return irq_alloc_descs(0, 0, 1, node);
> +}
> +
> +static inline int
> +irq_alloc_desc_at(unsigned int at, int node)
> +{
> +	return irq_alloc_descs(at, 0, 1, node);

need to change to 

	return irq_alloc_descs(at, at, 1, node);

> +}
> +
...

> Index: linux-2.6-tip/kernel/irq/irqdesc.c
> ===================================================================
> --- linux-2.6-tip.orig/kernel/irq/irqdesc.c
> +++ linux-2.6-tip/kernel/irq/irqdesc.c
...

> +/**
> + * irq_alloc_descs - allocate and initialize a range of irq descriptors
> + * @irq:	Allocate for specific irq number if irq > 0
> + * @from:	Start the search from this irq number
> + * @cnt:	Number of consecutive irqs to allocate.
> + * @node:	Preferred node on which the irq descriptor should be allocated
> + *
> + * Returns the first irq number or error code
> + */
> +int __ref
> +irq_alloc_descs(unsigned int irq, unsigned int from, unsigned int cnt, int node)
> +{
> +	unsigned long flags;
> +	int start, ret;
> +
> +	if (!cnt)
> +		return -EINVAL;
> +
> +	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
> +
or add
	if (irq)
		from = irq;
here.

> +	start = bitmap_find_next_zero_area(allocated_irqs, nr_irqs, from, cnt, 0);
> +	ret = -EEXIST;
> +	if (irq && start != irq)
> +		goto err;
> +
> +	ret = -ENOMEM;
> +	if (start >= nr_irqs)
> +		goto err;
> +
> +	bitmap_set(allocated_irqs, start, cnt);
> +	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
> +	return alloc_descs(start, cnt, node);
> +
> +err:
> +	raw_spin_unlock_irqrestore(&sparse_irq_lock, flags);
> +	return ret;
> +}

Yinghai

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

* Re: [patch 40/47] genirq: Sanitize dynamic irq handling
  2010-09-30 23:17 ` [patch 40/47] genirq: Sanitize dynamic irq handling Thomas Gleixner
  2010-09-30 23:17   ` Thomas Gleixner
@ 2010-10-01  5:47   ` Yinghai Lu
  1 sibling, 0 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-01  5:47 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Grant Likely, Eric W. Biederman

On 09/30/2010 04:17 PM, Thomas Gleixner wrote:
> Use the cleanup functions of the dynamic allocator. No need to have
> separate implementations.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  include/linux/irq.h    |   12 +++--
>  kernel/irq/chip.c      |  104 -------------------------------------------------
>  kernel/irq/internals.h |    1 
>  kernel/irq/irqdesc.c   |   37 +++++++++++------
>  4 files changed, 33 insertions(+), 121 deletions(-)
> 
> Index: linux-2.6-tip/include/linux/irq.h
> ===================================================================
> --- linux-2.6-tip.orig/include/linux/irq.h
> +++ linux-2.6-tip/include/linux/irq.h
> @@ -497,11 +497,15 @@ static inline int irq_has_action(unsigne
>  	return desc->action != NULL;
>  }
>  
> -/* Dynamic irq helper functions */
> -extern void dynamic_irq_init(unsigned int irq);
> -void dynamic_irq_init_keep_chip_data(unsigned int irq);
> +/*
> + * Dynamic irq helper functions. Obsolete. Use irq_alloc_desc* and
> + * irq_free_desc instead.
> + */
>  extern void dynamic_irq_cleanup(unsigned int irq);
> -void dynamic_irq_cleanup_keep_chip_data(unsigned int irq);
> +static inline void dynamic_irq_init(unsigned int irq)
> +{
> +	dynamic_irq_cleanup(irq);
> +}
>  
>  /* Set/get chip/data for an IRQ: */
>  extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
> Index: linux-2.6-tip/kernel/irq/chip.c
> ===================================================================
> --- linux-2.6-tip.orig/kernel/irq/chip.c
> +++ linux-2.6-tip/kernel/irq/chip.c
> @@ -18,110 +18,6 @@
>  
>  #include "internals.h"
>  
> -static void dynamic_irq_init_x(unsigned int irq, bool keep_chip_data)
> -{
> -	struct irq_desc *desc;
> -	unsigned long flags;
> -
> -	desc = irq_to_desc(irq);
> -	if (!desc) {
> -		WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
> -		return;
> -	}
> -
> -	/* Ensure we don't have left over values from a previous use of this irq */
> -	raw_spin_lock_irqsave(&desc->lock, flags);
> -	desc->status = IRQ_DEFAULT_INIT_FLAGS;
> -	desc->chip = &no_irq_chip;
> -	desc->irq_data.chip = &no_irq_chip;
> -	desc->handle_irq = handle_bad_irq;
> -	desc->depth = 1;
> -	desc->irq_data.msi_desc = NULL;
> -	desc->irq_data.handler_data = NULL;
> -	if (!keep_chip_data)
> -		desc->irq_data.chip_data = NULL;
> -	desc->action = NULL;
> -	desc->irq_count = 0;
> -	desc->irqs_unhandled = 0;
> -#ifdef CONFIG_SMP
> -	cpumask_setall(desc->affinity);
> -#ifdef CONFIG_GENERIC_PENDING_IRQ
> -	cpumask_clear(desc->pending_mask);
> -#endif
> -#endif
> -	raw_spin_unlock_irqrestore(&desc->lock, flags);
> -}
> -
> -/**
> - *	dynamic_irq_init - initialize a dynamically allocated irq
> - *	@irq:	irq number to initialize
> - */
> -void dynamic_irq_init(unsigned int irq)
> -{
> -	dynamic_irq_init_x(irq, false);
> -}
> -
> -/**
> - *	dynamic_irq_init_keep_chip_data - initialize a dynamically allocated irq
> - *	@irq:	irq number to initialize
> - *
> - *	does not set irq_to_desc(irq)->chip_data to NULL
> - */
> -void dynamic_irq_init_keep_chip_data(unsigned int irq)
> -{
> -	dynamic_irq_init_x(irq, true);
> -}
> -
> -static void dynamic_irq_cleanup_x(unsigned int irq, bool keep_chip_data)
> -{
> -	struct irq_desc *desc = irq_to_desc(irq);
> -	unsigned long flags;
> -
> -	if (!desc) {
> -		WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
> -		return;
> -	}
> -
> -	raw_spin_lock_irqsave(&desc->lock, flags);
> -	if (desc->action) {
> -		raw_spin_unlock_irqrestore(&desc->lock, flags);
> -		WARN(1, KERN_ERR "Destroying IRQ%d without calling free_irq\n",
> -			irq);
> -		return;
> -	}
> -	desc->irq_data.msi_desc = NULL;
> -	desc->irq_data.handler_data = NULL;
> -	if (!keep_chip_data)
> -		desc->irq_data.chip_data = NULL;
> -	desc->handle_irq = handle_bad_irq;
> -	desc->chip = &no_irq_chip;
> -	desc->irq_data.chip = &no_irq_chip;
> -	desc->name = NULL;
> -	clear_kstat_irqs(desc);
> -	raw_spin_unlock_irqrestore(&desc->lock, flags);
> -}
> -
> -/**
> - *	dynamic_irq_cleanup - cleanup a dynamically allocated irq
> - *	@irq:	irq number to initialize
> - */
> -void dynamic_irq_cleanup(unsigned int irq)
> -{
> -	dynamic_irq_cleanup_x(irq, false);
> -}
> -
> -/**
> - *	dynamic_irq_cleanup_keep_chip_data - cleanup a dynamically allocated irq
> - *	@irq:	irq number to initialize
> - *
> - *	does not set irq_to_desc(irq)->chip_data to NULL
> - */
> -void dynamic_irq_cleanup_keep_chip_data(unsigned int irq)
> -{
> -	dynamic_irq_cleanup_x(irq, true);
> -}
> -
> -
>  /**
>   *	set_irq_chip - set the irq chip for an irq
>   *	@irq:	irq number
> Index: linux-2.6-tip/kernel/irq/internals.h
> ===================================================================
> --- linux-2.6-tip.orig/kernel/irq/internals.h
> +++ linux-2.6-tip/kernel/irq/internals.h
> @@ -17,7 +17,6 @@ extern void __enable_irq(struct irq_desc
>  
>  extern struct lock_class_key irq_desc_lock_class;
>  extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
> -extern void clear_kstat_irqs(struct irq_desc *desc);
>  extern raw_spinlock_t sparse_irq_lock;
>  
>  #ifdef CONFIG_SPARSE_IRQ
> Index: linux-2.6-tip/kernel/irq/irqdesc.c
> ===================================================================
> --- linux-2.6-tip.orig/kernel/irq/irqdesc.c
> +++ linux-2.6-tip/kernel/irq/irqdesc.c
> @@ -54,10 +54,13 @@ static void desc_smp_init(struct irq_des
>  	desc->node = node;
>  	desc->irq_data.affinity = &desc->affinity;
>  	cpumask_copy(desc->affinity, irq_default_affinity);
> +#ifdef CONFIG_GENERIC_PENDING_IRQ
> +	cpumask_clear(desc->pending_mask);
> +#endif
>  }
> -
> +static inline int desc_node(struct irq_desc *desc) { return desc->node; }
>  #else
> -static inline int
> +static inline int desc_node(struct irq_desc *desc) { return 0; }
>  alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
>  static inline void desc_smp_init(struct irq_desc *desc, int node) { }
>  #endif
> @@ -72,6 +75,8 @@ static void desc_set_defaults(unsigned i
>  	desc->irq_data.chip = &no_irq_chip;
>  	desc->handle_irq = handle_bad_irq;
>  	desc->depth = 1;
> +	desc->irq_count = 0;
> +	desc->irqs_unhandled = 0;
>  	desc->name = NULL;
>  	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
>  	desc_smp_init(desc, node);
> @@ -136,6 +141,7 @@ static void free_masks(struct irq_desc *
>  #endif
>  	free_cpumask_var(desc->affinity);
>  }
> +static int node

?

>  #else
>  static inline void free_masks(struct irq_desc *desc) { }
>  #endif
> @@ -290,16 +296,7 @@ struct irq_desc *irq_to_desc_alloc_node(
>  
>  static void free_desc(unsigned int irq)
>  {
> -	struct irq_desc *desc = irq_to_desc(irq);
> -	unsigned long flags;
> -
> -	raw_spin_lock_irqsave(&desc->lock, flags);
> -#ifdef CONFIG_SMP
> -	desc_set_defaults(irq, desc, desc->node);
> -#else
> -	desc_set_defaults(irq, desc, 0);
> -#endif
> -	raw_spin_unlock_irqrestore(&desc->lock, flags);
> +	dynamic_irq_cleanup(irq);
>  }
>  
>  static inline int alloc_descs(unsigned int start, unsigned int cnt, int node)
> @@ -386,6 +383,22 @@ unsigned int irq_get_next_irq(unsigned i
>  	return res;
>  }
>  
> +/**
> + * dynamic_irq_cleanup - cleanup a dynamically allocated irq
> + * @irq:	irq number to initialize
> + */
> +void dynamic_irq_cleanup(unsigned int irq)
> +{
> +	struct irq_desc *desc = irq_to_desc(irq);
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&desc->lock, flags);
> +	desc_set_defaults(irq, desc, desc_node(desc));
> +	raw_spin_unlock_irqrestore(&desc->lock, flags);
> +}
> +
> + unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
> +
>  /* Statistics access */
>  void clear_kstat_irqs(struct irq_desc *desc)
>  {
> 

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

* Re: [patch 00/47] Sparse irq rework
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (47 preceding siblings ...)
  2010-10-01  3:32 ` [patch 00/47] Sparse irq rework Linus Torvalds
@ 2010-10-01  5:54 ` Yinghai Lu
  2010-10-01  5:54   ` Yinghai Lu
  2010-10-01 20:35   ` Thomas Gleixner
  2010-10-03 11:23 ` Grant Likely
  2010-10-03 16:41 ` Eric W. Biederman
  50 siblings, 2 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-01  5:54 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Grant Likely, Eric W. Biederman

On 09/30/2010 04:14 PM, Thomas Gleixner wrote:
> The following patch series cleans up and mostly reimplements the core
> sparse irq implementation and sanitizes the most complex (ab)user:
> arch/x86
> 
> The series is based on the previous rework of irq chip functions which
> is available at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core
> 
> A combined throwaway git repository with all the following patches on top of
> tip/irq/core is available at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git
> 
> The overall changes are (full changelog below):
>     56 files changed, 1229 insertions(+), 1682 deletions(-)
> 
> The series consists of 3 parts:
> 
>     - cleanup of kernel/irq code and implementation of new allocator
>     - conversion of x86 to new irq_chip functions and new allocator
>     - trivial cleanup of the remaining users and removal of the old stuff
> 
> It's fully bisectable and survived a night of testing in my testfarm.

  CC      kernel/irq/irqdesc.o
kernel/irq/irqdesc.c:123: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘static’
kernel/irq/irqdesc.c: In function ‘alloc_descs’:
kernel/irq/irqdesc.c:176: error: implicit declaration of function ‘alloc_desc’
kernel/irq/irqdesc.c:176: warning: assignment makes pointer from integer without a cast
kernel/irq/irqdesc.c: In function ‘early_irq_init’:
kernel/irq/irqdesc.c:207: warning: assignment makes pointer from integer without a cast
kernel/irq/irqdesc.c: In function ‘irq_get_next_irq’:
kernel/irq/irqdesc.c:346: error: implicit declaration of function ‘find_next_bit_set’
kernel/irq/irqdesc.c:347: error: implicit declaration of function ‘raw_spin_unlock_irqsave’
kernel/irq/irqdesc.c: In function ‘kstat_irqs_cpu’:
kernel/irq/irqdesc.c:369: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
kernel/irq/irqdesc.c:374: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
kernel/irq/irqdesc.c:377: error: expected ‘{’ at end of input
make[1]: *** [kernel/irq/irqdesc.o] Error 1

Yinghai

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-01  5:54 ` Yinghai Lu
@ 2010-10-01  5:54   ` Yinghai Lu
  2010-10-01 20:35   ` Thomas Gleixner
  1 sibling, 0 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-01  5:54 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Grant Likely, Eric W. Biederman

On 09/30/2010 04:14 PM, Thomas Gleixner wrote:
> The following patch series cleans up and mostly reimplements the core
> sparse irq implementation and sanitizes the most complex (ab)user:
> arch/x86
> 
> The series is based on the previous rework of irq chip functions which
> is available at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core
> 
> A combined throwaway git repository with all the following patches on top of
> tip/irq/core is available at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git
> 
> The overall changes are (full changelog below):
>     56 files changed, 1229 insertions(+), 1682 deletions(-)
> 
> The series consists of 3 parts:
> 
>     - cleanup of kernel/irq code and implementation of new allocator
>     - conversion of x86 to new irq_chip functions and new allocator
>     - trivial cleanup of the remaining users and removal of the old stuff
> 
> It's fully bisectable and survived a night of testing in my testfarm.

  CC      kernel/irq/irqdesc.o
kernel/irq/irqdesc.c:123: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘static’
kernel/irq/irqdesc.c: In function ‘alloc_descs’:
kernel/irq/irqdesc.c:176: error: implicit declaration of function ‘alloc_desc’
kernel/irq/irqdesc.c:176: warning: assignment makes pointer from integer without a cast
kernel/irq/irqdesc.c: In function ‘early_irq_init’:
kernel/irq/irqdesc.c:207: warning: assignment makes pointer from integer without a cast
kernel/irq/irqdesc.c: In function ‘irq_get_next_irq’:
kernel/irq/irqdesc.c:346: error: implicit declaration of function ‘find_next_bit_set’
kernel/irq/irqdesc.c:347: error: implicit declaration of function ‘raw_spin_unlock_irqsave’
kernel/irq/irqdesc.c: In function ‘kstat_irqs_cpu’:
kernel/irq/irqdesc.c:369: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
kernel/irq/irqdesc.c:374: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
kernel/irq/irqdesc.c:377: error: expected ‘{’ at end of input
make[1]: *** [kernel/irq/irqdesc.o] Error 1

Yinghai

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-01  0:42   ` Benjamin Herrenschmidt
@ 2010-10-01 13:07     ` Thomas Gleixner
  2010-10-01 20:46       ` Benjamin Herrenschmidt
  2010-10-03 16:53       ` Eric W. Biederman
  0 siblings, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-01 13:07 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

On Fri, 1 Oct 2010, Benjamin Herrenschmidt wrote:

> On Thu, 2010-09-30 at 23:18 +0000, Thomas Gleixner wrote:
> > plain text document attachment (powerpc-use-new-allocator.patch)
> > Use the new functions and free the descriptor when the virq is
> > destroyed.
> 
> Looks ok as a first pass, but we should go further and replace the
> allocator we have in powerpc to use yours instead.
> 
> Then I should get rid of my big irq_map that maps virq to HW number &
> domain pointers and instead put those in the irq data. Any objection to
> me sticking some archdata there for that purpose ?

No, though if we can avoid another void pointer and have a sensible
data structure for it would be nice.
 
> That would make things much cleaner and in fact move one large step
> toward being able to make powerpc virq scheme generic, which seems to be
> a good idea from what I've heard :-)

Yep.

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-01  5:54 ` Yinghai Lu
  2010-10-01  5:54   ` Yinghai Lu
@ 2010-10-01 20:35   ` Thomas Gleixner
  1 sibling, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-01 20:35 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Grant Likely, Eric W. Biederman

[-- Attachment #1: Type: TEXT/PLAIN, Size: 398 bytes --]

On Thu, 30 Sep 2010, Yinghai Lu wrote:
> On 09/30/2010 04:14 PM, Thomas Gleixner wrote:
> kernel/irq/irqdesc.c:374: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
> kernel/irq/irqdesc.c:377: error: expected ‘{’ at end of input
> make[1]: *** [kernel/irq/irqdesc.o] Error 1

Yeah, I fat fingered the queue in the last moment :( Fixing the mess right now.

Thanks,

	tglx
e 

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

* Re: [patch 14/47] genirq: Implement a sane sparse_irq allocator
  2010-10-01  5:28   ` Yinghai Lu
@ 2010-10-01 20:36     ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-01 20:36 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Grant Likely, Eric W. Biederman

On Thu, 30 Sep 2010, Yinghai Lu wrote:
> On 09/30/2010 04:15 PM, Thomas Gleixner wrote:
> > +static inline int
> > +irq_alloc_desc_at(unsigned int at, int node)
> > +{
> > +	return irq_alloc_descs(at, 0, 1, node);
> 
> need to change to 
> 
> 	return irq_alloc_descs(at, at, 1, node);

Good point. Fixed.

Thanks,

	tglx

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-01 13:07     ` Thomas Gleixner
@ 2010-10-01 20:46       ` Benjamin Herrenschmidt
  2010-10-01 21:11         ` Grant Likely
  2010-10-03 16:53       ` Eric W. Biederman
  1 sibling, 1 reply; 158+ messages in thread
From: Benjamin Herrenschmidt @ 2010-10-01 20:46 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely, Eric W. Biederman

On Fri, 2010-10-01 at 15:07 +0200, Thomas Gleixner wrote:
> On Fri, 1 Oct 2010, Benjamin Herrenschmidt wrote:
> 
> > On Thu, 2010-09-30 at 23:18 +0000, Thomas Gleixner wrote:
> > > plain text document attachment (powerpc-use-new-allocator.patch)
> > > Use the new functions and free the descriptor when the virq is
> > > destroyed.
> > 
> > Looks ok as a first pass, but we should go further and replace the
> > allocator we have in powerpc to use yours instead.
> > 
> > Then I should get rid of my big irq_map that maps virq to HW number &
> > domain pointers and instead put those in the irq data. Any objection to
> > me sticking some archdata there for that purpose ?
> 
> No, though if we can avoid another void pointer and have a sensible
> data structure for it would be nice.

Yes, I'm thinking about an arch defined structure like I did for struct
device.

Cheers,
Ben.

> > That would make things much cleaner and in fact move one large step
> > toward being able to make powerpc virq scheme generic, which seems to be
> > a good idea from what I've heard :-)
> 
> Yep.
> 
> Thanks,
> 
> 	tglx
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-01 20:46       ` Benjamin Herrenschmidt
@ 2010-10-01 21:11         ` Grant Likely
  2010-10-01 21:17           ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 158+ messages in thread
From: Grant Likely @ 2010-10-01 21:11 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Eric W. Biederman

On Sat, Oct 2, 2010 at 5:46 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Fri, 2010-10-01 at 15:07 +0200, Thomas Gleixner wrote:
>> On Fri, 1 Oct 2010, Benjamin Herrenschmidt wrote:
>>
>> > On Thu, 2010-09-30 at 23:18 +0000, Thomas Gleixner wrote:
>> > > plain text document attachment (powerpc-use-new-allocator.patch)
>> > > Use the new functions and free the descriptor when the virq is
>> > > destroyed.
>> >
>> > Looks ok as a first pass, but we should go further and replace the
>> > allocator we have in powerpc to use yours instead.
>> >
>> > Then I should get rid of my big irq_map that maps virq to HW number &
>> > domain pointers and instead put those in the irq data. Any objection to
>> > me sticking some archdata there for that purpose ?
>>
>> No, though if we can avoid another void pointer and have a sensible
>> data structure for it would be nice.
>
> Yes, I'm thinking about an arch defined structure like I did for struct
> device.

Before doing that, I'd like to see what data members are still needed.
 The powerpc use-case is quite sane, and it may turn out to be common
code after all.  I certainly want to port the PowerPC functionality to
ARM.

g.

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-01 21:11         ` Grant Likely
@ 2010-10-01 21:17           ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 158+ messages in thread
From: Benjamin Herrenschmidt @ 2010-10-01 21:17 UTC (permalink / raw)
  To: Grant Likely
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Eric W. Biederman

On Sat, 2010-10-02 at 06:11 +0900, Grant Likely wrote:
> 
> Before doing that, I'd like to see what data members are still needed.
>  The powerpc use-case is quite sane, and it may turn out to be common
> code after all.  I certainly want to port the PowerPC functionality to
> ARM. 

Pretty much the host (domain) pointer and the associated HW number. The
later might want to be an arch typedef tho (on ppc64 at least it wants
to be 64-bit), and that's it.

Cheers,
Ben.

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

* Re: [patch 16/47] genirq: Implement sane enumeration
  2010-09-30 23:15 ` [patch 16/47] genirq: Implement sane enumeration Thomas Gleixner
  2010-09-30 23:15   ` Thomas Gleixner
@ 2010-10-03 10:55   ` Grant Likely
  1 sibling, 0 replies; 158+ messages in thread
From: Grant Likely @ 2010-10-03 10:55 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Eric W. Biederman

On Thu, Sep 30, 2010 at 11:15:51PM -0000, Thomas Gleixner wrote:
> Use the allocator bitmap to lookup active interrupts.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
[...]
> Index: linux-2.6-tip/kernel/irq/irqdesc.c
> ===================================================================
> --- linux-2.6-tip.orig/kernel/irq/irqdesc.c
> +++ linux-2.6-tip/kernel/irq/irqdesc.c
> @@ -470,6 +470,23 @@ err:
>  	return ret;
>  }
>  
> +/**
> + * irq_get_next_irq - get next allocated irq number
> + * @offset:	where to start the search
> + *
> + * Returns next irq number after offset or nr_irqs if none is found.
> + */
> +unsigned int irq_get_next_irq(unsigned int offset)
> +{
> +	unsigned long flags;
> +	unsigned int res;
> +
> +	raw_spin_lock_irqsave(&sparse_irq_lock, flags);
> +	res = find_next_bit_set(allocated_irqs, nr_irqs, offset);
> +	raw_spin_unlock_irqsave(&sparse_irq_lock, flags);
> +	return res;
> +}

Where is the bitmap defined?  I don't see it in the queue; but I also
notice that patch #14 is missing.  Is it defined there?

g.

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

* Re: [patch 00/47] Sparse irq rework
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (48 preceding siblings ...)
  2010-10-01  5:54 ` Yinghai Lu
@ 2010-10-03 11:23 ` Grant Likely
  2010-10-03 11:29   ` Russell King - ARM Linux
  2010-10-03 16:41 ` Eric W. Biederman
  50 siblings, 1 reply; 158+ messages in thread
From: Grant Likely @ 2010-10-03 11:23 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Eric W. Biederman

On Thu, Sep 30, 2010 at 11:14:27PM -0000, Thomas Gleixner wrote:
> The following patch series cleans up and mostly reimplements the core
> sparse irq implementation and sanitizes the most complex (ab)user:
> arch/x86

Hoy Thomas,

patches 1-13 & 15 all look fine to me.  Feel free to add my Acked-by:
line.

Patch 14 seems to be missing, and by inference it appears that the
all important new allocator is added by patch 14.  All of the rest of
the series seems to be fine, but I'm forced to make assumptions about
what the new allocator looks like, so I cannot be positive.

Cheers,
g.


> 
> The series is based on the previous rework of irq chip functions which
> is available at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core
> 
> A combined throwaway git repository with all the following patches on top of
> tip/irq/core is available at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git
> 
> The overall changes are (full changelog below):
>     56 files changed, 1229 insertions(+), 1682 deletions(-)
> 
> The series consists of 3 parts:
> 
>     - cleanup of kernel/irq code and implementation of new allocator
>     - conversion of x86 to new irq_chip functions and new allocator
>     - trivial cleanup of the remaining users and removal of the old stuff
> 
> It's fully bisectable and survived a night of testing in my testfarm.
> 
> There are two bugfix patches (1/47, 2/47), which resulted of staring
> at that maze for way too long. They are targeted for mainline urgent,
> but I left them in the queue to avoid further churn.
> 
> 
> Rationale:
> ----------
> 
> The current sparse_irq allocator has several short comings due to
> failures in the design or the lack of it:
> 
>  - Requires iteration over the number of active irqs to find a free slot
>    Some architectures have grown their own workarounds for this.
> 
>  - Freeing of irq descriptors is not possible
> 
>  - Racy between create_irq_nr and destroy_irq plugged by horrible
>    callbacks
> 
>  - Migration of active irq descriptors is not possible
> 
>  - No bulk allocation of irq ranges
> 
> Aside of that the sparse irq design failure caused that we sprinkled
> irq_desc references all over the place outside of kernel/irq/. That
> makes it extremly hard to do the core changes which are necessary to
> do further cleanups and improvements like he migration of active irq
> descriptors. The arch code needs only to know about the irq chip and
> the data associated with the irq. The irq descriptor itself is solely
> a core code data structure.
> 
> The reason is that with the non sparse code access to the irq data was
> just array pointer math and most code (aside of the old __do_IRQ()
> users) used the provided accessor functions.
> 
> With sparse it requires a radix tree lookup, which casued performance
> problems. Instead of tackling the problem at the chip function level
> and handing down a pointer to the associated data instead of an irq
> number, the low level code acquired a reference to irq_desc and
> populated that all over the place. Yeah, it's easier than doing a full
> cleanup and a sensible migration path, but the resulting mess is just
> disgusting.
> 
> The previous chip functions series on which this series is based is
> addressing this issue on the chip level side by handing down the
> associated interrupt data instead of the interruut number. The x86
> cleanup is making use of it.
> 
> 
> New implementation:
> -------------------
> 
> I've implemented a sane allocator which fixes the above short comings
> (though migration of active descriptors still needs a full tree wide
> cleanup of the direct and mostly unlocked access to irq_desc).
> 
> The new allocator still uses a radix_tree, but uses a bitmap for
> keeping track of allocated irq numbers. That results in:
> 
>  - Fast lookup of a free slot
> 
>  - The removal of disposed descriptors (destroy_irq())
> 
>  - Prevents the create/destroy race
> 
>  - Bulk (de)allocation of consecutive irq ranges
> 
>  - Migration of life descriptors after further cleanups
> 
> The bitmap is also used in the SPARSE_IRQ=n case for lookup and
> raceless (de)allocation of irq numbers. So it removes the requirement
> for looping through the descriptor array to find slots.
> 
> Right now it uses sparse_irq_lock to protect the bitmap and the radix
> tree, but after cleaning up all users we should be able to convert
> that to a mutex and switch the radix_tree and descriptor allocations
> to GFP_KERNEL.
> 
> Note, that I wanted to use lib/idr.c code for it, but idr/ida lacks
> bulk allocation and a bitmap based iterator function, so I decided to
> open code it for now. That's definitely something which could be
> useful for others as well, but I have only a limited coding power.
> 
> There are some trivial preparatory patches as well, which touch places
> all over the tree to make the conversion and cleanup simpler.
> 
> 
> Full conversion and clean up of x86:
> ------------------------------------
> 
> I spent quite a time to come up with a sane and splitable concept,
> which does not reach out into drivers/pci/[msi|ht|dmar] and whatever.
> 
> But that's simply impossible because everything is twisted together
> mainly by optimization hacks done over time. (i.e. handing down
> irq_desc to low level msi functions instead of irq_desc.msi_desc would
> have kept the mess confined to x86).
> 
> So I went there and started to convert stuff piece by piece in x86 and
> added the drivers/pci/* fixes as separate patches along the way. Not
> nice, but it turned out to be the only way which avoided even more
> churn.
> 
> 
> Cleanup of leftovers:
> ---------------------
> 
> The leftovers (powerpc, arm, sh) have been converted with minimal
> effort to allow the removal of the core code gunk. Not urgent stuff
> 
> There are more things which might be cleaned up, but that's not the
> scope of this work.
> 
> 
> Further work:
> -------------
> 
>  - Cleanup the irq_desc references all over the tree, which should become
>    easier after the remaining __do_IRQ() users are gone.
> 
>  - Implement migration of active irq descriptors
> 
>  - Implement node bound late allocation of low level irq vectors which
>    solves an existing (SGI) problem on large machines.
> 
> 
> How to merge:
> -------------
> 
> It needs:
> 
>    - ack to the new allocator design
> 
>    - ack to merge the whole arch/!x86 and driver related cleanups
>      along with the core changes and the x86 cleanup
> 
> 
> Thoughts ?
> 
> Thanks,
> 
> 	tglx
> ---
> 
>  b/Documentation/DocBook/genericirq.tmpl  |   82 +--
>  b/arch/arm/include/asm/hw_irq.h          |    2 
>  b/arch/arm/kernel/irq.c                  |   30 -
>  b/arch/arm/mach-davinci/gpio.c           |    2 
>  b/arch/arm/mach-iop13xx/msi.c            |    8 
>  b/arch/ia64/kernel/msi_ia64.c            |    8 
>  b/arch/ia64/sn/kernel/msi_sn.c           |    4 
>  b/arch/powerpc/include/asm/hw_irq.h      |    2 
>  b/arch/powerpc/kernel/irq.c              |   32 -
>  b/arch/powerpc/platforms/cell/axon_msi.c |    6 
>  b/arch/powerpc/platforms/pseries/xics.c  |    2 
>  b/arch/powerpc/sysdev/fsl_msi.c          |    4 
>  b/arch/powerpc/sysdev/mpic_pasemi_msi.c  |   22 
>  b/arch/powerpc/sysdev/mpic_u3msi.c       |   16 
>  b/arch/sh/kernel/cpu/irq/ipr.c           |    6 
>  b/arch/sh/kernel/irq.c                   |    2 
>  b/arch/sparc/kernel/pci_msi.c            |    8 
>  b/arch/x86/Kconfig                       |    1 
>  b/arch/x86/include/asm/hpet.h            |   10 
>  b/arch/x86/include/asm/hw_irq.h          |    7 
>  b/arch/x86/include/asm/i8259.h           |    2 
>  b/arch/x86/kernel/apb_timer.c            |   54 --
>  b/arch/x86/kernel/apic/io_apic.c         |  812 +++++++++++--------------------
>  b/arch/x86/kernel/apic/nmi.c             |    2 
>  b/arch/x86/kernel/hpet.c                 |   18 
>  b/arch/x86/kernel/i8259.c                |   63 +-
>  b/arch/x86/kernel/irqinit.c              |   17 
>  b/arch/x86/kernel/smpboot.c              |    4 
>  b/arch/x86/kernel/uv_irq.c               |   55 --
>  b/arch/x86/kernel/visws_quirks.c         |  140 +----
>  b/arch/x86/lguest/boot.c                 |   18 
>  b/drivers/isdn/hisax/config.c            |   18 
>  b/drivers/isdn/hisax/hisax.h             |    1 
>  b/drivers/pci/dmar.c                     |    8 
>  b/drivers/pci/htirq.c                    |   22 
>  b/drivers/pci/msi.c                      |   38 -
>  b/drivers/sh/intc.c                      |   37 -
>  b/drivers/xen/events.c                   |   23 
>  b/include/linux/dmar.h                   |    5 
>  b/include/linux/htirq.h                  |    5 
>  b/include/linux/interrupt.h              |    3 
>  b/include/linux/irq.h                    |  195 +++----
>  b/include/linux/irqnr.h                  |    5 
>  b/include/linux/lockdep.h                |    8 
>  b/include/linux/msi.h                    |   13 
>  b/init/main.c                            |    1 
>  b/kernel/irq/Kconfig                     |    5 
>  b/kernel/irq/Makefile                    |    3 
>  b/kernel/irq/chip.c                      |  138 -----
>  b/kernel/irq/dummychip.c                 |   67 ++
>  b/kernel/irq/handle.c                    |  344 -------------
>  b/kernel/irq/internals.h                 |   11 
>  b/kernel/irq/irqdesc.c                   |  377 ++++++++++++++
>  b/kernel/irq/proc.c                      |   18 
>  b/kernel/softirq.c                       |    7 
>  kernel/irq/numa_migrate.c                |  120 ----
>  56 files changed, 1229 insertions(+), 1682 deletions(-)
> 
> 
> 

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 11:23 ` Grant Likely
@ 2010-10-03 11:29   ` Russell King - ARM Linux
  2010-10-03 11:29     ` Russell King - ARM Linux
  2010-10-03 11:57     ` Grant Likely
  0 siblings, 2 replies; 158+ messages in thread
From: Russell King - ARM Linux @ 2010-10-03 11:29 UTC (permalink / raw)
  To: Grant Likely
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Eric W. Biederman

On Sun, Oct 03, 2010 at 05:23:12AM -0600, Grant Likely wrote:
> On Thu, Sep 30, 2010 at 11:14:27PM -0000, Thomas Gleixner wrote:
> > The following patch series cleans up and mostly reimplements the core
> > sparse irq implementation and sanitizes the most complex (ab)user:
> > arch/x86
> 
> Hoy Thomas,
> 
> patches 1-13 & 15 all look fine to me.  Feel free to add my Acked-by:
> line.
> 
> Patch 14 seems to be missing, and by inference it appears that the
> all important new allocator is added by patch 14.  All of the rest of
> the series seems to be fine, but I'm forced to make assumptions about
> what the new allocator looks like, so I cannot be positive.

Patch 14 was present, you were even CC'd on it.

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 11:29   ` Russell King - ARM Linux
@ 2010-10-03 11:29     ` Russell King - ARM Linux
  2010-10-03 11:57     ` Grant Likely
  1 sibling, 0 replies; 158+ messages in thread
From: Russell King - ARM Linux @ 2010-10-03 11:29 UTC (permalink / raw)
  To: Grant Likely
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Eric W. Biederman

On Sun, Oct 03, 2010 at 05:23:12AM -0600, Grant Likely wrote:
> On Thu, Sep 30, 2010 at 11:14:27PM -0000, Thomas Gleixner wrote:
> > The following patch series cleans up and mostly reimplements the core
> > sparse irq implementation and sanitizes the most complex (ab)user:
> > arch/x86
> 
> Hoy Thomas,
> 
> patches 1-13 & 15 all look fine to me.  Feel free to add my Acked-by:
> line.
> 
> Patch 14 seems to be missing, and by inference it appears that the
> all important new allocator is added by patch 14.  All of the rest of
> the series seems to be fine, but I'm forced to make assumptions about
> what the new allocator looks like, so I cannot be positive.

Patch 14 was present, you were even CC'd on it.

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 11:29   ` Russell King - ARM Linux
  2010-10-03 11:29     ` Russell King - ARM Linux
@ 2010-10-03 11:57     ` Grant Likely
  2010-10-03 13:48       ` Thomas Gleixner
  1 sibling, 1 reply; 158+ messages in thread
From: Grant Likely @ 2010-10-03 11:57 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Eric W. Biederman

On Sun, Oct 3, 2010 at 5:29 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Sun, Oct 03, 2010 at 05:23:12AM -0600, Grant Likely wrote:
>> On Thu, Sep 30, 2010 at 11:14:27PM -0000, Thomas Gleixner wrote:
>> > The following patch series cleans up and mostly reimplements the core
>> > sparse irq implementation and sanitizes the most complex (ab)user:
>> > arch/x86
>>
>> Hoy Thomas,
>>
>> patches 1-13 & 15 all look fine to me.  Feel free to add my Acked-by:
>> line.
>>
>> Patch 14 seems to be missing, and by inference it appears that the
>> all important new allocator is added by patch 14.  All of the rest of
>> the series seems to be fine, but I'm forced to make assumptions about
>> what the new allocator looks like, so I cannot be positive.
>
> Patch 14 was present, you were even CC'd on it.

Hmmm... found it now.  I'm not sure what happened there, but I
couldn't find it the first time I looked.  Most likely it is a PEBKAC
failure.  Sorry for the noise.

Okay, patch 14 looks good to me too (including Yinghai's comment).
The new allocator seems sane, and I didn't see any obvious errors in
patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
able to carve out some time to do so early this week.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 11:57     ` Grant Likely
@ 2010-10-03 13:48       ` Thomas Gleixner
  2010-10-05 10:22         ` Thomas Gleixner
  0 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-03 13:48 UTC (permalink / raw)
  To: Grant Likely
  Cc: Russell King - ARM Linux, LKML, linux-arch, Linus Torvalds,
	Andrew Morton, x86, Peter Zijlstra, Benjamin Herrenschmidt,
	Paul Mundt, David Woodhouse, Jesse Barnes, Yinghai Lu,
	Eric W. Biederman

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1493 bytes --]

On Sun, 3 Oct 2010, Grant Likely wrote:

> On Sun, Oct 3, 2010 at 5:29 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Sun, Oct 03, 2010 at 05:23:12AM -0600, Grant Likely wrote:
> >> On Thu, Sep 30, 2010 at 11:14:27PM -0000, Thomas Gleixner wrote:
> >> > The following patch series cleans up and mostly reimplements the core
> >> > sparse irq implementation and sanitizes the most complex (ab)user:
> >> > arch/x86
> >>
> >> Hoy Thomas,
> >>
> >> patches 1-13 & 15 all look fine to me.  Feel free to add my Acked-by:
> >> line.
> >>
> >> Patch 14 seems to be missing, and by inference it appears that the
> >> all important new allocator is added by patch 14.  All of the rest of
> >> the series seems to be fine, but I'm forced to make assumptions about
> >> what the new allocator looks like, so I cannot be positive.
> >
> > Patch 14 was present, you were even CC'd on it.
> 
> Hmmm... found it now.  I'm not sure what happened there, but I
> couldn't find it the first time I looked.  Most likely it is a PEBKAC
> failure.  Sorry for the noise.
> 
> Okay, patch 14 looks good to me too (including Yinghai's comment).
> The new allocator seems sane, and I didn't see any obvious errors in
> patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
> able to carve out some time to do so early this week.

Wait until I pushed out a fixed tree. In meantime I found out how I
managed to screw up the quilt series :(

Will post, once it's ready.

Thanks,

	tglx

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

* Re: [patch 20/47] x86: Remove useless reinitialization of irq descriptors
  2010-09-30 23:16 ` [patch 20/47] x86: Remove useless reinitialization of irq descriptors Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
@ 2010-10-03 15:21   ` Eric W. Biederman
  2010-10-03 18:26     ` Thomas Gleixner
  1 sibling, 1 reply; 158+ messages in thread
From: Eric W. Biederman @ 2010-10-03 15:21 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

Thomas Gleixner <tglx@linutronix.de> writes:

> The descriptors are already initialized in exaclty this way.

They aren't only status is initialized exactly that way.

> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  arch/x86/kernel/irqinit.c |   17 ++++-------------
>  1 file changed, 4 insertions(+), 13 deletions(-)
>
> Index: linux-2.6-tip/arch/x86/kernel/irqinit.c
> ===================================================================
> --- linux-2.6-tip.orig/arch/x86/kernel/irqinit.c
> +++ linux-2.6-tip/arch/x86/kernel/irqinit.c
> @@ -100,6 +100,8 @@ int vector_used_by_percpu_irq(unsigned i
>  
>  void __init init_ISA_irqs(void)
>  {
> +	struct irq_chip *chip = legacy_pic->chip;
> +	const char *name = chip->name;
>  	int i;
>  
>  #if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
> @@ -107,19 +109,8 @@ void __init init_ISA_irqs(void)
>  #endif
>  	legacy_pic->init(0);
>  
> -	/*
> -	 * 16 old-style INTA-cycle interrupts:
> -	 */

Why delete the comment here?

> -	for (i = 0; i < legacy_pic->nr_legacy_irqs; i++) {
> -		struct irq_desc *desc = irq_to_desc(i);
> -
> -		desc->status = IRQ_DISABLED;
> -		desc->action = NULL;
> -		desc->depth = 1;
> -
> -		set_irq_chip_and_handler_name(i, &i8259A_chip,
> -					      handle_level_irq, "XT");
> -	}
> +	for (i = 0; i < legacy_pic->nr_legacy_irqs; i++)
> +		set_irq_chip_and_handler_name(i, chip, handle_level_irq, name);
>  }
>  
>  void __init init_IRQ(void)

Eric

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

* Re: [patch 00/47] Sparse irq rework
  2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
                   ` (49 preceding siblings ...)
  2010-10-03 11:23 ` Grant Likely
@ 2010-10-03 16:41 ` Eric W. Biederman
  2010-10-03 16:41   ` Eric W. Biederman
  2010-10-03 19:16   ` Thomas Gleixner
  50 siblings, 2 replies; 158+ messages in thread
From: Eric W. Biederman @ 2010-10-03 16:41 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

Thomas Gleixner <tglx@linutronix.de> writes:

> The following patch series cleans up and mostly reimplements the core
> sparse irq implementation and sanitizes the most complex (ab)user:
> arch/x86

Overall this patchset looks pretty sane, but I don't see a clear picture
of what everything is going to look like when the dust settles.

> The series is based on the previous rework of irq chip functions which
> is available at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core
>
> A combined throwaway git repository with all the following patches on top of
> tip/irq/core is available at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git
>
> The overall changes are (full changelog below):
>     56 files changed, 1229 insertions(+), 1682 deletions(-)
>
> The series consists of 3 parts:
>
>     - cleanup of kernel/irq code and implementation of new allocator
>     - conversion of x86 to new irq_chip functions and new allocator
>     - trivial cleanup of the remaining users and removal of the old stuff
>
> It's fully bisectable and survived a night of testing in my testfarm.
>
> There are two bugfix patches (1/47, 2/47), which resulted of staring
> at that maze for way too long. They are targeted for mainline urgent,
> but I left them in the queue to avoid further churn.
>
>
> Rationale:
> ----------
>
> The current sparse_irq allocator has several short comings due to
> failures in the design or the lack of it:
>
>  - Requires iteration over the number of active irqs to find a free slot
>    Some architectures have grown their own workarounds for this.
>
>  - Freeing of irq descriptors is not possible
>
>  - Racy between create_irq_nr and destroy_irq plugged by horrible
>    callbacks
>
>  - Migration of active irq descriptors is not possible

I believe you have distored the design when aiming for migration
of active irq descriptors (which you have not even implemented yet).

How do you plan to remove the radix tree lookup from the irq
handling path?

On x86 the obvious implementation is to store a pointer to the irq_desc
in our 256 entry per cpu tables.  Please implement this and see how
it affects the design.  The code is pretty trivial.

From what I can see of your migration plan it seems incompatible with
removing the radix tree look up in the path to generic_handle_irq().

>  - No bulk allocation of irq ranges

Where is that a short coming?

> Aside of that the sparse irq design failure caused that we sprinkled
> irq_desc references all over the place outside of kernel/irq/. That
> makes it extremly hard to do the core changes which are necessary to
> do further cleanups and improvements like he migration of active irq
> descriptors. The arch code needs only to know about the irq chip and
> the data associated with the irq. The irq descriptor itself is solely
> a core code data structure.

If by core you mean arch code irq handling code certainly and
msi fits that bill.

> The reason is that with the non sparse code access to the irq data was
> just array pointer math and most code (aside of the old __do_IRQ()
> users) used the provided accessor functions.
>
> With sparse it requires a radix tree lookup, which casued performance
> problems. Instead of tackling the problem at the chip function level
> and handing down a pointer to the associated data instead of an irq
> number, the low level code acquired a reference to irq_desc and
> populated that all over the place. Yeah, it's easier than doing a full
> cleanup and a sensible migration path, but the resulting mess is just
> disgusting.
>
> The previous chip functions series on which this series is based is
> addressing this issue on the chip level side by handing down the
> associated interrupt data instead of the interruut number. The x86
> cleanup is making use of it.

And always handing down the data structure so you can do the same
thing with sparse irq enabled or not is a much needed code cleanup.


> New implementation:
> -------------------
>
> I've implemented a sane allocator which fixes the above short comings
> (though migration of active descriptors still needs a full tree wide
> cleanup of the direct and mostly unlocked access to irq_desc).
>
> The new allocator still uses a radix_tree, but uses a bitmap for
> keeping track of allocated irq numbers. That results in:

I don't know that I have a problem with this but I do have a problem
with using a bitmap.  A lot of the kernels irq usage has been distored
because we use a compact array, that we cannot grow over time.  Using a
bitmap here essentially removes 90% of the point of sparse irq.  The
ability to remove a hard coded NR_IRQS from the kernel.

>  - Fast lookup of a free slot
>
>  - The removal of disposed descriptors (destroy_irq())
>
>  - Prevents the create/destroy race
>
>  - Bulk (de)allocation of consecutive irq ranges
>
>  - Migration of life descriptors after further cleanups

You should be able to do all of that by walking your radix tree in the
sparse irq case.


> Full conversion and clean up of x86:
> ------------------------------------
>
> I spent quite a time to come up with a sane and splitable concept,
> which does not reach out into drivers/pci/[msi|ht|dmar] and whatever.
>
> But that's simply impossible because everything is twisted together
> mainly by optimization hacks done over time. (i.e. handing down
> irq_desc to low level msi functions instead of irq_desc.msi_desc would
> have kept the mess confined to x86).

Those files provide the genirq irq chip implementation especially
drivers/pci/msi.c.  Of course they will do what every other irq_chip
implementation does to get access to data.  There is an unpleasant
difference between which generic irq data field htirq.c uses and msi.c
which may be worth cleaning up.  But otherwise I don't see any
fundamental problems.

The big difference is those are the irq controllers that we have code
for that is not necessarily architecture specific.

> So I went there and started to convert stuff piece by piece in x86 and
> added the drivers/pci/* fixes as separate patches along the way. Not
> nice, but it turned out to be the only way which avoided even more
> churn.

You should be able to convert msi.c and company directly to using
irq_data immediately following your previous patchset shouldn't you.
Perhaps with two flavors of helper functions during the transition
to passing irq_data everywhere.

I don't see any code in the msi code is arch specific or sparse irq
specific.

> Further work:
> -------------
>
>  - Cleanup the irq_desc references all over the tree, which should become
>    easier after the remaining __do_IRQ() users are gone.
>
>  - Implement migration of active irq descriptors
>
>  - Implement node bound late allocation of low level irq vectors which
>    solves an existing (SGI) problem on large machines.
>
>
> How to merge:
> -------------
>
> It needs:
>
>    - ack to the new allocator design
>
>    - ack to merge the whole arch/!x86 and driver related cleanups
>      along with the core changes and the x86 cleanup


Eric

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 16:41 ` Eric W. Biederman
@ 2010-10-03 16:41   ` Eric W. Biederman
  2010-10-03 19:16   ` Thomas Gleixner
  1 sibling, 0 replies; 158+ messages in thread
From: Eric W. Biederman @ 2010-10-03 16:41 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

Thomas Gleixner <tglx@linutronix.de> writes:

> The following patch series cleans up and mostly reimplements the core
> sparse irq implementation and sanitizes the most complex (ab)user:
> arch/x86

Overall this patchset looks pretty sane, but I don't see a clear picture
of what everything is going to look like when the dust settles.

> The series is based on the previous rework of irq chip functions which
> is available at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core
>
> A combined throwaway git repository with all the following patches on top of
> tip/irq/core is available at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git
>
> The overall changes are (full changelog below):
>     56 files changed, 1229 insertions(+), 1682 deletions(-)
>
> The series consists of 3 parts:
>
>     - cleanup of kernel/irq code and implementation of new allocator
>     - conversion of x86 to new irq_chip functions and new allocator
>     - trivial cleanup of the remaining users and removal of the old stuff
>
> It's fully bisectable and survived a night of testing in my testfarm.
>
> There are two bugfix patches (1/47, 2/47), which resulted of staring
> at that maze for way too long. They are targeted for mainline urgent,
> but I left them in the queue to avoid further churn.
>
>
> Rationale:
> ----------
>
> The current sparse_irq allocator has several short comings due to
> failures in the design or the lack of it:
>
>  - Requires iteration over the number of active irqs to find a free slot
>    Some architectures have grown their own workarounds for this.
>
>  - Freeing of irq descriptors is not possible
>
>  - Racy between create_irq_nr and destroy_irq plugged by horrible
>    callbacks
>
>  - Migration of active irq descriptors is not possible

I believe you have distored the design when aiming for migration
of active irq descriptors (which you have not even implemented yet).

How do you plan to remove the radix tree lookup from the irq
handling path?

On x86 the obvious implementation is to store a pointer to the irq_desc
in our 256 entry per cpu tables.  Please implement this and see how
it affects the design.  The code is pretty trivial.

From what I can see of your migration plan it seems incompatible with
removing the radix tree look up in the path to generic_handle_irq().

>  - No bulk allocation of irq ranges

Where is that a short coming?

> Aside of that the sparse irq design failure caused that we sprinkled
> irq_desc references all over the place outside of kernel/irq/. That
> makes it extremly hard to do the core changes which are necessary to
> do further cleanups and improvements like he migration of active irq
> descriptors. The arch code needs only to know about the irq chip and
> the data associated with the irq. The irq descriptor itself is solely
> a core code data structure.

If by core you mean arch code irq handling code certainly and
msi fits that bill.

> The reason is that with the non sparse code access to the irq data was
> just array pointer math and most code (aside of the old __do_IRQ()
> users) used the provided accessor functions.
>
> With sparse it requires a radix tree lookup, which casued performance
> problems. Instead of tackling the problem at the chip function level
> and handing down a pointer to the associated data instead of an irq
> number, the low level code acquired a reference to irq_desc and
> populated that all over the place. Yeah, it's easier than doing a full
> cleanup and a sensible migration path, but the resulting mess is just
> disgusting.
>
> The previous chip functions series on which this series is based is
> addressing this issue on the chip level side by handing down the
> associated interrupt data instead of the interruut number. The x86
> cleanup is making use of it.

And always handing down the data structure so you can do the same
thing with sparse irq enabled or not is a much needed code cleanup.


> New implementation:
> -------------------
>
> I've implemented a sane allocator which fixes the above short comings
> (though migration of active descriptors still needs a full tree wide
> cleanup of the direct and mostly unlocked access to irq_desc).
>
> The new allocator still uses a radix_tree, but uses a bitmap for
> keeping track of allocated irq numbers. That results in:

I don't know that I have a problem with this but I do have a problem
with using a bitmap.  A lot of the kernels irq usage has been distored
because we use a compact array, that we cannot grow over time.  Using a
bitmap here essentially removes 90% of the point of sparse irq.  The
ability to remove a hard coded NR_IRQS from the kernel.

>  - Fast lookup of a free slot
>
>  - The removal of disposed descriptors (destroy_irq())
>
>  - Prevents the create/destroy race
>
>  - Bulk (de)allocation of consecutive irq ranges
>
>  - Migration of life descriptors after further cleanups

You should be able to do all of that by walking your radix tree in the
sparse irq case.


> Full conversion and clean up of x86:
> ------------------------------------
>
> I spent quite a time to come up with a sane and splitable concept,
> which does not reach out into drivers/pci/[msi|ht|dmar] and whatever.
>
> But that's simply impossible because everything is twisted together
> mainly by optimization hacks done over time. (i.e. handing down
> irq_desc to low level msi functions instead of irq_desc.msi_desc would
> have kept the mess confined to x86).

Those files provide the genirq irq chip implementation especially
drivers/pci/msi.c.  Of course they will do what every other irq_chip
implementation does to get access to data.  There is an unpleasant
difference between which generic irq data field htirq.c uses and msi.c
which may be worth cleaning up.  But otherwise I don't see any
fundamental problems.

The big difference is those are the irq controllers that we have code
for that is not necessarily architecture specific.

> So I went there and started to convert stuff piece by piece in x86 and
> added the drivers/pci/* fixes as separate patches along the way. Not
> nice, but it turned out to be the only way which avoided even more
> churn.

You should be able to convert msi.c and company directly to using
irq_data immediately following your previous patchset shouldn't you.
Perhaps with two flavors of helper functions during the transition
to passing irq_data everywhere.

I don't see any code in the msi code is arch specific or sparse irq
specific.

> Further work:
> -------------
>
>  - Cleanup the irq_desc references all over the tree, which should become
>    easier after the remaining __do_IRQ() users are gone.
>
>  - Implement migration of active irq descriptors
>
>  - Implement node bound late allocation of low level irq vectors which
>    solves an existing (SGI) problem on large machines.
>
>
> How to merge:
> -------------
>
> It needs:
>
>    - ack to the new allocator design
>
>    - ack to merge the whole arch/!x86 and driver related cleanups
>      along with the core changes and the x86 cleanup


Eric

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-01 13:07     ` Thomas Gleixner
  2010-10-01 20:46       ` Benjamin Herrenschmidt
@ 2010-10-03 16:53       ` Eric W. Biederman
  2010-10-03 16:53         ` Eric W. Biederman
                           ` (2 more replies)
  1 sibling, 3 replies; 158+ messages in thread
From: Eric W. Biederman @ 2010-10-03 16:53 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Benjamin Herrenschmidt, LKML, linux-arch, Linus Torvalds,
	Andrew Morton, x86, Peter Zijlstra, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

Thomas Gleixner <tglx@linutronix.de> writes:

>> That would make things much cleaner and in fact move one large step
>> toward being able to make powerpc virq scheme generic, which seems to be
>> a good idea from what I've heard :-)
>
> Yep.

I'm not certain about making the ppc virq scheme generic.  Maybe it is
just my distorted impression but I have the understanding that ppc irq
numbers mean nothing and are totally unstable whereas on x86 irq numbers
in general are stable (across kernel upgrades and changes in device
probe order) and the irq number has a useful hardware meaning.  Which
means you don't have to go through several layers of translation tables
to figure out which hardware pin you are talking about.

Eric

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-03 16:53       ` Eric W. Biederman
@ 2010-10-03 16:53         ` Eric W. Biederman
  2010-10-03 18:34         ` Thomas Gleixner
  2010-10-03 22:54         ` Benjamin Herrenschmidt
  2 siblings, 0 replies; 158+ messages in thread
From: Eric W. Biederman @ 2010-10-03 16:53 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Benjamin Herrenschmidt, LKML, linux-arch, Linus Torvalds,
	Andrew Morton, x86, Peter Zijlstra, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

Thomas Gleixner <tglx@linutronix.de> writes:

>> That would make things much cleaner and in fact move one large step
>> toward being able to make powerpc virq scheme generic, which seems to be
>> a good idea from what I've heard :-)
>
> Yep.

I'm not certain about making the ppc virq scheme generic.  Maybe it is
just my distorted impression but I have the understanding that ppc irq
numbers mean nothing and are totally unstable whereas on x86 irq numbers
in general are stable (across kernel upgrades and changes in device
probe order) and the irq number has a useful hardware meaning.  Which
means you don't have to go through several layers of translation tables
to figure out which hardware pin you are talking about.

Eric

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

* Re: [patch 20/47] x86: Remove useless reinitialization of irq descriptors
  2010-10-03 15:21   ` Eric W. Biederman
@ 2010-10-03 18:26     ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-03 18:26 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

On Sun, 3 Oct 2010, Eric W. Biederman wrote:

> Thomas Gleixner <tglx@linutronix.de> writes:
> 
> > The descriptors are already initialized in exaclty this way.
> 
> They aren't only status is initialized exactly that way.

Err.

SPARSE_IRQ=n:

struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
        [0 ... NR_IRQS-1] = {
                .status = IRQ_DISABLED,
		.chip = &no_irq_chip,
                .handle_irq = handle_bad_irq,
                .depth = 1,
                .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
        }
};

So action == NULL and depth == 1

SPARSE_IRQ=y:

allocates with kzalloc which makes action == NULL and depth is set in
the init function to 1.

That's true for mainline and after the rework as well.

Thanks,

	tglx

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-03 16:53       ` Eric W. Biederman
  2010-10-03 16:53         ` Eric W. Biederman
@ 2010-10-03 18:34         ` Thomas Gleixner
  2010-10-03 20:04           ` Thomas Gleixner
  2010-10-03 22:54         ` Benjamin Herrenschmidt
  2 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-03 18:34 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Benjamin Herrenschmidt, LKML, linux-arch, Linus Torvalds,
	Andrew Morton, x86, Peter Zijlstra, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

On Sun, 3 Oct 2010, Eric W. Biederman wrote:

> Thomas Gleixner <tglx@linutronix.de> writes:
> 
> >> That would make things much cleaner and in fact move one large step
> >> toward being able to make powerpc virq scheme generic, which seems to be
> >> a good idea from what I've heard :-)
> >
> > Yep.
> 
> I'm not certain about making the ppc virq scheme generic.  Maybe it is
> just my distorted impression but I have the understanding that ppc irq
> numbers mean nothing and are totally unstable whereas on x86 irq numbers
> in general are stable (across kernel upgrades and changes in device
> probe order) and the irq number has a useful hardware meaning.  Which
> means you don't have to go through several layers of translation tables
> to figure out which hardware pin you are talking about.

Nobody is forced to use it, but we have already several instances of
virq mapping implementations in arch/*. Having a generic
infrastructure for this makes a ton of sense.

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 16:41 ` Eric W. Biederman
  2010-10-03 16:41   ` Eric W. Biederman
@ 2010-10-03 19:16   ` Thomas Gleixner
  2010-10-03 22:57     ` Benjamin Herrenschmidt
                       ` (2 more replies)
  1 sibling, 3 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-03 19:16 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

On Sun, 3 Oct 2010, Eric W. Biederman wrote:
> Thomas Gleixner <tglx@linutronix.de> writes:
> > Rationale:
> > ----------
> >
> > The current sparse_irq allocator has several short comings due to
> > failures in the design or the lack of it:
> >
> >  - Requires iteration over the number of active irqs to find a free slot
> >    Some architectures have grown their own workarounds for this.
> >
> >  - Freeing of irq descriptors is not possible
> >
> >  - Racy between create_irq_nr and destroy_irq plugged by horrible
> >    callbacks
> >
> >  - Migration of active irq descriptors is not possible
> 
> I believe you have distored the design when aiming for migration
> of active irq descriptors (which you have not even implemented yet).
> 
> How do you plan to remove the radix tree lookup from the irq
> handling path?

Not at all and it's not even even a requirement to remove the lookup
for implementing live migration.

> On x86 the obvious implementation is to store a pointer to the irq_desc
> in our 256 entry per cpu tables.  Please implement this and see how
> it affects the design.  The code is pretty trivial.

Thought about that already, but that's a pure optimization which does
not change anything about the underlying problem.
 
> >From what I can see of your migration plan it seems incompatible with
> removing the radix tree look up in the path to generic_handle_irq().
> 
> >  - No bulk allocation of irq ranges
> 
> Where is that a short coming?

In embedded, where you have modular irq expanders loaded which
prefer to have a consecutive number space.

> > Aside of that the sparse irq design failure caused that we sprinkled
> > irq_desc references all over the place outside of kernel/irq/. That
> > makes it extremly hard to do the core changes which are necessary to
> > do further cleanups and improvements like he migration of active irq
> > descriptors. The arch code needs only to know about the irq chip and
> > the data associated with the irq. The irq descriptor itself is solely
> > a core code data structure.
> 
> If by core you mean arch code irq handling code certainly and
> msi fits that bill.

Right. The chip functions are changing from (unsigned int) to (struct
irq_data *data). And that's what my first series is providing.
 
> > The reason is that with the non sparse code access to the irq data was
> > just array pointer math and most code (aside of the old __do_IRQ()
> > users) used the provided accessor functions.
> >
> > With sparse it requires a radix tree lookup, which casued performance
> > problems. Instead of tackling the problem at the chip function level
> > and handing down a pointer to the associated data instead of an irq
> > number, the low level code acquired a reference to irq_desc and
> > populated that all over the place. Yeah, it's easier than doing a full
> > cleanup and a sensible migration path, but the resulting mess is just
> > disgusting.
> >
> > The previous chip functions series on which this series is based is
> > addressing this issue on the chip level side by handing down the
> > associated interrupt data instead of the interruut number. The x86
> > cleanup is making use of it.
> 
> And always handing down the data structure so you can do the same
> thing with sparse irq enabled or not is a much needed code cleanup.

Well, that's the plan. I just don't want to do the full tree sweep
myself. I have implemented a migration path in the first series which
allows a step by step cleanup of the chip implementations.
 
> > New implementation:
> > -------------------
> >
> > I've implemented a sane allocator which fixes the above short comings
> > (though migration of active descriptors still needs a full tree wide
> > cleanup of the direct and mostly unlocked access to irq_desc).
> >
> > The new allocator still uses a radix_tree, but uses a bitmap for
> > keeping track of allocated irq numbers. That results in:
> 
> I don't know that I have a problem with this but I do have a problem
> with using a bitmap.  A lot of the kernels irq usage has been distored
> because we use a compact array, that we cannot grow over time.  Using a
> bitmap here essentially removes 90% of the point of sparse irq.  The
> ability to remove a hard coded NR_IRQS from the kernel.

Well, lets look at some (un)realistic numbers:

Assume 16k cores and 32 irqs / core. That's 512k interrupts and
requires a 64k bitmap.

If we hit that limit, then we have some other more serious problems to
solve.

And I really do not see a point to have a truly random 64bit number
space for interrupts. Especially the dynamically allocated interrupts
(MSI & co) do not care about the number space at all. They care about
getting a unique number, nothing else.

> >  - Fast lookup of a free slot
> >
> >  - The removal of disposed descriptors (destroy_irq())
> >
> >  - Prevents the create/destroy race
> >
> >  - Bulk (de)allocation of consecutive irq ranges
> >
> >  - Migration of life descriptors after further cleanups
> 
> You should be able to do all of that by walking your radix tree in the
> sparse irq case.

The bitmap makes the design way simpler and gets rid of useless tree
walks and looped lookups for bulk allocations.
 
> > Full conversion and clean up of x86:
> > ------------------------------------
> >
> > I spent quite a time to come up with a sane and splitable concept,
> > which does not reach out into drivers/pci/[msi|ht|dmar] and whatever.
> >
> > But that's simply impossible because everything is twisted together
> > mainly by optimization hacks done over time. (i.e. handing down
> > irq_desc to low level msi functions instead of irq_desc.msi_desc would
> > have kept the mess confined to x86).
> 
> Those files provide the genirq irq chip implementation especially
> drivers/pci/msi.c.  Of course they will do what every other irq_chip
> implementation does to get access to data.  There is an unpleasant
> difference between which generic irq data field htirq.c uses and msi.c
> which may be worth cleaning up.  But otherwise I don't see any
> fundamental problems.

The fundamental problem I hit, was the hack which handed down irq_desc
to avoid the lookup. If it had been msi_desc in the first place, then
I would not even need to touch the msi code to cleanup x86.

> The big difference is those are the irq controllers that we have code
> for that is not necessarily architecture specific.
> 
> > So I went there and started to convert stuff piece by piece in x86 and
> > added the drivers/pci/* fixes as separate patches along the way. Not
> > nice, but it turned out to be the only way which avoided even more
> > churn.
> 
> You should be able to convert msi.c and company directly to using
> irq_data immediately following your previous patchset shouldn't you.
> Perhaps with two flavors of helper functions during the transition
> to passing irq_data everywhere.

That's already in the first series. Otherwise I would not be possible
to convert one irq chip after the other.
 
> I don't see any code in the msi code is arch specific or sparse irq
> specific.

I just did realize the irq_desc handdown to msi late, when I gradually
converted the irq chips which are used in io_apic.c. I can push that
patch further down in the queue, but that does not make a difference.
 
Thanks,

	tglx

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-03 18:34         ` Thomas Gleixner
@ 2010-10-03 20:04           ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-03 20:04 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Benjamin Herrenschmidt, LKML, linux-arch, Linus Torvalds,
	Andrew Morton, x86, Peter Zijlstra, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely



On Sun, 3 Oct 2010, Thomas Gleixner wrote:

> On Sun, 3 Oct 2010, Eric W. Biederman wrote:
> 
> > Thomas Gleixner <tglx@linutronix.de> writes:
> > 
> > >> That would make things much cleaner and in fact move one large step
> > >> toward being able to make powerpc virq scheme generic, which seems to be
> > >> a good idea from what I've heard :-)
> > >
> > > Yep.
> > 
> > I'm not certain about making the ppc virq scheme generic.  Maybe it is
> > just my distorted impression but I have the understanding that ppc irq
> > numbers mean nothing and are totally unstable whereas on x86 irq numbers
> > in general are stable (across kernel upgrades and changes in device
> > probe order) and the irq number has a useful hardware meaning.  Which
> > means you don't have to go through several layers of translation tables
> > to figure out which hardware pin you are talking about.
> 
> Nobody is forced to use it, but we have already several instances of
> virq mapping implementations in arch/*. Having a generic
> infrastructure for this makes a ton of sense.

Forgot to say: With MSI and dynamic allocated irqs the stable numbers
are completely meaningless. So where is the point ?

Thanks,

	tglx

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-03 16:53       ` Eric W. Biederman
  2010-10-03 16:53         ` Eric W. Biederman
  2010-10-03 18:34         ` Thomas Gleixner
@ 2010-10-03 22:54         ` Benjamin Herrenschmidt
  2010-10-03 22:54           ` Benjamin Herrenschmidt
                             ` (2 more replies)
  2 siblings, 3 replies; 158+ messages in thread
From: Benjamin Herrenschmidt @ 2010-10-03 22:54 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely

On Sun, 2010-10-03 at 09:53 -0700, Eric W. Biederman wrote:
> Thomas Gleixner <tglx@linutronix.de> writes:
> 
> >> That would make things much cleaner and in fact move one large step
> >> toward being able to make powerpc virq scheme generic, which seems to be
> >> a good idea from what I've heard :-)
> >
> > Yep.
> 
> I'm not certain about making the ppc virq scheme generic.  Maybe it is
> just my distorted impression but I have the understanding that ppc irq
> numbers mean nothing and are totally unstable whereas on x86 irq numbers
> in general are stable (across kernel upgrades and changes in device
> probe order) and the irq number has a useful hardware meaning.  Which
> means you don't have to go through several layers of translation tables
> to figure out which hardware pin you are talking about.

In addition to Thomas comments, it's actually more complex than that :-)

Even assuming that what you say is true (and last I looked at my x86
machine, it's not ... x86 remaps "GSI" numbers and the results doesn't
seem always entirely predictible. HT interrupts makes it worse and MSIs
just completely kill your argument :-)

Some setups have stable numbers, some don't. Hypervisors can return your
crazy HW interrupt numbers, etc...

However, remapping arbitrary crazy HW number is only one aspect of the
powerpc virq scheme (typically for IRQ domains using the radix tree
based reverse-map).

The main deal I'd say is that in embedded land (and to some extent I
suspect that's going to happen more with x86), you quickly end up with
multiple interrupt domains, via cascaded controllers of all kinds etc...

In fact, I've been in situations where I want to be able to hot plug
entire PICs.

At this point, you end up having -some- kind of scheme to map the linux
IRQ numbers to HW numbers. The "old way" to do that tends to be by
assigning fixed ranges of numbers. This somewhat works, but it is a bit
clumsy and not very dynamic nor suited for hotpluggable stuff. It
generally requires the platform code to know about everything and
declare such ranges, etc...

Now, if the stability of the numbers is a problem for you, there's a few
easy things to do to solve that:

 - First, and we do that today on powerpc, we reserve 1...15 as "legacy"
and only a PIC that claims to be "legacy" can claim them (for us that
means some kind of 8259). So your old style legacy x86 IRQs can remain
there if you want to.

 - In systems with one domain, we tend to often end up with virq ==
hwirq since we try to allocate the same number "by default". Probably
what happens today with GSI on my x86 box here.

 - Then, while powerpc allocates virq numbers when irqs are mapped, that
can be quite "late", it could be perfectly kosher to imagine a way for
"child" PICs to instead instanciate the mapping of their whole range
early. That way, their virq numbers remain contiguous, providing a
simpler 1:N mapping, and in embedded systems, you'll probably end up
with the same mapping on every boot.

 - Appart from the risk of breaking crap that parses /proc/interrupts,
adding the HW irq information there would be trivial and solve your
problem.

So overall, I don't see a problem at all. And it makes handling of
arbitrary combinations of interrupt domains (cascaded PICs) very very
easy indeed.

Cheers,
Ben.

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-03 22:54         ` Benjamin Herrenschmidt
@ 2010-10-03 22:54           ` Benjamin Herrenschmidt
  2010-10-04  0:15           ` Eric W. Biederman
  2010-10-04 16:46           ` Grant Likely
  2 siblings, 0 replies; 158+ messages in thread
From: Benjamin Herrenschmidt @ 2010-10-03 22:54 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely

On Sun, 2010-10-03 at 09:53 -0700, Eric W. Biederman wrote:
> Thomas Gleixner <tglx@linutronix.de> writes:
> 
> >> That would make things much cleaner and in fact move one large step
> >> toward being able to make powerpc virq scheme generic, which seems to be
> >> a good idea from what I've heard :-)
> >
> > Yep.
> 
> I'm not certain about making the ppc virq scheme generic.  Maybe it is
> just my distorted impression but I have the understanding that ppc irq
> numbers mean nothing and are totally unstable whereas on x86 irq numbers
> in general are stable (across kernel upgrades and changes in device
> probe order) and the irq number has a useful hardware meaning.  Which
> means you don't have to go through several layers of translation tables
> to figure out which hardware pin you are talking about.

In addition to Thomas comments, it's actually more complex than that :-)

Even assuming that what you say is true (and last I looked at my x86
machine, it's not ... x86 remaps "GSI" numbers and the results doesn't
seem always entirely predictible. HT interrupts makes it worse and MSIs
just completely kill your argument :-)

Some setups have stable numbers, some don't. Hypervisors can return your
crazy HW interrupt numbers, etc...

However, remapping arbitrary crazy HW number is only one aspect of the
powerpc virq scheme (typically for IRQ domains using the radix tree
based reverse-map).

The main deal I'd say is that in embedded land (and to some extent I
suspect that's going to happen more with x86), you quickly end up with
multiple interrupt domains, via cascaded controllers of all kinds etc...

In fact, I've been in situations where I want to be able to hot plug
entire PICs.

At this point, you end up having -some- kind of scheme to map the linux
IRQ numbers to HW numbers. The "old way" to do that tends to be by
assigning fixed ranges of numbers. This somewhat works, but it is a bit
clumsy and not very dynamic nor suited for hotpluggable stuff. It
generally requires the platform code to know about everything and
declare such ranges, etc...

Now, if the stability of the numbers is a problem for you, there's a few
easy things to do to solve that:

 - First, and we do that today on powerpc, we reserve 1...15 as "legacy"
and only a PIC that claims to be "legacy" can claim them (for us that
means some kind of 8259). So your old style legacy x86 IRQs can remain
there if you want to.

 - In systems with one domain, we tend to often end up with virq ==
hwirq since we try to allocate the same number "by default". Probably
what happens today with GSI on my x86 box here.

 - Then, while powerpc allocates virq numbers when irqs are mapped, that
can be quite "late", it could be perfectly kosher to imagine a way for
"child" PICs to instead instanciate the mapping of their whole range
early. That way, their virq numbers remain contiguous, providing a
simpler 1:N mapping, and in embedded systems, you'll probably end up
with the same mapping on every boot.

 - Appart from the risk of breaking crap that parses /proc/interrupts,
adding the HW irq information there would be trivial and solve your
problem.

So overall, I don't see a problem at all. And it makes handling of
arbitrary combinations of interrupt domains (cascaded PICs) very very
easy indeed.

Cheers,
Ben.


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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 19:16   ` Thomas Gleixner
@ 2010-10-03 22:57     ` Benjamin Herrenschmidt
  2010-10-04 16:31       ` Grant Likely
  2010-10-04  0:49     ` Eric W. Biederman
  2010-10-04  1:13     ` Eric W. Biederman
  2 siblings, 1 reply; 158+ messages in thread
From: Benjamin Herrenschmidt @ 2010-10-03 22:57 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Eric W. Biederman, LKML, linux-arch, Linus Torvalds,
	Andrew Morton, x86, Peter Zijlstra, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

On Sun, 2010-10-03 at 21:16 +0200, Thomas Gleixner wrote:
> 
> And I really do not see a point to have a truly random 64bit number
> space for interrupts. Especially the dynamically allocated interrupts
> (MSI & co) do not care about the number space at all. They care about
> getting a unique number, nothing else.

Actually, some implementations care about the actual number... but then,
at least on powerpc, those are hidden behind the virq translation so we
really don't care :-)

(IE. Some PCI host bridges give meaning to the bits of the number, while
x86 tends to use the address for that).

Cheers,
Ben.

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-03 22:54         ` Benjamin Herrenschmidt
  2010-10-03 22:54           ` Benjamin Herrenschmidt
@ 2010-10-04  0:15           ` Eric W. Biederman
  2010-10-04  0:37             ` Benjamin Herrenschmidt
  2010-10-04 16:46           ` Grant Likely
  2 siblings, 1 reply; 158+ messages in thread
From: Eric W. Biederman @ 2010-10-04  0:15 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely

Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> On Sun, 2010-10-03 at 09:53 -0700, Eric W. Biederman wrote:
>> Thomas Gleixner <tglx@linutronix.de> writes:
>> 
>> >> That would make things much cleaner and in fact move one large step
>> >> toward being able to make powerpc virq scheme generic, which seems to be
>> >> a good idea from what I've heard :-)
>> >
>> > Yep.
>> 
>> I'm not certain about making the ppc virq scheme generic.  Maybe it is
>> just my distorted impression but I have the understanding that ppc irq
>> numbers mean nothing and are totally unstable whereas on x86 irq numbers
>> in general are stable (across kernel upgrades and changes in device
>> probe order) and the irq number has a useful hardware meaning.  Which
>> means you don't have to go through several layers of translation tables
>> to figure out which hardware pin you are talking about.
>
> In addition to Thomas comments, it's actually more complex than that :-)
>
> Even assuming that what you say is true (and last I looked at my x86
> machine, it's not ... x86 remaps "GSI" numbers and the results doesn't
> seem always entirely predictible. HT interrupts makes it worse and MSIs
> just completely kill your argument :-)

I won't say kill.  There are reasons for pushing for sparse irq
numbering, but some things you can't change until you have enough of the
bugs out that people stop compiling the arch with a small fixed sized
irq table.  The common case with MSI can be handled with 16bits...

Currently on x86 we practically have a 1-1 between GSI and irq numbers.
The difference is platforms who have insanely decided to use the freedom
in the ACPI spec to have GSI 0-15 be something other than the i82559
ISA irqs.  Those GSI's we remap.  The rest we leave alone.

We used to have an arbitrary and scary system that compressed GSIs into
some small NR_IRQS and I it is hard to describe how many bugs and weird
corner cases we killed when we removed that code on x86.

So I guess my argument really is that while requiring the users to pass
through a bit of a remapping layer to keep the code from making bad
assumptions isn't bad.  Irq numbers are cheap let's not be so frugal
with them that we create problems with ourselves.  Let's just remove
the hard coded NR_IRQ assumptions, and move on with life.

> Some setups have stable numbers, some don't. Hypervisors can return your
> crazy HW interrupt numbers, etc...

I agree.  There are limits to what can be done.

> However, remapping arbitrary crazy HW number is only one aspect of the
> powerpc virq scheme (typically for IRQ domains using the radix tree
> based reverse-map).
>
> The main deal I'd say is that in embedded land (and to some extent I
> suspect that's going to happen more with x86), you quickly end up with
> multiple interrupt domains, via cascaded controllers of all kinds etc...
>
> In fact, I've been in situations where I want to be able to hot plug
> entire PICs.

I have no problems handling nested irq controllers, that seems sensible.

> At this point, you end up having -some- kind of scheme to map the linux
> IRQ numbers to HW numbers. The "old way" to do that tends to be by
> assigning fixed ranges of numbers. This somewhat works, but it is a bit
> clumsy and not very dynamic nor suited for hotpluggable stuff. It
> generally requires the platform code to know about everything and
> declare such ranges, etc...

Agreed.

> Now, if the stability of the numbers is a problem for you, there's a few
> easy things to do to solve that:

I care about stability more as a metric than as an absolute goal.

>  - First, and we do that today on powerpc, we reserve 1...15 as "legacy"
> and only a PIC that claims to be "legacy" can claim them (for us that
> means some kind of 8259). So your old style legacy x86 IRQs can remain
> there if you want to.

There are weird corner cases in the code that break if you don't do
that.

>  - In systems with one domain, we tend to often end up with virq ==
> hwirq since we try to allocate the same number "by default". Probably
> what happens today with GSI on my x86 box here.

Pretty much.

>  - Then, while powerpc allocates virq numbers when irqs are mapped, that
> can be quite "late", it could be perfectly kosher to imagine a way for
> "child" PICs to instead instanciate the mapping of their whole range
> early. That way, their virq numbers remain contiguous, providing a
> simpler 1:N mapping, and in embedded systems, you'll probably end up
> with the same mapping on every boot.

Which is probably good enough for most purposes.

>  - Appart from the risk of breaking crap that parses /proc/interrupts,
> adding the HW irq information there would be trivial and solve your
> problem.

At this point in time getting things into sysfs seems the way to handle
that.

Eric

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-04  0:15           ` Eric W. Biederman
@ 2010-10-04  0:37             ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 158+ messages in thread
From: Benjamin Herrenschmidt @ 2010-10-04  0:37 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Paul Mundt, Russell King, David Woodhouse,
	Jesse Barnes, Yinghai Lu, Grant Likely

On Sun, 2010-10-03 at 17:15 -0700, Eric W. Biederman wrote:
> 
> >  - Appart from the risk of breaking crap that
> parses /proc/interrupts,
> > adding the HW irq information there would be trivial and solve your
> > problem.
> 
> At this point in time getting things into sysfs seems the way to
> handle
> that. 

Right. For now, we have it in debugfs on powerpc, but I agree this
should probably move to sysfs.

Cheers,
Ben.

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 19:16   ` Thomas Gleixner
  2010-10-03 22:57     ` Benjamin Herrenschmidt
@ 2010-10-04  0:49     ` Eric W. Biederman
  2010-10-04  8:05       ` Thomas Gleixner
  2010-10-04  1:13     ` Eric W. Biederman
  2 siblings, 1 reply; 158+ messages in thread
From: Eric W. Biederman @ 2010-10-04  0:49 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

Thomas Gleixner <tglx@linutronix.de> writes:

> On Sun, 3 Oct 2010, Eric W. Biederman wrote:
>> Thomas Gleixner <tglx@linutronix.de> writes:
>> > Rationale:
>> > ----------
>> >
>> > The current sparse_irq allocator has several short comings due to
>> > failures in the design or the lack of it:
>> >
>> >  - Requires iteration over the number of active irqs to find a free slot
>> >    Some architectures have grown their own workarounds for this.
>> >
>> >  - Freeing of irq descriptors is not possible
>> >
>> >  - Racy between create_irq_nr and destroy_irq plugged by horrible
>> >    callbacks
>> >
>> >  - Migration of active irq descriptors is not possible
>> 
>> I believe you have distored the design when aiming for migration
>> of active irq descriptors (which you have not even implemented yet).
>> 
>> How do you plan to remove the radix tree lookup from the irq
>> handling path?
>
> Not at all and it's not even even a requirement to remove the lookup
> for implementing live migration.

It sounds like it is a requirement to *keep* the lookup for supporting
live migration.  *Keeping* the lookup I see as a serious problem.  If we
do this right the only users of the radix tree will be drivers using the
functions in interrupt.h.

>> Those files provide the genirq irq chip implementation especially
>> drivers/pci/msi.c.  Of course they will do what every other irq_chip
>> implementation does to get access to data.  There is an unpleasant
>> difference between which generic irq data field htirq.c uses and msi.c
>> which may be worth cleaning up.  But otherwise I don't see any
>> fundamental problems.
>
> The fundamental problem I hit, was the hack which handed down irq_desc
> to avoid the lookup. If it had been msi_desc in the first place, then
> I would not even need to touch the msi code to cleanup x86.

Just because you intend to rename the irq_desc irq_data...

It isn't a hack for an irq method to look at irq_desc.  At least not
until your irq_data changes go through.  This has nothing to do with
how x86 is structured and everything to do with your irq_data
``cleanup'' which appears to be mostly about code churn, for very little
apparent benefit.

In the current state of the kernel I find it very hard to swallow that
having a genirq client using irq_desc (which is the only way to
implement somethings) is a hack.

Eric

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 19:16   ` Thomas Gleixner
  2010-10-03 22:57     ` Benjamin Herrenschmidt
  2010-10-04  0:49     ` Eric W. Biederman
@ 2010-10-04  1:13     ` Eric W. Biederman
  2010-10-04  1:13       ` Eric W. Biederman
  2010-10-04  6:36       ` Ingo Molnar
  2 siblings, 2 replies; 158+ messages in thread
From: Eric W. Biederman @ 2010-10-04  1:13 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

Thomas Gleixner <tglx@linutronix.de> writes:

>> I don't know that I have a problem with this but I do have a problem
>> with using a bitmap.  A lot of the kernels irq usage has been distored
>> because we use a compact array, that we cannot grow over time.  Using a
>> bitmap here essentially removes 90% of the point of sparse irq.  The
>> ability to remove a hard coded NR_IRQS from the kernel.
>
> Well, lets look at some (un)realistic numbers:
>
> Assume 16k cores and 32 irqs / core. That's 512k interrupts and
> requires a 64k bitmap.
>
> If we hit that limit, then we have some other more serious problems to
> solve.

Possibly. 

Fundamentally keeping NR_IRQS anywhere I see as a problem, and it
really disturbs me.  Even nr_irqs I see as pretty fishy.

Looking at this objectively I see a bitmap sized to the formula
32*NR_CPUS with NR_CPUS expected to double every 18-24 months.
Which means in a decade our worst case will be 2M not 64k.

Can we please build this with scalable interfaces so we don't have to do
this again in a couple of years, and so we don't have to have little
machines paying the price for big machines, and so that big machines
aren't hamstrung because of data structures built for little machines.

Perhaps this just requires using ida instead of a bitmap.


I really think it is a mistake to use an irq number outside of the
functions in interrupt.h that go to the drivers and the userspace
display functions.

Eric

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-04  1:13     ` Eric W. Biederman
@ 2010-10-04  1:13       ` Eric W. Biederman
  2010-10-04  6:36       ` Ingo Molnar
  1 sibling, 0 replies; 158+ messages in thread
From: Eric W. Biederman @ 2010-10-04  1:13 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

Thomas Gleixner <tglx@linutronix.de> writes:

>> I don't know that I have a problem with this but I do have a problem
>> with using a bitmap.  A lot of the kernels irq usage has been distored
>> because we use a compact array, that we cannot grow over time.  Using a
>> bitmap here essentially removes 90% of the point of sparse irq.  The
>> ability to remove a hard coded NR_IRQS from the kernel.
>
> Well, lets look at some (un)realistic numbers:
>
> Assume 16k cores and 32 irqs / core. That's 512k interrupts and
> requires a 64k bitmap.
>
> If we hit that limit, then we have some other more serious problems to
> solve.

Possibly. 

Fundamentally keeping NR_IRQS anywhere I see as a problem, and it
really disturbs me.  Even nr_irqs I see as pretty fishy.

Looking at this objectively I see a bitmap sized to the formula
32*NR_CPUS with NR_CPUS expected to double every 18-24 months.
Which means in a decade our worst case will be 2M not 64k.

Can we please build this with scalable interfaces so we don't have to do
this again in a couple of years, and so we don't have to have little
machines paying the price for big machines, and so that big machines
aren't hamstrung because of data structures built for little machines.

Perhaps this just requires using ida instead of a bitmap.


I really think it is a mistake to use an irq number outside of the
functions in interrupt.h that go to the drivers and the userspace
display functions.

Eric


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

* Re: [patch 00/47] Sparse irq rework
  2010-10-04  1:13     ` Eric W. Biederman
  2010-10-04  1:13       ` Eric W. Biederman
@ 2010-10-04  6:36       ` Ingo Molnar
  1 sibling, 0 replies; 158+ messages in thread
From: Ingo Molnar @ 2010-10-04  6:36 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Thomas Gleixner, LKML, linux-arch, Linus Torvalds, Andrew Morton,
	x86, Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt,
	Russell King, David Woodhouse, Jesse Barnes, Yinghai Lu,
	Grant Likely


* Eric W. Biederman <ebiederm@xmission.com> wrote:

> Looking at this objectively I see a bitmap sized to the formula 
> 32*NR_CPUS with NR_CPUS expected to double every 18-24 months. Which 
> means in a decade our worst case will be 2M not 64k.

On a 16 TB box? Noise.

> Can we please build this with scalable interfaces so we don't have to 
> do this again in a couple of years, and so we don't have to have 
> little machines paying the price for big machines, and so that big 
> machines aren't hamstrung because of data structures built for little 
> machines.

Bitmaps are rather scalable, we use them all around the place.

> Perhaps this just requires using ida instead of a bitmap.

Erm, IDA/IDR uses a bitmap ...

IDA is a dynamically allocated bitmap - but for something as critical as 
IRQs i'd rather like to see a preallocated bitmap and platform control 
over the max (nr_irqs). We dont want to allow crappy drivers to install 
irq 0x12345678 and blow up the bitmap size to dozens of MB, etc.

Bitmaps are simple - and that's a virtue.

Thanks,

	Ingo

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-04  0:49     ` Eric W. Biederman
@ 2010-10-04  8:05       ` Thomas Gleixner
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-04  8:05 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Jesse Barnes, Yinghai Lu, Grant Likely

On Sun, 3 Oct 2010, Eric W. Biederman wrote:
> Thomas Gleixner <tglx@linutronix.de> writes:
> >> I believe you have distored the design when aiming for migration
> >> of active irq descriptors (which you have not even implemented yet).
> >> 
> >> How do you plan to remove the radix tree lookup from the irq
> >> handling path?
> >
> > Not at all and it's not even even a requirement to remove the lookup
> > for implementing live migration.
> 
> It sounds like it is a requirement to *keep* the lookup for supporting
> live migration.  *Keeping* the lookup I see as a serious problem.  If we
> do this right the only users of the radix tree will be drivers using the
> functions in interrupt.h.

Oh well. I said that it's not a requirement to remove the lookup from
the entry code, but we can remove it for optimizaiton reasons.

That is the same problem vs. migration as we have a reference to
irq_desc either by lookup or by storage in vector data on x86.

> >> Those files provide the genirq irq chip implementation especially
> >> drivers/pci/msi.c.  Of course they will do what every other irq_chip
> >> implementation does to get access to data.  There is an unpleasant
> >> difference between which generic irq data field htirq.c uses and msi.c
> >> which may be worth cleaning up.  But otherwise I don't see any
> >> fundamental problems.
> >
> > The fundamental problem I hit, was the hack which handed down irq_desc
> > to avoid the lookup. If it had been msi_desc in the first place, then
> > I would not even need to touch the msi code to cleanup x86.
> 
> Just because you intend to rename the irq_desc irq_data...

No, I'm not renaming it. I'm cleaning up the mess which was created
with references to irq_desc all over the place. I need to change core
code and I cant w/o breaking the world and some more, just because
everyone fiddles in irq_desc directly. So I want to hand down irq_data
which is right now inside of irq_desc until the irq_desc users outside
of kernel/irq are gone. Then irq_data is not necessarily a part of
irq_desc anymore.
 
> It isn't a hack for an irq method to look at irq_desc.  At least not
> until your irq_data changes go through.  This has nothing to do with
> how x86 is structured and everything to do with your irq_data
> ``cleanup'' which appears to be mostly about code churn, for very little
> apparent benefit.

I tend to disagree. The sparse_irq optimizations to get rid of the
redundant irq_desc lookups to gain access to the irq_data should have
been done in exactly that way.

And I call something which removes 500 lines of code hardly useless
code churn.

> In the current state of the kernel I find it very hard to swallow that
> having a genirq client using irq_desc (which is the only way to
> implement somethings) is a hack.

This could have been done 2 years ago by those who pushed sparse_irq
including the resulting "optimization".

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 22:57     ` Benjamin Herrenschmidt
@ 2010-10-04 16:31       ` Grant Likely
  0 siblings, 0 replies; 158+ messages in thread
From: Grant Likely @ 2010-10-04 16:31 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Thomas Gleixner, Eric W. Biederman, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra, Paul Mundt,
	Russell King, David Woodhouse, Jesse Barnes, Yinghai Lu

On Mon, Oct 04, 2010 at 09:57:33AM +1100, Benjamin Herrenschmidt wrote:
> On Sun, 2010-10-03 at 21:16 +0200, Thomas Gleixner wrote:
> > 
> > And I really do not see a point to have a truly random 64bit number
> > space for interrupts. Especially the dynamically allocated interrupts
> > (MSI & co) do not care about the number space at all. They care about
> > getting a unique number, nothing else.
> 
> Actually, some implementations care about the actual number... but then,
> at least on powerpc, those are hidden behind the virq translation so we
> really don't care :-)

In fact, if it wasn't for all the embedded platforms where some hard
coded irq number is encoded into the static device tables
(platform_device et al.) I'd argue that the irq number is completely
meaningless outside of the core irq code, and from a device driver
point of view it is just an opaque cookie.

Also from the userspace point of view, the attachment to a particular
irq controller instance is far more interesting than the specific irq
number.

g.

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

* Re: [patch 46/47] powerpc: Use new irq allocator
  2010-10-03 22:54         ` Benjamin Herrenschmidt
  2010-10-03 22:54           ` Benjamin Herrenschmidt
  2010-10-04  0:15           ` Eric W. Biederman
@ 2010-10-04 16:46           ` Grant Likely
  2 siblings, 0 replies; 158+ messages in thread
From: Grant Likely @ 2010-10-04 16:46 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Eric W. Biederman, Thomas Gleixner, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra, Paul Mundt,
	Russell King, David Woodhouse, Jesse Barnes, Yinghai Lu

On Mon, Oct 04, 2010 at 09:54:19AM +1100, Benjamin Herrenschmidt wrote:
> On Sun, 2010-10-03 at 09:53 -0700, Eric W. Biederman wrote:
> > Thomas Gleixner <tglx@linutronix.de> writes:
> > 
> > >> That would make things much cleaner and in fact move one large step
> > >> toward being able to make powerpc virq scheme generic, which seems to be
> > >> a good idea from what I've heard :-)
> > >
> > > Yep.
> > 
> > I'm not certain about making the ppc virq scheme generic.  Maybe it is
> > just my distorted impression but I have the understanding that ppc irq
> > numbers mean nothing and are totally unstable whereas on x86 irq numbers
> > in general are stable (across kernel upgrades and changes in device
> > probe order) and the irq number has a useful hardware meaning.  Which
> > means you don't have to go through several layers of translation tables
> > to figure out which hardware pin you are talking about.
[...]
>
> The main deal I'd say is that in embedded land (and to some extent I
> suspect that's going to happen more with x86), you quickly end up with
> multiple interrupt domains, via cascaded controllers of all kinds etc...
[...]
>  - Appart from the risk of breaking crap that parses /proc/interrupts,
> adding the HW irq information there would be trivial and solve your
> problem.
> 
> So overall, I don't see a problem at all. And it makes handling of
> arbitrary combinations of interrupt domains (cascaded PICs) very very
> easy indeed.

Right, the stability of irq numbers is more of a user-interface
problem than a technical deficiency with virq, and a solvable one at
that.  If fact, I'd go as far as saying that having irq numbers mean
nothing is a *virtue* of the approach because it forces developers to
look at the real irq controller attachment rather than some
hwirq==linux-irq assumption.

As mentioned in my other reply, I'd be perfectly happy to stop exposing
linux irq numbers to userspace entirely, but I realize that would
break /proc/interrupts users.  However, I do completely agree that
exposing the hwirq information is very much required.

g.

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-03 13:48       ` Thomas Gleixner
@ 2010-10-05 10:22         ` Thomas Gleixner
  2010-10-05 10:22           ` Thomas Gleixner
  2010-10-06 22:45           ` Yinghai Lu
  0 siblings, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-05 10:22 UTC (permalink / raw)
  To: Grant Likely
  Cc: Russell King - ARM Linux, LKML, linux-arch, Linus Torvalds,
	Andrew Morton, x86, Peter Zijlstra, Benjamin Herrenschmidt,
	Paul Mundt, David Woodhouse, Jesse Barnes, Yinghai Lu,
	Eric W. Biederman

On Sun, 3 Oct 2010, Thomas Gleixner wrote:
> On Sun, 3 Oct 2010, Grant Likely wrote:
> > Okay, patch 14 looks good to me too (including Yinghai's comment).
> > The new allocator seems sane, and I didn't see any obvious errors in
> > patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
> > able to carve out some time to do so early this week.
> 
> Wait until I pushed out a fixed tree. In meantime I found out how I
> managed to screw up the quilt series :(
> 
> Will post, once it's ready.

Pushed out an updated tree to

 git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-05 10:22         ` Thomas Gleixner
@ 2010-10-05 10:22           ` Thomas Gleixner
  2010-10-06 22:45           ` Yinghai Lu
  1 sibling, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-05 10:22 UTC (permalink / raw)
  To: Grant Likely
  Cc: Russell King - ARM Linux, LKML, linux-arch, Linus Torvalds,
	Andrew Morton, x86, Peter Zijlstra, Benjamin Herrenschmidt,
	Paul Mundt, David Woodhouse, Jesse Barnes, Yinghai Lu,
	Eric W. Biederman

On Sun, 3 Oct 2010, Thomas Gleixner wrote:
> On Sun, 3 Oct 2010, Grant Likely wrote:
> > Okay, patch 14 looks good to me too (including Yinghai's comment).
> > The new allocator seems sane, and I didn't see any obvious errors in
> > patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
> > able to carve out some time to do so early this week.
> 
> Wait until I pushed out a fixed tree. In meantime I found out how I
> managed to screw up the quilt series :(
> 
> Will post, once it's ready.

Pushed out an updated tree to

 git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-05 10:22         ` Thomas Gleixner
  2010-10-05 10:22           ` Thomas Gleixner
@ 2010-10-06 22:45           ` Yinghai Lu
  2010-10-06 22:52             ` Thomas Gleixner
  1 sibling, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-06 22:45 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/05/2010 03:22 AM, Thomas Gleixner wrote:
> On Sun, 3 Oct 2010, Thomas Gleixner wrote:
>> On Sun, 3 Oct 2010, Grant Likely wrote:
>>> Okay, patch 14 looks good to me too (including Yinghai's comment).
>>> The new allocator seems sane, and I didn't see any obvious errors in
>>> patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
>>> able to carve out some time to do so early this week.
>>
>> Wait until I pushed out a fixed tree. In meantime I found out how I
>> managed to screw up the quilt series :(
>>
>> Will post, once it's ready.
> 
> Pushed out an updated tree to
> 
>  git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
> 

test it together with tip, it seems all io apic routing is not set rightly. MSI is ok...

[  200.290040] ehci_hcd 0000:00:1d.7: PCI INT A -> GSI 23 (level, low) -> IRQ 23
[  200.290991] ehci_hcd 0000:00:1d.7: setting latency timer to 64
[  200.310002] ehci_hcd 0000:00:1d.7: EHCI Host Controller
[  200.310455] ehci_hcd 0000:00:1d.7: new USB bus registered, assigned bus number 1
[  200.330127] ehci_hcd 0000:00:1d.7: debug port 1
[  200.334395] ehci_hcd 0000:00:1d.7: cache line size of 256 is not supported
[  200.350042] ehci_hcd 0000:00:1d.7: request interrupt 23 failed
[  200.350491] ehci_hcd 0000:00:1d.7: USB bus 1 deregistered
[  200.372257] ehci_hcd 0000:00:1d.7: PCI INT A disabled
[  200.372644] ehci_hcd 0000:00:1d.7: init 0000:00:1d.7 fail, -38
[  200.389916] ehci_hcd: probe of 0000:00:1d.7 failed with error -38

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-06 22:45           ` Yinghai Lu
@ 2010-10-06 22:52             ` Thomas Gleixner
  2010-10-06 23:37               ` Yinghai Lu
  0 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-06 22:52 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Wed, 6 Oct 2010, Yinghai Lu wrote:

> On 10/05/2010 03:22 AM, Thomas Gleixner wrote:
> > On Sun, 3 Oct 2010, Thomas Gleixner wrote:
> >> On Sun, 3 Oct 2010, Grant Likely wrote:
> >>> Okay, patch 14 looks good to me too (including Yinghai's comment).
> >>> The new allocator seems sane, and I didn't see any obvious errors in
> >>> patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
> >>> able to carve out some time to do so early this week.
> >>
> >> Wait until I pushed out a fixed tree. In meantime I found out how I
> >> managed to screw up the quilt series :(
> >>
> >> Will post, once it's ready.
> > 
> > Pushed out an updated tree to
> > 
> >  git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
> > 
> 
> test it together with tip, it seems all io apic routing is not set rightly. MSI is ok...
> 
> [  200.290040] ehci_hcd 0000:00:1d.7: PCI INT A -> GSI 23 (level, low) -> IRQ 23
> [  200.290991] ehci_hcd 0000:00:1d.7: setting latency timer to 64
> [  200.310002] ehci_hcd 0000:00:1d.7: EHCI Host Controller
> [  200.310455] ehci_hcd 0000:00:1d.7: new USB bus registered, assigned bus number 1
> [  200.330127] ehci_hcd 0000:00:1d.7: debug port 1
> [  200.334395] ehci_hcd 0000:00:1d.7: cache line size of 256 is not supported
> [  200.350042] ehci_hcd 0000:00:1d.7: request interrupt 23 failed
> [  200.350491] ehci_hcd 0000:00:1d.7: USB bus 1 deregistered
> [  200.372257] ehci_hcd 0000:00:1d.7: PCI INT A disabled
> [  200.372644] ehci_hcd 0000:00:1d.7: init 0000:00:1d.7 fail, -38
> [  200.389916] ehci_hcd: probe of 0000:00:1d.7 failed with error -38

Yep. Ingo's testing found that already. Does the patch below fix it ?

Thanks,

	tglx
---
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 2f171df..eb3d01d 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -252,11 +252,15 @@ static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
 static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node)
 {
 	int res = irq_alloc_desc_at(at, node);
+	struct irq_data *data;
 
 	if (res < 0 && res != -EEXIST)
 		return NULL;
 
-	return get_irq_chip_data(at);
+	data = irq_get_irq_data(at);
+	if (res >= 0 && !data->chip_data)
+		data->chip_data = alloc_irq_cfg(at, node);
+	return data->chip_data;
 }
 
 static int alloc_irq_from(unsigned int from, int node)

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-06 22:52             ` Thomas Gleixner
@ 2010-10-06 23:37               ` Yinghai Lu
  2010-10-07  0:16                 ` Yinghai Lu
  0 siblings, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-06 23:37 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/06/2010 03:52 PM, Thomas Gleixner wrote:
> On Wed, 6 Oct 2010, Yinghai Lu wrote:
> 
>> On 10/05/2010 03:22 AM, Thomas Gleixner wrote:
>>> On Sun, 3 Oct 2010, Thomas Gleixner wrote:
>>>> On Sun, 3 Oct 2010, Grant Likely wrote:
>>>>> Okay, patch 14 looks good to me too (including Yinghai's comment).
>>>>> The new allocator seems sane, and I didn't see any obvious errors in
>>>>> patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
>>>>> able to carve out some time to do so early this week.
>>>>
>>>> Wait until I pushed out a fixed tree. In meantime I found out how I
>>>> managed to screw up the quilt series :(
>>>>
>>>> Will post, once it's ready.
>>>
>>> Pushed out an updated tree to
>>>
>>>  git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
>>>
>>
>> test it together with tip, it seems all io apic routing is not set rightly. MSI is ok...
>>
>> [  200.290040] ehci_hcd 0000:00:1d.7: PCI INT A -> GSI 23 (level, low) -> IRQ 23
>> [  200.290991] ehci_hcd 0000:00:1d.7: setting latency timer to 64
>> [  200.310002] ehci_hcd 0000:00:1d.7: EHCI Host Controller
>> [  200.310455] ehci_hcd 0000:00:1d.7: new USB bus registered, assigned bus number 1
>> [  200.330127] ehci_hcd 0000:00:1d.7: debug port 1
>> [  200.334395] ehci_hcd 0000:00:1d.7: cache line size of 256 is not supported
>> [  200.350042] ehci_hcd 0000:00:1d.7: request interrupt 23 failed
>> [  200.350491] ehci_hcd 0000:00:1d.7: USB bus 1 deregistered
>> [  200.372257] ehci_hcd 0000:00:1d.7: PCI INT A disabled
>> [  200.372644] ehci_hcd 0000:00:1d.7: init 0000:00:1d.7 fail, -38
>> [  200.389916] ehci_hcd: probe of 0000:00:1d.7 failed with error -38
> 
> Yep. Ingo's testing found that already. Does the patch below fix it ?
> 
> Thanks,
> 
> 	tglx
> ---
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index 2f171df..eb3d01d 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -252,11 +252,15 @@ static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
>  static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node)
>  {
>  	int res = irq_alloc_desc_at(at, node);
> +	struct irq_data *data;
>  
>  	if (res < 0 && res != -EEXIST)
>  		return NULL;
>  
> -	return get_irq_chip_data(at);
> +	data = irq_get_irq_data(at);
> +	if (res >= 0 && !data->chip_data)
> +		data->chip_data = alloc_irq_cfg(at, node);
> +	return data->chip_data;
>  }
>  
>  static int alloc_irq_from(unsigned int from, int node)

yes, it fixes the problem.

but can you merge get_irq_cfg_at() and alloc_irq_and_cfg_at() ? 
it's confusing to let get_...() to do the alloc work.

Thanks

Yinghai

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-06 23:37               ` Yinghai Lu
@ 2010-10-07  0:16                 ` Yinghai Lu
  2010-10-07  4:01                   ` Thomas Gleixner
  0 siblings, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-07  0:16 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/06/2010 04:37 PM, Yinghai Lu wrote:
> On 10/06/2010 03:52 PM, Thomas Gleixner wrote:
>> On Wed, 6 Oct 2010, Yinghai Lu wrote:
>>
>>> On 10/05/2010 03:22 AM, Thomas Gleixner wrote:
>>>> On Sun, 3 Oct 2010, Thomas Gleixner wrote:
>>>>> On Sun, 3 Oct 2010, Grant Likely wrote:
>>>>>> Okay, patch 14 looks good to me too (including Yinghai's comment).
>>>>>> The new allocator seems sane, and I didn't see any obvious errors in
>>>>>> patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
>>>>>> able to carve out some time to do so early this week.
>>>>>
>>>>> Wait until I pushed out a fixed tree. In meantime I found out how I
>>>>> managed to screw up the quilt series :(
>>>>>
>>>>> Will post, once it's ready.
>>>>
>>>> Pushed out an updated tree to
>>>>
>>>>  git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
>>>>
>>>
>>> test it together with tip, it seems all io apic routing is not set rightly. MSI is ok...
>>>
>>> [  200.290040] ehci_hcd 0000:00:1d.7: PCI INT A -> GSI 23 (level, low) -> IRQ 23
>>> [  200.290991] ehci_hcd 0000:00:1d.7: setting latency timer to 64
>>> [  200.310002] ehci_hcd 0000:00:1d.7: EHCI Host Controller
>>> [  200.310455] ehci_hcd 0000:00:1d.7: new USB bus registered, assigned bus number 1
>>> [  200.330127] ehci_hcd 0000:00:1d.7: debug port 1
>>> [  200.334395] ehci_hcd 0000:00:1d.7: cache line size of 256 is not supported
>>> [  200.350042] ehci_hcd 0000:00:1d.7: request interrupt 23 failed
>>> [  200.350491] ehci_hcd 0000:00:1d.7: USB bus 1 deregistered
>>> [  200.372257] ehci_hcd 0000:00:1d.7: PCI INT A disabled
>>> [  200.372644] ehci_hcd 0000:00:1d.7: init 0000:00:1d.7 fail, -38
>>> [  200.389916] ehci_hcd: probe of 0000:00:1d.7 failed with error -38
>>
>> Yep. Ingo's testing found that already. Does the patch below fix it ?
>>
>> Thanks,
>>
>> 	tglx
>> ---
>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>> index 2f171df..eb3d01d 100644
>> --- a/arch/x86/kernel/apic/io_apic.c
>> +++ b/arch/x86/kernel/apic/io_apic.c
>> @@ -252,11 +252,15 @@ static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
>>  static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node)
>>  {
>>  	int res = irq_alloc_desc_at(at, node);
>> +	struct irq_data *data;
>>  
>>  	if (res < 0 && res != -EEXIST)
>>  		return NULL;
>>  
>> -	return get_irq_chip_data(at);
>> +	data = irq_get_irq_data(at);
>> +	if (res >= 0 && !data->chip_data)
>> +		data->chip_data = alloc_irq_cfg(at, node);
>> +	return data->chip_data;
>>  }
>>  
>>  static int alloc_irq_from(unsigned int from, int node)
> 
> yes, it fixes the problem.
> 
> but can you merge get_irq_cfg_at() and alloc_irq_and_cfg_at() ? 
> it's confusing to let get_...() to do the alloc work.

more:

[   80.725830] ------------[ cut here ]------------
[   80.726176] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
[   80.745935] Hardware name: Sun Fire X4800
[   80.746179] irq_2_iommu!=NULL irq 8
[   80.746460] Modules linked in:
[   80.765852] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01782-g0d439ac-dirty #161
[   80.766500] Call Trace:
[   80.786032]  [<ffffffff810787a0>] warn_slowpath_common+0x85/0x9d
[   80.786503]  [<ffffffff8107885b>] warn_slowpath_fmt+0x46/0x48
[   80.805801]  [<ffffffff8141c5f2>] ? radix_tree_lookup+0xb/0xd
[   80.806304]  [<ffffffff8145f97c>] irq_2_iommu_alloc+0x52/0xdc
[   80.825786]  [<ffffffff81ccb2cb>] ? _raw_spin_lock_irqsave+0x6d/0x7b
[   80.826291]  [<ffffffff8145fb4d>] ? alloc_irte+0x97/0x168
[   80.845811]  [<ffffffff8145fbce>] alloc_irte+0x118/0x168
[   80.846200]  [<ffffffff810505ec>] setup_ioapic_irq+0x137/0x330
[   80.865804]  [<ffffffff810c3e73>] ? irq_to_desc+0x17/0x19
[   80.866236]  [<ffffffff810c5bcd>] ? irq_get_irq_data+0xe/0x10
[   80.885735]  [<ffffffff81051b42>] io_apic_set_pci_routing+0x119/0x12b
[   80.886229]  [<ffffffff810a5984>] ? debug_check_no_locks_freed+0x113/0x129
[   80.905778]  [<ffffffff8104c800>] mp_register_gsi+0x180/0x191
[   80.906225]  [<ffffffff815060c9>] ? dev_printk+0x45/0x47
[   80.925725]  [<ffffffff8104c85e>] acpi_register_gsi+0x4d/0x5b
[   80.926182]  [<ffffffff814b2d45>] pnpacpi_parse_allocated_irqresource+0xd0/0x107
[   80.945838]  [<ffffffff814b2dd9>] pnpacpi_allocated_resource+0x5d/0x2df
[   80.965584]  [<ffffffff8149c5cf>] ? acpi_rs_get_method_data+0x3b/0x45
[   80.966058]  [<ffffffff814b2d7c>] ? pnpacpi_allocated_resource+0x0/0x2df
[   80.985665]  [<ffffffff8149bc2e>] acpi_walk_resources+0x82/0xd3
[   80.986091]  [<ffffffff814b30ba>] pnpacpi_parse_allocated_resource+0x5f/0x87
[   81.005805]  [<ffffffff827f2e93>] pnpacpi_add_device_handler+0x199/0x220
[   81.025459]  [<ffffffff81494187>] acpi_ns_get_device_callback+0x14a/0x174
[   81.025960]  [<ffffffff81497237>] acpi_ns_walk_namespace+0xc0/0x181
[   81.045481]  [<ffffffff8149403d>] ? acpi_ns_get_device_callback+0x0/0x174
[   81.046027]  [<ffffffff81494026>] acpi_get_devices+0x66/0x7d
[   81.065529]  [<ffffffff827f2cfa>] ? pnpacpi_add_device_handler+0x0/0x220
[   81.085206]  [<ffffffff81477ef0>] ? register_acpi_bus_type+0x75/0x7b
[   81.085667]  [<ffffffff827f2bdd>] ? pnpacpi_init+0x0/0x8c
[   81.105175]  [<ffffffff827f2c3b>] pnpacpi_init+0x5e/0x8c
[   81.105587]  [<ffffffff810002da>] do_one_initcall+0x57/0x135
[   81.125214]  [<ffffffff827bff7a>] kernel_init+0x167/0x1f1
[   81.125633]  [<ffffffff81034954>] kernel_thread_helper+0x4/0x10
[   81.145165]  [<ffffffff81ccbdbc>] ? restore_args+0x0/0x30
[   81.145568]  [<ffffffff827bfe13>] ? kernel_init+0x0/0x1f1
[   81.165084]  [<ffffffff81034950>] ? kernel_thread_helper+0x0/0x10
[   81.165646] ---[ end trace 5003353dd8ff0030 ]---

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-07  0:16                 ` Yinghai Lu
@ 2010-10-07  4:01                   ` Thomas Gleixner
  2010-10-07  4:38                     ` Yinghai Lu
  0 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-07  4:01 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Wed, 6 Oct 2010, Yinghai Lu wrote:

> On 10/06/2010 04:37 PM, Yinghai Lu wrote:
> > On 10/06/2010 03:52 PM, Thomas Gleixner wrote:
> >> On Wed, 6 Oct 2010, Yinghai Lu wrote:
> >>
> >>> On 10/05/2010 03:22 AM, Thomas Gleixner wrote:
> >>>> On Sun, 3 Oct 2010, Thomas Gleixner wrote:
> >>>>> On Sun, 3 Oct 2010, Grant Likely wrote:
> >>>>>> Okay, patch 14 looks good to me too (including Yinghai's comment).
> >>>>>> The new allocator seems sane, and I didn't see any obvious errors in
> >>>>>> patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
> >>>>>> able to carve out some time to do so early this week.
> >>>>>
> >>>>> Wait until I pushed out a fixed tree. In meantime I found out how I
> >>>>> managed to screw up the quilt series :(
> >>>>>
> >>>>> Will post, once it's ready.
> >>>>
> >>>> Pushed out an updated tree to
> >>>>
> >>>>  git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
> >>>>
> >>>
> >>> test it together with tip, it seems all io apic routing is not set rightly. MSI is ok...
> >>>
> >>> [  200.290040] ehci_hcd 0000:00:1d.7: PCI INT A -> GSI 23 (level, low) -> IRQ 23
> >>> [  200.290991] ehci_hcd 0000:00:1d.7: setting latency timer to 64
> >>> [  200.310002] ehci_hcd 0000:00:1d.7: EHCI Host Controller
> >>> [  200.310455] ehci_hcd 0000:00:1d.7: new USB bus registered, assigned bus number 1
> >>> [  200.330127] ehci_hcd 0000:00:1d.7: debug port 1
> >>> [  200.334395] ehci_hcd 0000:00:1d.7: cache line size of 256 is not supported
> >>> [  200.350042] ehci_hcd 0000:00:1d.7: request interrupt 23 failed
> >>> [  200.350491] ehci_hcd 0000:00:1d.7: USB bus 1 deregistered
> >>> [  200.372257] ehci_hcd 0000:00:1d.7: PCI INT A disabled
> >>> [  200.372644] ehci_hcd 0000:00:1d.7: init 0000:00:1d.7 fail, -38
> >>> [  200.389916] ehci_hcd: probe of 0000:00:1d.7 failed with error -38
> >>
> >> Yep. Ingo's testing found that already. Does the patch below fix it ?
> >>
> >> Thanks,
> >>
> >> 	tglx
> >> ---
> >> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> >> index 2f171df..eb3d01d 100644
> >> --- a/arch/x86/kernel/apic/io_apic.c
> >> +++ b/arch/x86/kernel/apic/io_apic.c
> >> @@ -252,11 +252,15 @@ static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
> >>  static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node)
> >>  {
> >>  	int res = irq_alloc_desc_at(at, node);
> >> +	struct irq_data *data;
> >>  
> >>  	if (res < 0 && res != -EEXIST)
> >>  		return NULL;
> >>  
> >> -	return get_irq_chip_data(at);
> >> +	data = irq_get_irq_data(at);
> >> +	if (res >= 0 && !data->chip_data)
> >> +		data->chip_data = alloc_irq_cfg(at, node);
> >> +	return data->chip_data;
> >>  }
> >>  
> >>  static int alloc_irq_from(unsigned int from, int node)
> > 
> > yes, it fixes the problem.
> > 
> > but can you merge get_irq_cfg_at() and alloc_irq_and_cfg_at() ? 
> > it's confusing to let get_...() to do the alloc work.

Well, I'm not too happy about this preallocated stuff anyway, which is
the reason for the warning below.
 
> [   80.726176] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
> [   80.745935] Hardware name: Sun Fire X4800
> [   80.746179] irq_2_iommu!=NULL irq 8

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-07  4:01                   ` Thomas Gleixner
@ 2010-10-07  4:38                     ` Yinghai Lu
  2010-10-08 21:50                       ` Thomas Gleixner
  0 siblings, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-07  4:38 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/06/2010 09:01 PM, Thomas Gleixner wrote:
> On Wed, 6 Oct 2010, Yinghai Lu wrote:
> 
>> On 10/06/2010 04:37 PM, Yinghai Lu wrote:
>>> On 10/06/2010 03:52 PM, Thomas Gleixner wrote:
>>>> On Wed, 6 Oct 2010, Yinghai Lu wrote:
>>>>
>>>>> On 10/05/2010 03:22 AM, Thomas Gleixner wrote:
>>>>>> On Sun, 3 Oct 2010, Thomas Gleixner wrote:
>>>>>>> On Sun, 3 Oct 2010, Grant Likely wrote:
>>>>>>>> Okay, patch 14 looks good to me too (including Yinghai's comment).
>>>>>>>> The new allocator seems sane, and I didn't see any obvious errors in
>>>>>>>> patches 16-47.  I've not tested any of this yet.  Hopefully I'll be
>>>>>>>> able to carve out some time to do so early this week.
>>>>>>>
>>>>>>> Wait until I pushed out a fixed tree. In meantime I found out how I
>>>>>>> managed to screw up the quilt series :(
>>>>>>>
>>>>>>> Will post, once it's ready.
>>>>>>
>>>>>> Pushed out an updated tree to
>>>>>>
>>>>>>  git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
>>>>>>
>>>>>
>>>>> test it together with tip, it seems all io apic routing is not set rightly. MSI is ok...
>>>>>
>>>>> [  200.290040] ehci_hcd 0000:00:1d.7: PCI INT A -> GSI 23 (level, low) -> IRQ 23
>>>>> [  200.290991] ehci_hcd 0000:00:1d.7: setting latency timer to 64
>>>>> [  200.310002] ehci_hcd 0000:00:1d.7: EHCI Host Controller
>>>>> [  200.310455] ehci_hcd 0000:00:1d.7: new USB bus registered, assigned bus number 1
>>>>> [  200.330127] ehci_hcd 0000:00:1d.7: debug port 1
>>>>> [  200.334395] ehci_hcd 0000:00:1d.7: cache line size of 256 is not supported
>>>>> [  200.350042] ehci_hcd 0000:00:1d.7: request interrupt 23 failed
>>>>> [  200.350491] ehci_hcd 0000:00:1d.7: USB bus 1 deregistered
>>>>> [  200.372257] ehci_hcd 0000:00:1d.7: PCI INT A disabled
>>>>> [  200.372644] ehci_hcd 0000:00:1d.7: init 0000:00:1d.7 fail, -38
>>>>> [  200.389916] ehci_hcd: probe of 0000:00:1d.7 failed with error -38
>>>>
>>>> Yep. Ingo's testing found that already. Does the patch below fix it ?
>>>>
>>>> Thanks,
>>>>
>>>> 	tglx
>>>> ---
>>>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>>>> index 2f171df..eb3d01d 100644
>>>> --- a/arch/x86/kernel/apic/io_apic.c
>>>> +++ b/arch/x86/kernel/apic/io_apic.c
>>>> @@ -252,11 +252,15 @@ static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
>>>>  static struct irq_cfg *get_irq_cfg_at(unsigned int at, int node)
>>>>  {
>>>>  	int res = irq_alloc_desc_at(at, node);
>>>> +	struct irq_data *data;
>>>>  
>>>>  	if (res < 0 && res != -EEXIST)
>>>>  		return NULL;
>>>>  
>>>> -	return get_irq_chip_data(at);
>>>> +	data = irq_get_irq_data(at);
>>>> +	if (res >= 0 && !data->chip_data)
>>>> +		data->chip_data = alloc_irq_cfg(at, node);
>>>> +	return data->chip_data;
>>>>  }
>>>>  
>>>>  static int alloc_irq_from(unsigned int from, int node)
>>>
>>> yes, it fixes the problem.
>>>
>>> but can you merge get_irq_cfg_at() and alloc_irq_and_cfg_at() ? 
>>> it's confusing to let get_...() to do the alloc work.
> 
> Well, I'm not too happy about this preallocated stuff anyway, which is
> the reason for the warning below.
>  
>> [   80.726176] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
>> [   80.745935] Hardware name: Sun Fire X4800
>> [   80.746179] irq_2_iommu!=NULL irq 8
> 

no, irq_2_iommu are all dynamically allocated even for irq < 16.

that trace look like pnpacpi try to register the irq.

Yinghai

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-07  4:38                     ` Yinghai Lu
@ 2010-10-08 21:50                       ` Thomas Gleixner
  2010-10-08 21:54                         ` Thomas Gleixner
  0 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-08 21:50 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Wed, 6 Oct 2010, Yinghai Lu wrote:
> On 10/06/2010 09:01 PM, Thomas Gleixner wrote:
> > Well, I'm not too happy about this preallocated stuff anyway, which is
> > the reason for the warning below.
> >  
> >> [   80.726176] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
> >> [   80.745935] Hardware name: Sun Fire X4800
> >> [   80.746179] irq_2_iommu!=NULL irq 8
> > 
> 
> no, irq_2_iommu are all dynamically allocated even for irq < 16.

I know. I was talking about the preallocated irq descriptors and the
handling of it in general.

Nevertheless, that irq_2_iommu stuff does not need it's own allocation
function. It's bound to a specific irq_cfg anyway, so the next logical
step is to move irq_2_iommu into struct irq_cfg and get rid of the
extra allocation/free in intr_remapping.c.

Thanks,
	
	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-08 21:50                       ` Thomas Gleixner
@ 2010-10-08 21:54                         ` Thomas Gleixner
  2010-10-09  4:26                           ` Yinghai Lu
  0 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-08 21:54 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Fri, 8 Oct 2010, Thomas Gleixner wrote:

> On Wed, 6 Oct 2010, Yinghai Lu wrote:
> > On 10/06/2010 09:01 PM, Thomas Gleixner wrote:
> > > Well, I'm not too happy about this preallocated stuff anyway, which is
> > > the reason for the warning below.
> > >  
> > >> [   80.726176] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
> > >> [   80.745935] Hardware name: Sun Fire X4800
> > >> [   80.746179] irq_2_iommu!=NULL irq 8
> > > 
> > 
> > no, irq_2_iommu are all dynamically allocated even for irq < 16.
> 
> I know. I was talking about the preallocated irq descriptors and the
> handling of it in general.
> 
> Nevertheless, that irq_2_iommu stuff does not need it's own allocation
> function. It's bound to a specific irq_cfg anyway, so the next logical
> step is to move irq_2_iommu into struct irq_cfg and get rid of the
> extra allocation/free in intr_remapping.c.

Forgot to say, that I updated the git tree with all the fallout
fixes.

git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master

Can you please retest ?

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-08 21:54                         ` Thomas Gleixner
@ 2010-10-09  4:26                           ` Yinghai Lu
  2010-10-09  5:44                             ` Yinghai Lu
  2010-10-09  6:10                             ` Thomas Gleixner
  0 siblings, 2 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-09  4:26 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/08/2010 02:54 PM, Thomas Gleixner wrote:
> On Fri, 8 Oct 2010, Thomas Gleixner wrote:
> 
>> On Wed, 6 Oct 2010, Yinghai Lu wrote:
>>> On 10/06/2010 09:01 PM, Thomas Gleixner wrote:
>>>> Well, I'm not too happy about this preallocated stuff anyway, which is
>>>> the reason for the warning below.
>>>>  
>>>>> [   80.726176] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
>>>>> [   80.745935] Hardware name: Sun Fire X4800
>>>>> [   80.746179] irq_2_iommu!=NULL irq 8
>>>>
>>>
>>> no, irq_2_iommu are all dynamically allocated even for irq < 16.
>>
>> I know. I was talking about the preallocated irq descriptors and the
>> handling of it in general.
>>
>> Nevertheless, that irq_2_iommu stuff does not need it's own allocation
>> function. It's bound to a specific irq_cfg anyway, so the next logical
>> step is to move irq_2_iommu into struct irq_cfg and get rid of the
>> extra allocation/free in intr_remapping.c.
> 
> Forgot to say, that I updated the git tree with all the fallout
> fixes.
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
> 
> Can you please retest ?
> 

one warning and two panics

[   37.369332] ------------[ cut here ]------------
[   37.383782] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
[   37.384463] Hardware name: Sun Fire X4800
[   37.403803] irq_2_iommu!=NULL irq 9
[   37.404054] Modules linked in:
[   37.404311] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171
[   37.424042] Call Trace:
[   37.424205]  [<ffffffff810787a0>] warn_slowpath_common+0x85/0x9d
[   37.443822]  [<ffffffff8107885b>] warn_slowpath_fmt+0x46/0x48
[   37.444383]  [<ffffffff8141c5f6>] ? radix_tree_lookup+0xb/0xd
[   37.463788]  [<ffffffff8145f97c>] irq_2_iommu_alloc+0x52/0xdc
[   37.464200]  [<ffffffff81ccc593>] ? _raw_spin_lock_irqsave+0x6d/0x7b
[   37.483853]  [<ffffffff8145fb4d>] ? alloc_irte+0x97/0x168
[   37.484296]  [<ffffffff8145fbce>] alloc_irte+0x118/0x168
[   37.503774]  [<ffffffff8105062a>] setup_ioapic_irq+0x13f/0x331
[   37.504278]  [<ffffffff81051d70>] setup_IO_APIC_irq_extra+0xce/0xde
[   37.523868]  [<ffffffff8104c678>] acpi_gsi_to_irq+0x2a/0x31
[   37.524475]  [<ffffffff814867c8>] ? acpi_ev_sci_xrupt_handler+0x0/0x2b
[   37.543942]  [<ffffffff81475056>] acpi_os_install_interrupt_handler+0x31/0xa5
[   37.563764]  [<ffffffff81486826>] acpi_ev_install_sci_handler+0x23/0x25
[   37.564309]  [<ffffffff81485b41>] acpi_ev_install_xrupt_handlers+0x13/0x5f
[   37.583694]  [<ffffffff8149fba1>] acpi_enable_subsystem+0x13a/0x145
[   37.584429]  [<ffffffff827f0c75>] ? acpi_init+0x0/0x1a2
[   37.603653]  [<ffffffff827f0a13>] acpi_bus_init+0x26/0x288
[   37.604032]  [<ffffffff81cc920f>] ? printk+0x41/0x43
[   37.623668]  [<ffffffff827f0cf4>] acpi_init+0x7f/0x1a2
[   37.624130]  [<ffffffff810002da>] do_one_initcall+0x57/0x135
[   37.643480]  [<ffffffff827bff7a>] kernel_init+0x167/0x1f1
[   37.643871]  [<ffffffff81034954>] kernel_thread_helper+0x4/0x10
[   37.663541]  [<ffffffff81ccd07c>] ? restore_args+0x0/0x30
[   37.663951]  [<ffffffff827bfe13>] ? kernel_init+0x0/0x1f1
[   37.683515]  [<ffffffff81034950>] ? kernel_thread_helper+0x0/0x10
[   37.684143] ---[ end trace 5003353dd8ff0030 ]---


[   59.429741] BUG: unable to handle kernel NULL pointer dereference at (null)
[   59.449366] IP: [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
[   59.469016] PGD 0 
[   59.469224] Oops: 0000 [#1] SMP 
[   59.469488] last sysfs file: 
[   59.469725] CPU 0 
[   59.488959] Modules linked in:
[   59.489246] 
[   59.489361] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire X4800
[   59.509192] RIP: 0010:[<ffffffff8147d715>]  [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
[   59.529156] RSP: 0018:ffff88385e455d70  EFLAGS: 00010206
[   59.529481] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff88305e460000
[   59.549153] RDX: 0000000000000000 RSI: ffffffff8147d6d7 RDI: ffff88305e460000
[   59.568832] RBP: ffff88385e455da0 R08: 0000000000000001 R09: 000000000000025a
[   59.569424] R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
[   59.589507] R13: 0000000000000084 R14: 0000000000000000 R15: 0000000000000001
[   59.608643] FS:  0000000000000000(0000) GS:ffff880079c00000(0000) knlGS:0000000000000000
[   59.609242] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[   59.628759] CR2: 0000000000000000 CR3: 0000000002466000 CR4: 00000000000006f0
[   59.629316] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   59.648990] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[   59.668728] Process swapper (pid: 1, threadinfo ffff88385e454000, task ffff88305e460000)
[   59.669392] Stack:
[   59.688540]  ffff88385e455d90 ffff88085e93c000 ffffffff82808301 0000000000000000
[   59.689144] <0> ffff88085e93c000 0000000000000001 ffff88385e455e10 ffffffff8147d766
[   59.708944] <0> ffff88385e455dd0 0000000000000002 ffff88385e6a4700 ffffea00c54a73e0
[   59.728590] Call Trace:
[   59.728829]  [<ffffffff82808301>] ? pci_acpi_init+0x2e/0x89
[   59.729292]  [<ffffffff8147d766>] acpi_pci_irq_lookup+0x25/0x1c3
[   59.748704]  [<ffffffff82808301>] ? pci_acpi_init+0x2e/0x89
[   59.749313]  [<ffffffff8147dd74>] acpi_pci_irq_enable+0x98/0x246
[   59.768827]  [<ffffffff828083a7>] ? pci_subsys_init+0x0/0x4d
[   59.769353]  [<ffffffff828083a7>] ? pci_subsys_init+0x0/0x4d
[   59.788753]  [<ffffffff82808341>] pci_acpi_init+0x6e/0x89
[   59.789250]  [<ffffffff828083b6>] pci_subsys_init+0xf/0x4d
[   59.808714]  [<ffffffff810002da>] do_one_initcall+0x57/0x135
[   59.828222]  [<ffffffff827bff7a>] kernel_init+0x167/0x1f1
[   59.828677]  [<ffffffff81034954>] kernel_thread_helper+0x4/0x10
[   59.848214]  [<ffffffff81ccd07c>] ? restore_args+0x0/0x30
[   59.848709]  [<ffffffff827bfe13>] ? kernel_init+0x0/0x1f1
[   59.868134]  [<ffffffff81034950>] ? kernel_thread_helper+0x0/0x10
[   59.868525] Code: b7 53 12 41 39 d5 75 20 0f b7 53 14 41 39 d4 75 17 0f b6 53 18 41 39 d7 75 0e 48 c7 c7 80 89 4a 82 e8 08 f6 84 00 eb 20 48 89 c3 <48> 8b 03 48 81 fb c0 89 4a 82 0f 18 08 75 bc 48 c7 c7 80 89 4a 
[   59.908388] RIP  [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
[   59.908973]  RSP <ffff88385e455d70>
[   59.928176] CR2: 0000000000000000
[   59.928496] ---[ end trace 5003353dd8ff0031 ]---
[   59.928831] Kernel panic - not syncing: Attempted to kill init!
[   59.948349] Pid: 1, comm: swapper Tainted: G      D W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171
[   59.968151] Call Trace:
[   59.968346]  [<ffffffff81cc90be>] panic+0x91/0x1a1
[   59.968787]  [<ffffffff81ccc63a>] ? _raw_write_unlock_irq+0x30/0x35
[   59.988375]  [<ffffffff8107bbb2>] ? do_exit+0x2d8/0x6cb
[   59.988861]  [<ffffffff8107b94c>] do_exit+0x72/0x6cb
[   60.008172]  [<ffffffff81079e0d>] ? kmsg_dump+0x13b/0x156
[   60.008525]  [<ffffffff81ccdece>] oops_end+0xb7/0xbf
[   60.028120]  [<ffffffff8105b056>] no_context+0x1fc/0x20b
[   60.028555]  [<ffffffff8105b1f7>] __bad_area_nosemaphore+0x192/0x1b5
[   60.048409]  [<ffffffff81ccff3b>] ? do_page_fault+0x12d/0x3f1
[   60.048996]  [<ffffffff8105b22d>] bad_area_nosemaphore+0x13/0x15
[   60.068128]  [<ffffffff81cd0005>] do_page_fault+0x1f7/0x3f1
[   60.068695]  [<ffffffff810a8162>] ? __lock_acquire+0x17cf/0x17e1
[   60.088165]  [<ffffffff810a8162>] ? __lock_acquire+0x17cf/0x17e1
[   60.107677]  [<ffffffff81ccd443>] ? error_sti+0x5/0x6
[   60.108081]  [<ffffffff81ccc1b7>] ? trace_hardirqs_off_thunk+0x3a/0x3c
[   60.127699]  [<ffffffff81ccd25f>] page_fault+0x1f/0x30
[   60.128081]  [<ffffffff8147d6d7>] ? acpi_pci_irq_find_prt_entry+0x47/0xb1
[   60.147705]  [<ffffffff8147d715>] ? acpi_pci_irq_find_prt_entry+0x85/0xb1
[   60.148453]  [<ffffffff82808301>] ? pci_acpi_init+0x2e/0x89
[   60.167787]  [<ffffffff8147d766>] acpi_pci_irq_lookup+0x25/0x1c3
[   60.168313]  [<ffffffff82808301>] ? pci_acpi_init+0x2e/0x89
[   60.187769]  [<ffffffff8147dd74>] acpi_pci_irq_enable+0x98/0x246
[   60.188167]  [<ffffffff828083a7>] ? pci_subsys_init+0x0/0x4d
[   60.207818]  [<ffffffff828083a7>] ? pci_subsys_init+0x0/0x4d
[   60.208205]  [<ffffffff82808341>] pci_acpi_init+0x6e/0x89
[   60.227805]  [<ffffffff828083b6>] pci_subsys_init+0xf/0x4d
[   60.228250]  [<ffffffff810002da>] do_one_initcall+0x57/0x135
[   60.247819]  [<ffffffff827bff7a>] kernel_init+0x167/0x1f1
[   60.248195]  [<ffffffff81034954>] kernel_thread_helper+0x4/0x10
[   60.267709]  [<ffffffff81ccd07c>] ? restore_args+0x0/0x30
[   60.268206]  [<ffffffff827bfe13>] ? kernel_init+0x0/0x1f1
[   60.287632]  [<ffffffff81034950>] ? kernel_thread_helper+0x0/0x10

[   70.976633] ACPI: acpi_idle registered with cpuidle
[   70.978833] Monitor-Mwait will be used to enter C-1 state
[   70.996684] Monitor-Mwait will be used to enter C-3 state
[   71.037469] BUG: unable to handle kernel NULL pointer dereference at (null)
[   71.038065] IP: [<ffffffff8141e232>] strcmp+0x4/0x21
[   71.056510] PGD 0 
[   71.056743] Oops: 0000 [#1] SMP 
[   71.056994] last sysfs file: 
[   71.057194] CPU 49 
[   71.057317] Modules linked in:
[   71.076724] 
[   71.076886] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire x4800
[   71.096947] RIP: 0010:[<ffffffff8141e232>]  [<ffffffff8141e232>] strcmp+0x4/0x21
[   71.116524] RSP: 0018:ffff8810794c3c00  EFLAGS: 00010246
[   71.117021] RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000000000000
[   71.136567] RDX: ffff88285b6b6064 RSI: ffff88285b6b6020 RDI: 0000000000000000
[   71.137218] RBP: ffff8810794c3c00 R08: ffffffff82491388 R09: ffff883000000000
[   71.156848] R10: 0000000000000000 R11: 0000000000000003 R12: ffff88285b7b7000
[   71.176524] R13: ffff88285b6b6020 R14: 00000000ffffffef R15: 0000000000000001
[   71.177081] FS:  0000000000000000(0000) GS:ffff88287f000000(0000) knlGS:0000000000000000
[   71.196812] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[   71.216423] CR2: 0000000000000000 CR3: 0000000002466000 CR4: 00000000000006e0
[   71.216993] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   71.236653] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[   71.237309] Process swapper (pid: 1, threadinfo ffff8810794c2000, task ffff88305b4a8000)
[   71.256941] Stack:
[   71.257101]  ffff8810794c3c30 ffffffff81187d7c ffff8810794c3ca0 ffff881078bfda50
[   71.276856] <0> ffff88103e8b0870 ffff8810794c3ce0 ffff8810794c3c60 ffffffff81187f2f
[   71.296598] <0> ffff88103e8b0870 ffff88103eab7d00 ffff88103e8b0870 ffff8810794c3ce0
[   71.297227] Call Trace:
[   71.316487]  [<ffffffff81187d7c>] sysfs_find_dirent+0x3f/0x59
[   71.316961]  [<ffffffff81187f2f>] __sysfs_add_one+0x2f/0x91
[   71.336455]  [<ffffffff81187fb2>] sysfs_add_one+0x21/0xf6
[   71.336871]  [<ffffffff81188804>] sysfs_do_create_link+0x108/0x1a5
[   71.356562]  [<ffffffff81cccccc>] ? _raw_spin_unlock_irq+0x30/0x36
[   71.357077]  [<ffffffff811888b4>] sysfs_create_link+0x13/0x15
[   71.376588]  [<ffffffff815098f6>] driver_sysfs_add+0x70/0x95
[   71.377087]  [<ffffffff81509b6f>] driver_probe_device+0x6e/0x151
[   71.396602]  [<ffffffff81509cb3>] __driver_attach+0x61/0x85
[   71.397034]  [<ffffffff81509c52>] ? __driver_attach+0x0/0x85
[   71.416639]  [<ffffffff81508d5f>] bus_for_each_dev+0x5c/0x88
[   71.417058]  [<ffffffff81509884>] driver_attach+0x1e/0x20
[   71.436737]  [<ffffffff815094bd>] bus_add_driver+0xfd/0x254
[   71.437164]  [<ffffffff827f2008>] ? acpi_processor_init+0x0/0x10b
[   71.456732]  [<ffffffff827f2008>] ? acpi_processor_init+0x0/0x10b
[   71.457236]  [<ffffffff81509f31>] driver_register+0x9b/0x108
[   71.476676]  [<ffffffff827f2008>] ? acpi_processor_init+0x0/0x10b
[   71.496278]  [<ffffffff81479b71>] acpi_bus_register_driver+0x43/0x46
[   71.496728]  [<ffffffff827f209b>] acpi_processor_init+0x93/0x10b
[   71.516373]  [<ffffffff8109c5a2>] ? ktime_get+0x65/0xbf
[   71.516814]  [<ffffffff827f2008>] ? acpi_processor_init+0x0/0x10b
[   71.536413]  [<ffffffff810002da>] do_one_initcall+0x57/0x135
[   71.536865]  [<ffffffff827bff7a>] kernel_init+0x167/0x1f1
[   71.556395]  [<ffffffff81034954>] kernel_thread_helper+0x4/0x10
[   71.556900]  [<ffffffff81ccd07c>] ? restore_args+0x0/0x30
[   71.576432]  [<ffffffff827bfe13>] ? kernel_init+0x0/0x1f1
[   71.576874]  [<ffffffff81034950>] ? kernel_thread_helper+0x0/0x10
[   71.596481] Code: 48 ff c1 80 39 00 75 f8 eb 0d 48 ff c1 48 ff ca 75 05 c6 01 00 eb 0e 40 8a 3e 48 ff c6 40 84 ff 40 88 39 75 e5 c9 c3 55 48 89 e5 <8a> 07 8a 16 48 ff c7 48 ff c6 38 d0 74 07 19 c0 83 c8 01 eb 06 
[   71.617378] RIP  [<ffffffff8141e232>] strcmp+0x4/0x21
[   71.636558]  RSP <ffff8810794c3c00>
[   71.636814] CR2: 0000000000000000
[   71.656246] ---[ end trace b7b9396a6ed2edd4 ]---
[   71.656712] Kernel panic - not syncing: Attempted to kill init!
[   71.657202] Pid: 1, comm: swapper Tainted: G      D W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171
[   71.676846] Call Trace:
[   71.696196]  [<ffffffff81cc90be>] panic+0x91/0x1a1
[   71.696532]  [<ffffffff81ccc63a>] ? _raw_write_unlock_irq+0x30/0x35
[   71.716196]  [<ffffffff8107bbb2>] ? do_exit+0x2d8/0x6cb
[   71.716710]  [<ffffffff8107b94c>] do_exit+0x72/0x6cb
[   71.717104]  [<ffffffff81079e0d>] ? kmsg_dump+0x13b/0x156
[   71.736627]  [<ffffffff81ccdece>] oops_end+0xb7/0xbf
[   71.737111]  [<ffffffff8105b056>] no_context+0x1fc/0x20b
[   71.756467]  [<ffffffff810a8162>] ? __lock_acquire+0x17cf/0x17e1
[   71.756999]  [<ffffffff8105b1f7>] __bad_area_nosemaphore+0x192/0x1b5
[   71.776547]  [<ffffffff81ccff3b>] ? do_page_fault+0x12d/0x3f1
[   71.776908]  [<ffffffff8105b22d>] bad_area_nosemaphore+0x13/0x15
[   71.796652]  [<ffffffff81cd0005>] do_page_fault+0x1f7/0x3f1
[   71.816151]  [<ffffffff81ccd443>] ? error_sti+0x5/0x6
[   71.816516]  [<ffffffff81ccc1b7>] ? trace_hardirqs_off_thunk+0x3a/0x3c
[   71.836242]  [<ffffffff81ccd25f>] page_fault+0x1f/0x30
[   71.836680]  [<ffffffff8141e232>] ? strcmp+0x4/0x21
[   71.837084]  [<ffffffff81187d7c>] sysfs_find_dirent+0x3f/0x59
[   71.856665]  [<ffffffff81187f2f>] __sysfs_add_one+0x2f/0x91
[   71.876096]  [<ffffffff81187fb2>] sysfs_add_one+0x21/0xf6
[   71.876533]  [<ffffffff81188804>] sysfs_do_create_link+0x108/0x1a5
[   71.896120]  [<ffffffff81cccccc>] ? _raw_spin_unlock_irq+0x30/0x36
[   71.896653]  [<ffffffff811888b4>] sysfs_create_link+0x13/0x15
[   71.916203]  [<ffffffff815098f6>] driver_sysfs_add+0x70/0x95
[   71.916754]  [<ffffffff81509b6f>] driver_probe_device+0x6e/0x151
[   71.936229]  [<ffffffff81509cb3>] __driver_attach+0x61/0x85
[   71.936711]  [<ffffffff81509c52>] ? __driver_attach+0x0/0x85
[   71.956235]  [<ffffffff81508d5f>] bus_for_each_dev+0x5c/0x88
[   71.956729]  [<ffffffff81509884>] driver_attach+0x1e/0x20
[   71.976295]  [<ffffffff815094bd>] bus_add_driver+0xfd/0x254
[   71.976802]  [<ffffffff827f2008>] ? acpi_processor_init+0x0/0x10b
[   71.996309]  [<ffffffff827f2008>] ? acpi_processor_init+0x0/0x10b
[   71.996810]  [<ffffffff81509f31>] driver_register+0x9b/0x108
[   72.016264]  [<ffffffff827f2008>] ? acpi_processor_init+0x0/0x10b
[   72.016670]  [<ffffffff81479b71>] acpi_bus_register_driver+0x43/0x46
[   72.036455]  [<ffffffff827f209b>] acpi_processor_init+0x93/0x10b
[   72.056001]  [<ffffffff8109c5a2>] ? ktime_get+0x65/0xbf
[   72.056441]  [<ffffffff827f2008>] ? acpi_processor_init+0x0/0x10b
[   72.076026]  [<ffffffff810002da>] do_one_initcall+0x57/0x135
[   72.076567]  [<ffffffff827bff7a>] kernel_init+0x167/0x1f1
[   72.096004]  [<ffffffff81034954>] kernel_thread_helper+0x4/0x10
[   72.096503]  [<ffffffff81ccd07c>] ? restore_args+0x0/0x30
[   72.116022]  [<ffffffff827bfe13>] ? kernel_init+0x0/0x1f1
[   72.116472]  [<ffffffff81034950>] ? kernel_thread_helper+0x0/0x10

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09  4:26                           ` Yinghai Lu
@ 2010-10-09  5:44                             ` Yinghai Lu
  2010-10-09  6:34                               ` Thomas Gleixner
  2010-10-09  6:10                             ` Thomas Gleixner
  1 sibling, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-09  5:44 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/08/2010 09:26 PM, Yinghai Lu wrote:
> On 10/08/2010 02:54 PM, Thomas Gleixner wrote:
>> On Fri, 8 Oct 2010, Thomas Gleixner wrote:
>>
>>> On Wed, 6 Oct 2010, Yinghai Lu wrote:
>>>> On 10/06/2010 09:01 PM, Thomas Gleixner wrote:
>>>>> Well, I'm not too happy about this preallocated stuff anyway, which is
>>>>> the reason for the warning below.
>>>>>  
>>>>>> [   80.726176] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
>>>>>> [   80.745935] Hardware name: Sun Fire X4800
>>>>>> [   80.746179] irq_2_iommu!=NULL irq 8
>>>>>
>>>>
>>>> no, irq_2_iommu are all dynamically allocated even for irq < 16.
>>>
>>> I know. I was talking about the preallocated irq descriptors and the
>>> handling of it in general.
>>>
>>> Nevertheless, that irq_2_iommu stuff does not need it's own allocation
>>> function. It's bound to a specific irq_cfg anyway, so the next logical
>>> step is to move irq_2_iommu into struct irq_cfg and get rid of the
>>> extra allocation/free in intr_remapping.c.
>>
>> Forgot to say, that I updated the git tree with all the fallout
>> fixes.
>>
>> git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
>>
>> Can you please retest ?
>>
> 
> one warning and two panics
> 
> [   37.369332] ------------[ cut here ]------------
> [   37.383782] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
> [   37.384463] Hardware name: Sun Fire X4800
> [   37.403803] irq_2_iommu!=NULL irq 9
> [   37.404054] Modules linked in:
> [   37.404311] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171
> [   37.424042] Call Trace:
> [   37.424205]  [<ffffffff810787a0>] warn_slowpath_common+0x85/0x9d
> [   37.443822]  [<ffffffff8107885b>] warn_slowpath_fmt+0x46/0x48
> [   37.444383]  [<ffffffff8141c5f6>] ? radix_tree_lookup+0xb/0xd
> [   37.463788]  [<ffffffff8145f97c>] irq_2_iommu_alloc+0x52/0xdc
> [   37.464200]  [<ffffffff81ccc593>] ? _raw_spin_lock_irqsave+0x6d/0x7b
> [   37.483853]  [<ffffffff8145fb4d>] ? alloc_irte+0x97/0x168
> [   37.484296]  [<ffffffff8145fbce>] alloc_irte+0x118/0x168
> [   37.503774]  [<ffffffff8105062a>] setup_ioapic_irq+0x13f/0x331
> [   37.504278]  [<ffffffff81051d70>] setup_IO_APIC_irq_extra+0xce/0xde
> [   37.523868]  [<ffffffff8104c678>] acpi_gsi_to_irq+0x2a/0x31
> [   37.524475]  [<ffffffff814867c8>] ? acpi_ev_sci_xrupt_handler+0x0/0x2b
> [   37.543942]  [<ffffffff81475056>] acpi_os_install_interrupt_handler+0x31/0xa5
> [   37.563764]  [<ffffffff81486826>] acpi_ev_install_sci_handler+0x23/0x25
> [   37.564309]  [<ffffffff81485b41>] acpi_ev_install_xrupt_handlers+0x13/0x5f
> [   37.583694]  [<ffffffff8149fba1>] acpi_enable_subsystem+0x13a/0x145
> [   37.584429]  [<ffffffff827f0c75>] ? acpi_init+0x0/0x1a2
> [   37.603653]  [<ffffffff827f0a13>] acpi_bus_init+0x26/0x288
> [   37.604032]  [<ffffffff81cc920f>] ? printk+0x41/0x43
> [   37.623668]  [<ffffffff827f0cf4>] acpi_init+0x7f/0x1a2
> [   37.624130]  [<ffffffff810002da>] do_one_initcall+0x57/0x135
> [   37.643480]  [<ffffffff827bff7a>] kernel_init+0x167/0x1f1
> [   37.643871]  [<ffffffff81034954>] kernel_thread_helper+0x4/0x10
> [   37.663541]  [<ffffffff81ccd07c>] ? restore_args+0x0/0x30
> [   37.663951]  [<ffffffff827bfe13>] ? kernel_init+0x0/0x1f1
> [   37.683515]  [<ffffffff81034950>] ? kernel_thread_helper+0x0/0x10
> [   37.684143] ---[ end trace 5003353dd8ff0030 ]---
> 

warning can be fixed by:

[PATCH] x86: Don't setup ioapic irq for sci two times.

With Thomas's sparseirq cleanup patchset, found one warning.

[   37.369332] ------------[ cut here ]------------
[   37.383782] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
[   37.384463] Hardware name: Sun Fire X4800
[   37.403803] irq_2_iommu!=NULL irq 9
[   37.404054] Modules linked in:
[   37.404311] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171
[   37.424042] Call Trace:
[   37.424205]  [<ffffffff810787a0>] warn_slowpath_common+0x85/0x9d
[   37.443822]  [<ffffffff8107885b>] warn_slowpath_fmt+0x46/0x48
[   37.444383]  [<ffffffff8141c5f6>] ? radix_tree_lookup+0xb/0xd
[   37.463788]  [<ffffffff8145f97c>] irq_2_iommu_alloc+0x52/0xdc
[   37.464200]  [<ffffffff81ccc593>] ? _raw_spin_lock_irqsave+0x6d/0x7b
[   37.483853]  [<ffffffff8145fb4d>] ? alloc_irte+0x97/0x168
[   37.484296]  [<ffffffff8145fbce>] alloc_irte+0x118/0x168
[   37.503774]  [<ffffffff8105062a>] setup_ioapic_irq+0x13f/0x331
[   37.504278]  [<ffffffff81051d70>] setup_IO_APIC_irq_extra+0xce/0xde
[   37.523868]  [<ffffffff8104c678>] acpi_gsi_to_irq+0x2a/0x31
...

It turns We could setup ioapic irq for sci two times if that is normal SCI.

Actually setup_IO_APIC_irq_extra() is for big apic id or big irq sci.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 arch/x86/kernel/apic/io_apic.c |    4 ++++
 1 file changed, 4 insertions(+)

Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -1449,6 +1449,10 @@ void setup_IO_APIC_irq_extra(u32 gsi)
 
 	irq = pin_2_irq(idx, apic_id, pin);
 
+	/* only handle fall out from setup_IO_APIC_irqs() */
+	if (!((apic_id > 0) && (irq > 16)))
+		return;
+
 	cfg = alloc_irq_and_cfg_at(irq, node);
 	if (!cfg)
 		return;

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09  4:26                           ` Yinghai Lu
  2010-10-09  5:44                             ` Yinghai Lu
@ 2010-10-09  6:10                             ` Thomas Gleixner
  2010-10-09  7:03                               ` Yinghai Lu
  1 sibling, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-09  6:10 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Fri, 8 Oct 2010, Yinghai Lu wrote:

> On 10/08/2010 02:54 PM, Thomas Gleixner wrote:
> > On Fri, 8 Oct 2010, Thomas Gleixner wrote:
> > 
> >> On Wed, 6 Oct 2010, Yinghai Lu wrote:
> >>> On 10/06/2010 09:01 PM, Thomas Gleixner wrote:
> >>>> Well, I'm not too happy about this preallocated stuff anyway, which is
> >>>> the reason for the warning below.
> >>>>  
> >>>>> [   80.726176] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
> >>>>> [   80.745935] Hardware name: Sun Fire X4800
> >>>>> [   80.746179] irq_2_iommu!=NULL irq 8
> >>>>
> >>>
> >>> no, irq_2_iommu are all dynamically allocated even for irq < 16.
> >>
> >> I know. I was talking about the preallocated irq descriptors and the
> >> handling of it in general.
> >>
> >> Nevertheless, that irq_2_iommu stuff does not need it's own allocation
> >> function. It's bound to a specific irq_cfg anyway, so the next logical
> >> step is to move irq_2_iommu into struct irq_cfg and get rid of the
> >> extra allocation/free in intr_remapping.c.
> > 
> > Forgot to say, that I updated the git tree with all the fallout
> > fixes.
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
> > 
> > Can you please retest ?
> > 
> 
> one warning and two panics
> 
> [   37.369332] ------------[ cut here ]------------
> [   37.383782] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
> [   37.384463] Hardware name: Sun Fire X4800
> [   37.403803] irq_2_iommu!=NULL irq 9
> [   37.404054] Modules linked in:
> [   37.404311] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171

Hmm, so that interrupt is already set up in the iommmu.
 
> [   59.429741] BUG: unable to handle kernel NULL pointer dereference at (null)
> [   59.449366] IP: [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1

I can hardly see how this is related to the irq work.

> [   71.076886] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire x4800
> [   71.096947] RIP: 0010:[<ffffffff8141e232>]  [<ffffffff8141e232>] strcmp+0x4/0x21

Ditto.

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09  5:44                             ` Yinghai Lu
@ 2010-10-09  6:34                               ` Thomas Gleixner
  2010-10-09  7:08                                 ` Yinghai Lu
  0 siblings, 1 reply; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-09  6:34 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Fri, 8 Oct 2010, Yinghai Lu wrote:
> On 10/08/2010 09:26 PM, Yinghai Lu wrote:
> [PATCH] x86: Don't setup ioapic irq for sci two times.
> 
> With Thomas's sparseirq cleanup patchset, found one warning.
> 
> [   37.369332] ------------[ cut here ]------------
> [   37.383782] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
> [   37.384463] Hardware name: Sun Fire X4800
> [   37.403803] irq_2_iommu!=NULL irq 9
> [   37.404054] Modules linked in:
> [   37.404311] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171
> [   37.424042] Call Trace:
> [   37.424205]  [<ffffffff810787a0>] warn_slowpath_common+0x85/0x9d
> [   37.443822]  [<ffffffff8107885b>] warn_slowpath_fmt+0x46/0x48
> [   37.444383]  [<ffffffff8141c5f6>] ? radix_tree_lookup+0xb/0xd
> [   37.463788]  [<ffffffff8145f97c>] irq_2_iommu_alloc+0x52/0xdc
> [   37.464200]  [<ffffffff81ccc593>] ? _raw_spin_lock_irqsave+0x6d/0x7b
> [   37.483853]  [<ffffffff8145fb4d>] ? alloc_irte+0x97/0x168
> [   37.484296]  [<ffffffff8145fbce>] alloc_irte+0x118/0x168
> [   37.503774]  [<ffffffff8105062a>] setup_ioapic_irq+0x13f/0x331
> [   37.504278]  [<ffffffff81051d70>] setup_IO_APIC_irq_extra+0xce/0xde
> [   37.523868]  [<ffffffff8104c678>] acpi_gsi_to_irq+0x2a/0x31
> ...
> 
> It turns We could setup ioapic irq for sci two times if that is normal SCI.
> 
> Actually setup_IO_APIC_irq_extra() is for big apic id or big irq sci.
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> 
> ---
>  arch/x86/kernel/apic/io_apic.c |    4 ++++
>  1 file changed, 4 insertions(+)
> 
> Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
> +++ linux-2.6/arch/x86/kernel/apic/io_apic.c
> @@ -1449,6 +1449,10 @@ void setup_IO_APIC_irq_extra(u32 gsi)
>  
>  	irq = pin_2_irq(idx, apic_id, pin);
>  
> +	/* only handle fall out from setup_IO_APIC_irqs() */

What's the fallout ? And why are we coming here in the first place
when the irq is < 16 ?

> +	if (!((apic_id > 0) && (irq > 16)))
> +		return;
> +
>  	cfg = alloc_irq_and_cfg_at(irq, node);
>  	if (!cfg)
>  		return;
> 

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09  6:10                             ` Thomas Gleixner
@ 2010-10-09  7:03                               ` Yinghai Lu
  2010-10-09 12:12                                 ` Thomas Gleixner
  0 siblings, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-09  7:03 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/08/2010 11:10 PM, Thomas Gleixner wrote:
> On Fri, 8 Oct 2010, Yinghai Lu wrote:
> 
>> On 10/08/2010 02:54 PM, Thomas Gleixner wrote:
>>> On Fri, 8 Oct 2010, Thomas Gleixner wrote:
>>>
>>>> On Wed, 6 Oct 2010, Yinghai Lu wrote:
>>>>> On 10/06/2010 09:01 PM, Thomas Gleixner wrote:
>>>>>> Well, I'm not too happy about this preallocated stuff anyway, which is
>>>>>> the reason for the warning below.
>>>>>>  
>>>>>>> [   80.726176] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
>>>>>>> [   80.745935] Hardware name: Sun Fire X4800
>>>>>>> [   80.746179] irq_2_iommu!=NULL irq 8
>>>>>>
>>>>>
>>>>> no, irq_2_iommu are all dynamically allocated even for irq < 16.
>>>>
>>>> I know. I was talking about the preallocated irq descriptors and the
>>>> handling of it in general.
>>>>
>>>> Nevertheless, that irq_2_iommu stuff does not need it's own allocation
>>>> function. It's bound to a specific irq_cfg anyway, so the next logical
>>>> step is to move irq_2_iommu into struct irq_cfg and get rid of the
>>>> extra allocation/free in intr_remapping.c.
>>>
>>> Forgot to say, that I updated the git tree with all the fallout
>>> fixes.
>>>
>>> git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git master
>>>
>>> Can you please retest ?
>>>
>>
>> one warning and two panics
>>
>> [   37.369332] ------------[ cut here ]------------
>> [   37.383782] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
>> [   37.384463] Hardware name: Sun Fire X4800
>> [   37.403803] irq_2_iommu!=NULL irq 9
>> [   37.404054] Modules linked in:
>> [   37.404311] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171
> 
> Hmm, so that interrupt is already set up in the iommmu.
>  
>> [   59.429741] BUG: unable to handle kernel NULL pointer dereference at (null)
>> [   59.449366] IP: [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
> 
> I can hardly see how this is related to the irq work.
> 
>> [   71.076886] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire x4800
>> [   71.096947] RIP: 0010:[<ffffffff8141e232>]  [<ffffffff8141e232>] strcmp+0x4/0x21
> 
> Ditto.

don't know.

but without merging your branch, those problems don't come out.

only thing i can think about that you real free irq code could stress or expose other subsystem's bug etc.

Yinghai

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09  6:34                               ` Thomas Gleixner
@ 2010-10-09  7:08                                 ` Yinghai Lu
  2010-10-09  7:08                                   ` Yinghai Lu
                                                     ` (2 more replies)
  0 siblings, 3 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-09  7:08 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
> On Fri, 8 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 09:26 PM, Yinghai Lu wrote:
>> [PATCH] x86: Don't setup ioapic irq for sci two times.
>>
>> With Thomas's sparseirq cleanup patchset, found one warning.
>>
>> [   37.369332] ------------[ cut here ]------------
>> [   37.383782] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
>> [   37.384463] Hardware name: Sun Fire X4800
>> [   37.403803] irq_2_iommu!=NULL irq 9
>> [   37.404054] Modules linked in:
>> [   37.404311] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171
>> [   37.424042] Call Trace:
>> [   37.424205]  [<ffffffff810787a0>] warn_slowpath_common+0x85/0x9d
>> [   37.443822]  [<ffffffff8107885b>] warn_slowpath_fmt+0x46/0x48
>> [   37.444383]  [<ffffffff8141c5f6>] ? radix_tree_lookup+0xb/0xd
>> [   37.463788]  [<ffffffff8145f97c>] irq_2_iommu_alloc+0x52/0xdc
>> [   37.464200]  [<ffffffff81ccc593>] ? _raw_spin_lock_irqsave+0x6d/0x7b
>> [   37.483853]  [<ffffffff8145fb4d>] ? alloc_irte+0x97/0x168
>> [   37.484296]  [<ffffffff8145fbce>] alloc_irte+0x118/0x168
>> [   37.503774]  [<ffffffff8105062a>] setup_ioapic_irq+0x13f/0x331
>> [   37.504278]  [<ffffffff81051d70>] setup_IO_APIC_irq_extra+0xce/0xde
>> [   37.523868]  [<ffffffff8104c678>] acpi_gsi_to_irq+0x2a/0x31
>> ...
>>
>> It turns We could setup ioapic irq for sci two times if that is normal SCI.
>>
>> Actually setup_IO_APIC_irq_extra() is for big apic id or big irq sci.
>>
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>>
>> ---
>>  arch/x86/kernel/apic/io_apic.c |    4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
>> ===================================================================
>> --- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
>> +++ linux-2.6/arch/x86/kernel/apic/io_apic.c
>> @@ -1449,6 +1449,10 @@ void setup_IO_APIC_irq_extra(u32 gsi)
>>  
>>  	irq = pin_2_irq(idx, apic_id, pin);
>>  
>> +	/* only handle fall out from setup_IO_APIC_irqs() */
> 
> What's the fallout ? And why are we coming here in the first place
> when the irq is < 16 ?

setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.

it seems IBM's system have apic_id == 1, and sci irq is using 30.

so at that time add that setup_IO_APIC_irq_extra() to workaround it.
but it seems we set that two time when irq < 16.

> 
>> +	if (!((apic_id > 0) && (irq > 16)))
>> +		return;
>> +
>>  	cfg = alloc_irq_and_cfg_at(irq, node);
>>  	if (!cfg)
>>  		return;
>>

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09  7:08                                 ` Yinghai Lu
@ 2010-10-09  7:08                                   ` Yinghai Lu
  2010-10-09 12:08                                   ` Thomas Gleixner
  2010-10-10  9:32                                   ` Thomas Gleixner
  2 siblings, 0 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-09  7:08 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
> On Fri, 8 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 09:26 PM, Yinghai Lu wrote:
>> [PATCH] x86: Don't setup ioapic irq for sci two times.
>>
>> With Thomas's sparseirq cleanup patchset, found one warning.
>>
>> [   37.369332] ------------[ cut here ]------------
>> [   37.383782] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xdc()
>> [   37.384463] Hardware name: Sun Fire X4800
>> [   37.403803] irq_2_iommu!=NULL irq 9
>> [   37.404054] Modules linked in:
>> [   37.404311] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171
>> [   37.424042] Call Trace:
>> [   37.424205]  [<ffffffff810787a0>] warn_slowpath_common+0x85/0x9d
>> [   37.443822]  [<ffffffff8107885b>] warn_slowpath_fmt+0x46/0x48
>> [   37.444383]  [<ffffffff8141c5f6>] ? radix_tree_lookup+0xb/0xd
>> [   37.463788]  [<ffffffff8145f97c>] irq_2_iommu_alloc+0x52/0xdc
>> [   37.464200]  [<ffffffff81ccc593>] ? _raw_spin_lock_irqsave+0x6d/0x7b
>> [   37.483853]  [<ffffffff8145fb4d>] ? alloc_irte+0x97/0x168
>> [   37.484296]  [<ffffffff8145fbce>] alloc_irte+0x118/0x168
>> [   37.503774]  [<ffffffff8105062a>] setup_ioapic_irq+0x13f/0x331
>> [   37.504278]  [<ffffffff81051d70>] setup_IO_APIC_irq_extra+0xce/0xde
>> [   37.523868]  [<ffffffff8104c678>] acpi_gsi_to_irq+0x2a/0x31
>> ...
>>
>> It turns We could setup ioapic irq for sci two times if that is normal SCI.
>>
>> Actually setup_IO_APIC_irq_extra() is for big apic id or big irq sci.
>>
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>>
>> ---
>>  arch/x86/kernel/apic/io_apic.c |    4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
>> ===================================================================
>> --- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
>> +++ linux-2.6/arch/x86/kernel/apic/io_apic.c
>> @@ -1449,6 +1449,10 @@ void setup_IO_APIC_irq_extra(u32 gsi)
>>  
>>  	irq = pin_2_irq(idx, apic_id, pin);
>>  
>> +	/* only handle fall out from setup_IO_APIC_irqs() */
> 
> What's the fallout ? And why are we coming here in the first place
> when the irq is < 16 ?

setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.

it seems IBM's system have apic_id == 1, and sci irq is using 30.

so at that time add that setup_IO_APIC_irq_extra() to workaround it.
but it seems we set that two time when irq < 16.

> 
>> +	if (!((apic_id > 0) && (irq > 16)))
>> +		return;
>> +
>>  	cfg = alloc_irq_and_cfg_at(irq, node);
>>  	if (!cfg)
>>  		return;
>>


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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09  7:08                                 ` Yinghai Lu
  2010-10-09  7:08                                   ` Yinghai Lu
@ 2010-10-09 12:08                                   ` Thomas Gleixner
  2010-10-10  9:32                                   ` Thomas Gleixner
  2 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-09 12:08 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Sat, 9 Oct 2010, Yinghai Lu wrote:
> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
> >>  	irq = pin_2_irq(idx, apic_id, pin);
> >>  
> >> +	/* only handle fall out from setup_IO_APIC_irqs() */
> > 
> > What's the fallout ? And why are we coming here in the first place
> > when the irq is < 16 ?
> 
> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
> 
> it seems IBM's system have apic_id == 1, and sci irq is using 30.
> 
> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
> but it seems we set that two time when irq < 16.

Hmm. Ok. Thanks for figuring it out.

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09  7:03                               ` Yinghai Lu
@ 2010-10-09 12:12                                 ` Thomas Gleixner
  2010-10-10  2:32                                   ` Yinghai Lu
  2010-10-10  5:11                                   ` Yinghai Lu
  0 siblings, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-09 12:12 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Sat, 9 Oct 2010, Yinghai Lu wrote:
> On 10/08/2010 11:10 PM, Thomas Gleixner wrote:
> >> [   59.449366] IP: [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
> > 
> > I can hardly see how this is related to the irq work.
> > 
> >> [   71.076886] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire x4800
> >> [   71.096947] RIP: 0010:[<ffffffff8141e232>]  [<ffffffff8141e232>] strcmp+0x4/0x21
> > 
> > Ditto.
> 
> don't know.
> 
> but without merging your branch, those problems don't come out.
> 
> only thing i can think about that you real free irq code could
> stress or expose other subsystem's bug etc.

The first crash is in early boot and that code just fiddles with acpi
internal stuff.

Is that fully reproducible ? If yes, any chance you can bisect it ?

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09 12:12                                 ` Thomas Gleixner
@ 2010-10-10  2:32                                   ` Yinghai Lu
  2010-10-10  2:32                                     ` Yinghai Lu
  2010-10-10  5:11                                   ` Yinghai Lu
  1 sibling, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-10  2:32 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/09/2010 05:12 AM, Thomas Gleixner wrote:
> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 11:10 PM, Thomas Gleixner wrote:
>>>> [   59.449366] IP: [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
>>>
>>> I can hardly see how this is related to the irq work.
>>>
>>>> [   71.076886] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire x4800
>>>> [   71.096947] RIP: 0010:[<ffffffff8141e232>]  [<ffffffff8141e232>] strcmp+0x4/0x21
>>>
>>> Ditto.
>>
>> don't know.
>>
>> but without merging your branch, those problems don't come out.
>>
>> only thing i can think about that you real free irq code could
>> stress or expose other subsystem's bug etc.
> 
> The first crash is in early boot and that code just fiddles with acpi
> internal stuff.
> 
> Is that fully reproducible ? If yes, any chance you can bisect it ?
> 

not sure if it is right... the offending commit looks right.

2d80f45874f511aa31c34ab90cbcc5ebc2d62b1d is the first bad commit
commit 2d80f45874f511aa31c34ab90cbcc5ebc2d62b1d
Author: Thomas Gleixner <tglx@linutronix.de>
Date:   Mon Sep 27 20:55:03 2010 +0200

    genirq: Query arch for number of early descriptors
    
    sparse irq sets up NR_IRQS_LEGACY irq descriptors and archs then go
    ahead and allocate more.
    
    Use the unused return value of arch_probe_nr_irqs() to let the
    architecture return the number of early allocations. Fix up all users.
    
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Reviewed-by: Ingo Molnar <mingo@elte.hu>

:040000 040000 36e0def4d755eb235d8fce59ad821c6c6e8e1ca7 e74c903f10df76af20433a3fc6500b4e25de32d5 M	arch
:040000 040000 9015ff96c3853c81e3848e0921ccde3f56b8d452 c37e782686d0c3c99b42c15258ad07cace9eb415 M	include
:040000 040000 9ea7cd1eda18286f55b47941ad9ebd810a341b9a c1a57bc71c6769851659913d7b3f1d46577b90b3 M	kernel

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-10  2:32                                   ` Yinghai Lu
@ 2010-10-10  2:32                                     ` Yinghai Lu
  0 siblings, 0 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-10  2:32 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/09/2010 05:12 AM, Thomas Gleixner wrote:
> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 11:10 PM, Thomas Gleixner wrote:
>>>> [   59.449366] IP: [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
>>>
>>> I can hardly see how this is related to the irq work.
>>>
>>>> [   71.076886] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire x4800
>>>> [   71.096947] RIP: 0010:[<ffffffff8141e232>]  [<ffffffff8141e232>] strcmp+0x4/0x21
>>>
>>> Ditto.
>>
>> don't know.
>>
>> but without merging your branch, those problems don't come out.
>>
>> only thing i can think about that you real free irq code could
>> stress or expose other subsystem's bug etc.
> 
> The first crash is in early boot and that code just fiddles with acpi
> internal stuff.
> 
> Is that fully reproducible ? If yes, any chance you can bisect it ?
> 

not sure if it is right... the offending commit looks right.

2d80f45874f511aa31c34ab90cbcc5ebc2d62b1d is the first bad commit
commit 2d80f45874f511aa31c34ab90cbcc5ebc2d62b1d
Author: Thomas Gleixner <tglx@linutronix.de>
Date:   Mon Sep 27 20:55:03 2010 +0200

    genirq: Query arch for number of early descriptors
    
    sparse irq sets up NR_IRQS_LEGACY irq descriptors and archs then go
    ahead and allocate more.
    
    Use the unused return value of arch_probe_nr_irqs() to let the
    architecture return the number of early allocations. Fix up all users.
    
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Reviewed-by: Ingo Molnar <mingo@elte.hu>

:040000 040000 36e0def4d755eb235d8fce59ad821c6c6e8e1ca7 e74c903f10df76af20433a3fc6500b4e25de32d5 M	arch
:040000 040000 9015ff96c3853c81e3848e0921ccde3f56b8d452 c37e782686d0c3c99b42c15258ad07cace9eb415 M	include
:040000 040000 9ea7cd1eda18286f55b47941ad9ebd810a341b9a c1a57bc71c6769851659913d7b3f1d46577b90b3 M	kernel

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09 12:12                                 ` Thomas Gleixner
  2010-10-10  2:32                                   ` Yinghai Lu
@ 2010-10-10  5:11                                   ` Yinghai Lu
  2010-10-10  5:11                                     ` Yinghai Lu
  2010-10-10  8:20                                     ` Thomas Gleixner
  1 sibling, 2 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-10  5:11 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/09/2010 05:12 AM, Thomas Gleixner wrote:
> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 11:10 PM, Thomas Gleixner wrote:
>>>> [   59.449366] IP: [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
>>>
>>> I can hardly see how this is related to the irq work.
>>>
>>>> [   71.076886] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire x4800
>>>> [   71.096947] RIP: 0010:[<ffffffff8141e232>]  [<ffffffff8141e232>] strcmp+0x4/0x21
>>>
>>> Ditto.
>>
>> don't know.
>>
>> but without merging your branch, those problems don't come out.
>>
>> only thing i can think about that you real free irq code could
>> stress or expose other subsystem's bug etc.
> 
> The first crash is in early boot and that code just fiddles with acpi
> internal stuff.
> 

Need following patch. Please fold it into corresponding commit.

Yinghai

[PATCH] sparseirq: Fix kstat_irqs allocation

Should allocate array according to cpu num.

Also remove extra desc_smp_init() calling, because it is called in
desc_set_defaults() already

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 kernel/irq/irqdesc.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Index: linux-2.6/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6.orig/kernel/irq/irqdesc.c
+++ linux-2.6/kernel/irq/irqdesc.c
@@ -130,7 +130,9 @@ static struct irq_desc *alloc_desc(int i
 	desc = kzalloc_node(sizeof(*desc), gfp, node);
 	if (!desc)
 		return NULL;
-	desc->kstat_irqs = kzalloc_node(sizeof(*desc->kstat_irqs), gfp, node);
+	/* allocate based on nr_cpu_ids */
+	desc->kstat_irqs = kzalloc_node(nr_cpu_ids * sizeof(*desc->kstat_irqs),
+					 gfp, node);
 	if (!desc)
 		goto err_desc;
 
@@ -142,7 +144,6 @@ static struct irq_desc *alloc_desc(int i
 
 	desc_set_defaults(irq, desc, node);
 
-	desc_smp_init(desc, node);
 	return desc;
 
 err_kstat:

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-10  5:11                                   ` Yinghai Lu
@ 2010-10-10  5:11                                     ` Yinghai Lu
  2010-10-10  8:20                                     ` Thomas Gleixner
  1 sibling, 0 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-10  5:11 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/09/2010 05:12 AM, Thomas Gleixner wrote:
> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 11:10 PM, Thomas Gleixner wrote:
>>>> [   59.449366] IP: [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
>>>
>>> I can hardly see how this is related to the irq work.
>>>
>>>> [   71.076886] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire x4800
>>>> [   71.096947] RIP: 0010:[<ffffffff8141e232>]  [<ffffffff8141e232>] strcmp+0x4/0x21
>>>
>>> Ditto.
>>
>> don't know.
>>
>> but without merging your branch, those problems don't come out.
>>
>> only thing i can think about that you real free irq code could
>> stress or expose other subsystem's bug etc.
> 
> The first crash is in early boot and that code just fiddles with acpi
> internal stuff.
> 

Need following patch. Please fold it into corresponding commit.

Yinghai

[PATCH] sparseirq: Fix kstat_irqs allocation

Should allocate array according to cpu num.

Also remove extra desc_smp_init() calling, because it is called in
desc_set_defaults() already

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 kernel/irq/irqdesc.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Index: linux-2.6/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6.orig/kernel/irq/irqdesc.c
+++ linux-2.6/kernel/irq/irqdesc.c
@@ -130,7 +130,9 @@ static struct irq_desc *alloc_desc(int i
 	desc = kzalloc_node(sizeof(*desc), gfp, node);
 	if (!desc)
 		return NULL;
-	desc->kstat_irqs = kzalloc_node(sizeof(*desc->kstat_irqs), gfp, node);
+	/* allocate based on nr_cpu_ids */
+	desc->kstat_irqs = kzalloc_node(nr_cpu_ids * sizeof(*desc->kstat_irqs),
+					 gfp, node);
 	if (!desc)
 		goto err_desc;
 
@@ -142,7 +144,6 @@ static struct irq_desc *alloc_desc(int i
 
 	desc_set_defaults(irq, desc, node);
 
-	desc_smp_init(desc, node);
 	return desc;
 
 err_kstat:

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-10  5:11                                   ` Yinghai Lu
  2010-10-10  5:11                                     ` Yinghai Lu
@ 2010-10-10  8:20                                     ` Thomas Gleixner
  1 sibling, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-10  8:20 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Sat, 9 Oct 2010, Yinghai Lu wrote:

> On 10/09/2010 05:12 AM, Thomas Gleixner wrote:
> > On Sat, 9 Oct 2010, Yinghai Lu wrote:
> >> On 10/08/2010 11:10 PM, Thomas Gleixner wrote:
> >>>> [   59.449366] IP: [<ffffffff8147d715>] acpi_pci_irq_find_prt_entry+0x85/0xb1
> >>>
> >>> I can hardly see how this is related to the irq work.
> >>>
> >>>> [   71.076886] Pid: 1, comm: swapper Tainted: G        W   2.6.36-rc7-tip-yh-01944-ge8a4c5f-dirty #171      /Sun Fire x4800
> >>>> [   71.096947] RIP: 0010:[<ffffffff8141e232>]  [<ffffffff8141e232>] strcmp+0x4/0x21
> >>>
> >>> Ditto.
> >>
> >> don't know.
> >>
> >> but without merging your branch, those problems don't come out.
> >>
> >> only thing i can think about that you real free irq code could
> >> stress or expose other subsystem's bug etc.
> > 
> > The first crash is in early boot and that code just fiddles with acpi
> > internal stuff.
> > 
> 
> Need following patch. Please fold it into corresponding commit.

Thanks for spotting this !

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-09  7:08                                 ` Yinghai Lu
  2010-10-09  7:08                                   ` Yinghai Lu
  2010-10-09 12:08                                   ` Thomas Gleixner
@ 2010-10-10  9:32                                   ` Thomas Gleixner
  2010-10-10  9:32                                     ` Thomas Gleixner
                                                       ` (3 more replies)
  2 siblings, 4 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-10  9:32 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Sat, 9 Oct 2010, Yinghai Lu wrote:
> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
> > On Fri, 8 Oct 2010, Yinghai Lu wrote:
> >> +	/* only handle fall out from setup_IO_APIC_irqs() */
> > 
> > What's the fallout ? And why are we coming here in the first place
> > when the irq is < 16 ?
> 
> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
> 
> it seems IBM's system have apic_id == 1, and sci irq is using 30.
> 
> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
> but it seems we set that two time when irq < 16.
> 
> > 
> >> +	if (!((apic_id > 0) && (irq > 16)))
> >> +		return;

I added this into the queue, but simplified it to 

  if (apic_id == 0 || irq < NR_IRQS_LEGACY)

Folded in the other fix and pushed out an updated tree.

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-10  9:32                                   ` Thomas Gleixner
@ 2010-10-10  9:32                                     ` Thomas Gleixner
  2010-10-10 13:30                                     ` Anca Emanuel
                                                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-10  9:32 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On Sat, 9 Oct 2010, Yinghai Lu wrote:
> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
> > On Fri, 8 Oct 2010, Yinghai Lu wrote:
> >> +	/* only handle fall out from setup_IO_APIC_irqs() */
> > 
> > What's the fallout ? And why are we coming here in the first place
> > when the irq is < 16 ?
> 
> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
> 
> it seems IBM's system have apic_id == 1, and sci irq is using 30.
> 
> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
> but it seems we set that two time when irq < 16.
> 
> > 
> >> +	if (!((apic_id > 0) && (irq > 16)))
> >> +		return;

I added this into the queue, but simplified it to 

  if (apic_id == 0 || irq < NR_IRQS_LEGACY)

Folded in the other fix and pushed out an updated tree.

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-10  9:32                                   ` Thomas Gleixner
  2010-10-10  9:32                                     ` Thomas Gleixner
@ 2010-10-10 13:30                                     ` Anca Emanuel
  2010-10-11  2:20                                     ` Yinghai Lu
  2010-10-11  3:50                                     ` Yinghai Lu
  3 siblings, 0 replies; 158+ messages in thread
From: Anca Emanuel @ 2010-10-10 13:30 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Yinghai Lu, Grant Likely, Russell King - ARM Linux, LKML,
	linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

>Folded in the other fix and pushed out an updated tree.

Testing: git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-sparse-irq.git
master

Running new kernel for 10 minutes. No problems here (Intel Core Duo machine).

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-10  9:32                                   ` Thomas Gleixner
  2010-10-10  9:32                                     ` Thomas Gleixner
  2010-10-10 13:30                                     ` Anca Emanuel
@ 2010-10-11  2:20                                     ` Yinghai Lu
  2010-10-11  2:20                                       ` Yinghai Lu
  2010-10-11  3:50                                     ` Yinghai Lu
  3 siblings, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-11  2:20 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/10/2010 02:32 AM, Thomas Gleixner wrote:
> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
>>> On Fri, 8 Oct 2010, Yinghai Lu wrote:
>>>> +	/* only handle fall out from setup_IO_APIC_irqs() */
>>>
>>> What's the fallout ? And why are we coming here in the first place
>>> when the irq is < 16 ?
>>
>> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
>>
>> it seems IBM's system have apic_id == 1, and sci irq is using 30.
>>
>> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
>> but it seems we set that two time when irq < 16.
>>
>>>
>>>> +	if (!((apic_id > 0) && (irq > 16)))
>>>> +		return;
> 
> I added this into the queue, but simplified it to 
> 
>   if (apic_id == 0 || irq < NR_IRQS_LEGACY)
> 
> Folded in the other fix and pushed out an updated tree.
> 

ok. please check another small fix.

diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index b3805f3..2fb9df4 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -130,10 +130,11 @@ static struct irq_desc *alloc_desc(int irq, int node)
 	desc = kzalloc_node(sizeof(*desc), gfp, node);
 	if (!desc)
 		return NULL;
+
 	/* allocate based on nr_cpu_ids */
 	desc->kstat_irqs = kzalloc_node(nr_cpu_ids * sizeof(*desc->kstat_irqs),
 					 gfp, node);
-	if (!desc)
+	if (!desc->kstat_irqs)
 		goto err_desc;
 
 	if (alloc_masks(desc, gfp, node))
@@ -226,6 +227,7 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
 static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
 int __init early_irq_init(void)
 {
+	int node = first_online_node;
 	struct irq_desc *desc;
 	int count;
 	int i;
@@ -241,8 +243,8 @@ int __init early_irq_init(void)
 		desc[i].irq_data.irq = i;
 		desc[i].irq_data.chip = &no_irq_chip;
 		desc[i].kstat_irqs = kstat_irqs_all[i];
-		alloc_masks(desc + i, GFP_KERNEL, first_online_node);
-		desc_smp_init(desc + i, first_online_node);
+		alloc_masks(desc + i, GFP_KERNEL, node);
+		desc_smp_init(desc + i, node);
 		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
 	}
 	return arch_early_irq_init();

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-11  2:20                                     ` Yinghai Lu
@ 2010-10-11  2:20                                       ` Yinghai Lu
  0 siblings, 0 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-11  2:20 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/10/2010 02:32 AM, Thomas Gleixner wrote:
> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
>>> On Fri, 8 Oct 2010, Yinghai Lu wrote:
>>>> +	/* only handle fall out from setup_IO_APIC_irqs() */
>>>
>>> What's the fallout ? And why are we coming here in the first place
>>> when the irq is < 16 ?
>>
>> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
>>
>> it seems IBM's system have apic_id == 1, and sci irq is using 30.
>>
>> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
>> but it seems we set that two time when irq < 16.
>>
>>>
>>>> +	if (!((apic_id > 0) && (irq > 16)))
>>>> +		return;
> 
> I added this into the queue, but simplified it to 
> 
>   if (apic_id == 0 || irq < NR_IRQS_LEGACY)
> 
> Folded in the other fix and pushed out an updated tree.
> 

ok. please check another small fix.

diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index b3805f3..2fb9df4 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -130,10 +130,11 @@ static struct irq_desc *alloc_desc(int irq, int node)
 	desc = kzalloc_node(sizeof(*desc), gfp, node);
 	if (!desc)
 		return NULL;
+
 	/* allocate based on nr_cpu_ids */
 	desc->kstat_irqs = kzalloc_node(nr_cpu_ids * sizeof(*desc->kstat_irqs),
 					 gfp, node);
-	if (!desc)
+	if (!desc->kstat_irqs)
 		goto err_desc;
 
 	if (alloc_masks(desc, gfp, node))
@@ -226,6 +227,7 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
 static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
 int __init early_irq_init(void)
 {
+	int node = first_online_node;
 	struct irq_desc *desc;
 	int count;
 	int i;
@@ -241,8 +243,8 @@ int __init early_irq_init(void)
 		desc[i].irq_data.irq = i;
 		desc[i].irq_data.chip = &no_irq_chip;
 		desc[i].kstat_irqs = kstat_irqs_all[i];
-		alloc_masks(desc + i, GFP_KERNEL, first_online_node);
-		desc_smp_init(desc + i, first_online_node);
+		alloc_masks(desc + i, GFP_KERNEL, node);
+		desc_smp_init(desc + i, node);
 		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
 	}
 	return arch_early_irq_init();

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-10  9:32                                   ` Thomas Gleixner
                                                       ` (2 preceding siblings ...)
  2010-10-11  2:20                                     ` Yinghai Lu
@ 2010-10-11  3:50                                     ` Yinghai Lu
  2010-10-11  3:50                                       ` Yinghai Lu
  2010-10-11  8:16                                       ` Thomas Gleixner
  3 siblings, 2 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-11  3:50 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/10/2010 02:32 AM, Thomas Gleixner wrote:
> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
>>> On Fri, 8 Oct 2010, Yinghai Lu wrote:
>>>> +	/* only handle fall out from setup_IO_APIC_irqs() */
>>>
>>> What's the fallout ? And why are we coming here in the first place
>>> when the irq is < 16 ?
>>
>> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
>>
>> it seems IBM's system have apic_id == 1, and sci irq is using 30.
>>
>> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
>> but it seems we set that two time when irq < 16.
>>
>>>
>>>> +	if (!((apic_id > 0) && (irq > 16)))
>>>> +		return;
> 
> I added this into the queue, but simplified it to 
> 
>   if (apic_id == 0 || irq < NR_IRQS_LEGACY)
> 
> Folded in the other fix and pushed out an updated tree.

still have the irq_2_iommu_alloc warning from pnpacpi

[   79.199117] calling  pnpacpi_init+0x0/0x8c @ 1
[   79.199478] pnp: PnP ACPI init
[   79.218953] ACPI: bus type pnp registered
[   79.219874] pnp 00:00: [bus 00-3f]
[   79.220182] pnp 00:00: [io  0x0000-0x5fff window]
[   79.239384] pnp 00:00: [mem 0x000a0000-0x000bffff window]
[   79.239898] pnp 00:00: [mem 0x000d0000-0x000dffff window]
[   79.258900] pnp 00:00: [mem 0x00000000-0xffffffff window]
[   79.259454] pnp 00:00: [mem 0x90000000-0xafffffff window]
[   79.278769] pnp 00:00: [mem 0xfed40000-0xfed44fff window]
[   79.279163] pnp 00:00: [mem 0xfc000000000-0xfc07fffffff window]
[   79.299403] pnp 00:00: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
[   79.299988] pnp 00:01: [mem 0xfc000000-0xfcffffff]
[   79.318841] pnp 00:01: [mem 0xfd000000-0xfdffffff]
[   79.319243] pnp 00:01: [mem 0xfe000000-0xfebfffff]
[   79.339986] pnp 00:01: Plug and Play ACPI device, IDs PNP0c01 (active)
[   79.395515] pnp 00:02: [dma 4]
[   79.395849] pnp 00:02: [io  0x0000-0x000f]
[   79.396152] pnp 00:02: [io  0x0081-0x0083]
[   79.408405] pnp 00:02: [io  0x0087]
[   79.408739] pnp 00:02: [io  0x0089-0x008b]
[   79.409041] pnp 00:02: [io  0x008f]
[   79.428422] pnp 00:02: [io  0x00c0-0x00df]
[   79.429289] pnp 00:02: Plug and Play ACPI device, IDs PNP0200 (active)
[   79.429927] pnp 00:03: [io  0x0070-0x0071]
[   79.448615] IOAPIC[0]: Set routing entry (8-8 -> 0x38 -> IRQ 8 Mode:0 Active:0)
[   79.468286] ------------[ cut here ]------------
[   79.468664] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xde()
[   79.488347] Hardware name: Sun Fire X4800
[   79.488714] irq_2_iommu!=NULL irq 8
[   79.489046] Modules linked in:
[   79.508267] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01962-g3229a4e-dirty #9
[   79.508815] Call Trace:
[   79.528192]  [<ffffffff81079001>] warn_slowpath_common+0x85/0x9d
[   79.528670]  [<ffffffff810790bc>] warn_slowpath_fmt+0x46/0x48
[   79.548166]  [<ffffffff8146879c>] irq_2_iommu_alloc+0x52/0xde
[   79.548762]  [<ffffffff81cdfac3>] ? _raw_spin_lock_irqsave+0x6d/0x7b
[   79.568209]  [<ffffffff81468956>] ? alloc_irte+0xa4/0x176
[   79.568621]  [<ffffffff814689d9>] alloc_irte+0x127/0x176
[   79.588232]  [<ffffffff81050d3b>] setup_ioapic_irq+0x13f/0x337
[   79.588783]  [<ffffffff810c4f9f>] ? irq_to_desc+0x17/0x19
[   79.608202]  [<ffffffff810c6df7>] ? irq_get_irq_data+0xe/0x10
[   79.608682]  [<ffffffff81051043>] io_apic_set_pci_routing+0x110/0x121
[   79.628297]  [<ffffffff8104c8c8>] mp_register_gsi+0x19b/0x1ac
[   79.628811]  [<ffffffff8104c955>] acpi_register_gsi+0x4a/0x78
[   79.648259]  [<ffffffff810504d5>] ? acpi_get_override_irq+0x3e/0x13e
[   79.648770]  [<ffffffff814bb7de>] pnpacpi_parse_allocated_irqresource+0xf0/0x127
[   79.668439]  [<ffffffff814bb86f>] pnpacpi_allocated_resource+0x5a/0x2cf
[   79.687979]  [<ffffffff814a8bdb>] ? acpi_ut_remove_reference+0x6a/0x71
[   79.688490]  [<ffffffff814a457d>] ? acpi_rs_get_method_data+0x3b/0x45
[   79.708209]  [<ffffffff814bb815>] ? pnpacpi_allocated_resource+0x0/0x2cf
[   79.708805]  [<ffffffff814a3cc1>] acpi_walk_resources+0x81/0xc9
[   79.728209]  [<ffffffff814bb648>] pnpacpi_parse_allocated_resource+0x5c/0x85
[   79.748009]  [<ffffffff828076c1>] pnpacpi_add_device_handler+0x192/0x215
[   79.748593]  [<ffffffff8149c1c3>] acpi_ns_get_device_callback+0x14a/0x16c
[   79.767968]  [<ffffffff8149f27d>] acpi_ns_walk_namespace+0xbe/0x17d
[   79.768518]  [<ffffffff8149c079>] ? acpi_ns_get_device_callback+0x0/0x16c
[   79.788261]  [<ffffffff8149c062>] acpi_get_devices+0x66/0x7d
[   79.807674]  [<ffffffff8280752f>] ? pnpacpi_add_device_handler+0x0/0x215
[   79.808189]  [<ffffffff8148001e>] ? register_acpi_bus_type+0x70/0x7e
[   79.837937]  [<ffffffff82807412>] ? pnpacpi_init+0x0/0x8c
[   79.838448]  [<ffffffff82807470>] pnpacpi_init+0x5e/0x8c
[   79.857771]  [<ffffffff810001f2>] do_one_initcall+0x57/0x133
[   79.858157]  [<ffffffff827d38ef>] kernel_init+0x167/0x1f1
[   79.878118]  [<ffffffff81034994>] kernel_thread_helper+0x4/0x10
[   79.878614]  [<ffffffff81ce05bc>] ? restore_args+0x0/0x30
[   79.897624]  [<ffffffff827d3788>] ? kernel_init+0x0/0x1f1
[   79.897994]  [<ffffffff81034990>] ? kernel_thread_helper+0x0/0x10
[   79.917614] ---[ end trace 5003353dd8ff0030 ]---
[   79.917963] pnp 00:03: [irq 8]
[   79.918692] pnp 00:03: Plug and Play ACPI device, IDs PNP0b00 (active)
[   79.937833] pnp 00:04: [io  0x00f0-0x00ff]
[   79.938151] IOAPIC[0]: Set routing entry (8-13 -> 0x3d -> IRQ 13 Mode:0 Active:0)
[   79.957809] pnp 00:04: [irq 13]
[   79.958514] pnp 00:04: Plug and Play ACPI device, IDs PNP0c04 (active)
[   79.978078] pnp 00:05: [io  0x0010-0x001f]
[   79.978454] pnp 00:05: [io  0x0022-0x003f]
[   79.997386] pnp 00:05: [io  0x0044-0x005f]
[   79.997690] pnp 00:05: [io  0x0062-0x0063]
[   79.998074] pnp 00:05: [io  0x0065-0x006f]
[   80.017420] pnp 00:05: [io  0x0072-0x007f]
[   80.017750] pnp 00:05: [io  0x0080]
[   80.017988] pnp 00:05: [io  0x0084-0x0086]
[   80.037443] pnp 00:05: [io  0x0088]
[   80.037791] pnp 00:05: [io  0x008c-0x008e]
[   80.057114] pnp 00:05: [io  0x0090-0x009f]
[   80.057498] pnp 00:05: [io  0x00a2-0x00bf]
[   80.057792] pnp 00:05: [io  0x00e0-0x00ef]
[   80.077168] pnp 00:05: [io  0x04d0-0x04d1]
[   80.077454] pnp 00:05: [io  0x0800-0x087f]
[   80.077801] pnp 00:05: [io  0x0000-0xffffffffffffffff disabled]
[   80.097401] pnp 00:05: [io  0x0500-0x057f]
[   80.097733] pnp 00:05: [mem 0xfed1c000-0xfed1ffff]
[   80.117202] pnp 00:05: [mem 0xfed20000-0xfed3ffff]
[   80.117627] pnp 00:05: [mem 0xfed40000-0xfed8ffff]
[   80.138465] pnp 00:05: Plug and Play ACPI device, IDs PNP0c02 (active)
[   80.139192] pnp 00:06: [mem 0xfed00000-0xfed003ff]
[   80.157924] pnp 00:06: Plug and Play ACPI device, IDs PNP0103 (active)
[   80.158793] pnp 00:07: [io  0x0060]
[   80.177052] pnp 00:07: [io  0x0064]
[   80.177288] pnp 00:07: [mem 0xfec00000-0xfec00fff]
[   80.177676] pnp 00:07: [mem 0xfee00000-0xfee00fff]
[   80.198356] pnp 00:07: Plug and Play ACPI device, IDs PNP0c02 (active)
[   80.198877] pnp 00:08: [io  0x03f8-0x03ff]
[   80.216890] IOAPIC[0]: Set routing entry (8-4 -> 0x34 -> IRQ 4 Mode:0 Active:0)
[   80.217523] pnp 00:08: [irq 4]
[   80.236833] pnp 00:08: [dma 0 disabled]
[   80.237611] pnp 00:08: Plug and Play ACPI device, IDs PNP0501 (active)
[   80.256743] pnp 00:09: [io  0x0ca2]
[   80.257080] pnp 00:09: [io  0x0ca6]
[   80.257821] pnp 00:09: Plug and Play ACPI device, IDs IPI0001 (active)
[   80.277222] pnp 00:0a: [mem 0x80000000-0x8fffffff]
[   80.279023] pnp 00:0a: Plug and Play ACPI device, IDs PNP0c02 (active)
[   80.297523] pnp 00:0b: [mem 0x00000000-0x0009ffff]
[   80.297893] pnp 00:0b: [mem 0x000c0000-0x000cffff]
[   80.316657] pnp 00:0b: [mem 0x000e0000-0x000fffff]
[   80.317020] pnp 00:0b: [mem 0x00100000-0xffffffff]
[   80.336561] pnp 00:0b: [mem 0xfed90000-0xffffffff]
[   80.337082] pnp 00:0b: disabling [mem 0x00000000-0x0009ffff] because it overlaps 0000:c4:00.0 BAR 0 [mem 0x00000000-0x000fffff 64bit]
[   80.356938] pnp 00:0b: disabling [mem 0x000c0000-0x000cffff] because it overlaps 0000:c4:00.0 BAR 0 [mem 0x00000000-0x000fffff 64bit]
[   80.377019] pnp 00:0b: disabling [mem 0x000e0000-0x000fffff] because it overlaps 0000:c4:00.0 BAR 0 [mem 0x00000000-0x000fffff 64bit]
[   80.397045] pnp 00:0b: disabling [mem 0x00000000-0x0009ffff disabled] because it overlaps 0000:c4:00.0 BAR 2 [mem 0x00000000-0x007fffff 64bit pref]
[   80.417131] pnp 00:0b: disabling [mem 0x000c0000-0x000cffff disabled] because it overlaps 0000:c4:00.0 BAR 2 [mem 0x00000000-0x007fffff 64bit pref]
[   80.456390] pnp 00:0b: disabling [mem 0x000e0000-0x000fffff disabled] because it overlaps 0000:c4:00.0 BAR 2 [mem 0x00000000-0x007fffff 64bit pref]
[   80.476537] pnp 00:0b: disabling [mem 0x00100000-0xffffffff] because it overlaps 0000:c4:00.0 BAR 2 [mem 0x00000000-0x007fffff 64bit pref]
[   80.496584] pnp 00:0b: disabling [mem 0x00000000-0x0009ffff disabled] because it overlaps 0000:c4:00.0 BAR 4 [mem 0x00000000-0x0fffffff 64bit pref]
[   80.516724] pnp 00:0b: disabling [mem 0x000c0000-0x000cffff disabled] because it overlaps 0000:c4:00.0 BAR 4 [mem 0x00000000-0x0fffffff 64bit pref]
[   80.536892] pnp 00:0b: disabling [mem 0x000e0000-0x000fffff disabled] because it overlaps 0000:c4:00.0 BAR 4 [mem 0x00000000-0x0fffffff 64bit pref]
[   80.576556] pnp 00:0b: disabling [mem 0x00100000-0xffffffff disabled] because it overlaps 0000:c4:00.0 BAR 4 [mem 0x00000000-0x0fffffff 64bit pref]
[   80.597519] pnp 00:0b: Plug and Play ACPI device, IDs PNP0c01 (active)
[   80.598653] pnp 00:0c: [bus 40-7f]
[   80.616111] pnp 00:0c: [io  0x0000 window]
[   80.616464] pnp 00:0c: [io  0x0000 window]
[   80.616826] pnp 00:0c: [io  0x6000-0x9fff window]
[   80.636240] pnp 00:0c: [mem 0x00000000 window]
[   80.636525] pnp 00:0c: [mem 0x00000000 window]
[   80.655911] pnp 00:0c: [mem 0xb0000000-0xcfffffff window]
[   80.656462] pnp 00:0c: [mem 0x00000000-0xffffffff window]
[   80.675917] pnp 00:0c: [mem 0xfc080000000-0xfc0ffffffff window]
[   80.676936] pnp 00:0c: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
[   80.697473] pnp 00:0d: Plug and Play ACPI device, IDs PNP0c01 (active)
[   80.698718] pnp 00:0e: [bus 80-bf]
[   80.715901] pnp 00:0e: [io  0x0000 window]
[   80.716215] pnp 00:0e: [io  0x0000 window]
[   80.716604] pnp 00:0e: [io  0xa000-0xdfff window]
[   80.735981] pnp 00:0e: [mem 0x00000000 window]
[   80.736349] pnp 00:0e: [mem 0x00000000 window]
[   80.755714] pnp 00:0e: [mem 0xd0000000-0xefffffff window]
[   80.756197] pnp 00:0e: [mem 0x00000000-0xffffffff window]
[   80.775696] pnp 00:0e: [mem 0xfc100000000-0xfc17fffffff window]
[   80.776768] pnp 00:0e: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
[   80.797339] pnp 00:0f: Plug and Play ACPI device, IDs PNP0c01 (active)
[   80.798666] pnp 00:10: [bus c0-f7]
[   80.815710] pnp 00:10: [io  0x0000 window]
[   80.816075] pnp 00:10: [io  0x0000 window]
[   80.816527] pnp 00:10: [io  0xe000-0xffff window]
[   80.835833] pnp 00:10: [mem 0x00000000 window]
[   80.836145] pnp 00:10: [mem 0x00000000 window]
[   80.855581] pnp 00:10: [mem 0xf0000000-0xfbffffff window]
[   80.856100] pnp 00:10: [mem 0x00000000-0xffffffff window]
[   80.875531] pnp 00:10: [mem 0xfc180000000-0xfc1ffffffff window]
[   80.876551] pnp 00:10: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
[   80.897293] pnp 00:11: Plug and Play ACPI device, IDs PNP0c01 (active)
[   80.898293] pnp: PnP ACPI: found 18 devices
[   80.915724] ACPI: ACPI bus type pnp unregistered
[   80.916140] initcall pnpacpi_init+0x0/0x8c returned 0 after 1680029 usecs

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-11  3:50                                     ` Yinghai Lu
@ 2010-10-11  3:50                                       ` Yinghai Lu
  2010-10-11  8:16                                       ` Thomas Gleixner
  1 sibling, 0 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-11  3:50 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman

On 10/10/2010 02:32 AM, Thomas Gleixner wrote:
> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
>>> On Fri, 8 Oct 2010, Yinghai Lu wrote:
>>>> +	/* only handle fall out from setup_IO_APIC_irqs() */
>>>
>>> What's the fallout ? And why are we coming here in the first place
>>> when the irq is < 16 ?
>>
>> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
>>
>> it seems IBM's system have apic_id == 1, and sci irq is using 30.
>>
>> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
>> but it seems we set that two time when irq < 16.
>>
>>>
>>>> +	if (!((apic_id > 0) && (irq > 16)))
>>>> +		return;
> 
> I added this into the queue, but simplified it to 
> 
>   if (apic_id == 0 || irq < NR_IRQS_LEGACY)
> 
> Folded in the other fix and pushed out an updated tree.

still have the irq_2_iommu_alloc warning from pnpacpi

[   79.199117] calling  pnpacpi_init+0x0/0x8c @ 1
[   79.199478] pnp: PnP ACPI init
[   79.218953] ACPI: bus type pnp registered
[   79.219874] pnp 00:00: [bus 00-3f]
[   79.220182] pnp 00:00: [io  0x0000-0x5fff window]
[   79.239384] pnp 00:00: [mem 0x000a0000-0x000bffff window]
[   79.239898] pnp 00:00: [mem 0x000d0000-0x000dffff window]
[   79.258900] pnp 00:00: [mem 0x00000000-0xffffffff window]
[   79.259454] pnp 00:00: [mem 0x90000000-0xafffffff window]
[   79.278769] pnp 00:00: [mem 0xfed40000-0xfed44fff window]
[   79.279163] pnp 00:00: [mem 0xfc000000000-0xfc07fffffff window]
[   79.299403] pnp 00:00: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
[   79.299988] pnp 00:01: [mem 0xfc000000-0xfcffffff]
[   79.318841] pnp 00:01: [mem 0xfd000000-0xfdffffff]
[   79.319243] pnp 00:01: [mem 0xfe000000-0xfebfffff]
[   79.339986] pnp 00:01: Plug and Play ACPI device, IDs PNP0c01 (active)
[   79.395515] pnp 00:02: [dma 4]
[   79.395849] pnp 00:02: [io  0x0000-0x000f]
[   79.396152] pnp 00:02: [io  0x0081-0x0083]
[   79.408405] pnp 00:02: [io  0x0087]
[   79.408739] pnp 00:02: [io  0x0089-0x008b]
[   79.409041] pnp 00:02: [io  0x008f]
[   79.428422] pnp 00:02: [io  0x00c0-0x00df]
[   79.429289] pnp 00:02: Plug and Play ACPI device, IDs PNP0200 (active)
[   79.429927] pnp 00:03: [io  0x0070-0x0071]
[   79.448615] IOAPIC[0]: Set routing entry (8-8 -> 0x38 -> IRQ 8 Mode:0 Active:0)
[   79.468286] ------------[ cut here ]------------
[   79.468664] WARNING: at drivers/pci/intr_remapping.c:67 irq_2_iommu_alloc+0x52/0xde()
[   79.488347] Hardware name: Sun Fire X4800
[   79.488714] irq_2_iommu!=NULL irq 8
[   79.489046] Modules linked in:
[   79.508267] Pid: 1, comm: swapper Not tainted 2.6.36-rc7-tip-yh-01962-g3229a4e-dirty #9
[   79.508815] Call Trace:
[   79.528192]  [<ffffffff81079001>] warn_slowpath_common+0x85/0x9d
[   79.528670]  [<ffffffff810790bc>] warn_slowpath_fmt+0x46/0x48
[   79.548166]  [<ffffffff8146879c>] irq_2_iommu_alloc+0x52/0xde
[   79.548762]  [<ffffffff81cdfac3>] ? _raw_spin_lock_irqsave+0x6d/0x7b
[   79.568209]  [<ffffffff81468956>] ? alloc_irte+0xa4/0x176
[   79.568621]  [<ffffffff814689d9>] alloc_irte+0x127/0x176
[   79.588232]  [<ffffffff81050d3b>] setup_ioapic_irq+0x13f/0x337
[   79.588783]  [<ffffffff810c4f9f>] ? irq_to_desc+0x17/0x19
[   79.608202]  [<ffffffff810c6df7>] ? irq_get_irq_data+0xe/0x10
[   79.608682]  [<ffffffff81051043>] io_apic_set_pci_routing+0x110/0x121
[   79.628297]  [<ffffffff8104c8c8>] mp_register_gsi+0x19b/0x1ac
[   79.628811]  [<ffffffff8104c955>] acpi_register_gsi+0x4a/0x78
[   79.648259]  [<ffffffff810504d5>] ? acpi_get_override_irq+0x3e/0x13e
[   79.648770]  [<ffffffff814bb7de>] pnpacpi_parse_allocated_irqresource+0xf0/0x127
[   79.668439]  [<ffffffff814bb86f>] pnpacpi_allocated_resource+0x5a/0x2cf
[   79.687979]  [<ffffffff814a8bdb>] ? acpi_ut_remove_reference+0x6a/0x71
[   79.688490]  [<ffffffff814a457d>] ? acpi_rs_get_method_data+0x3b/0x45
[   79.708209]  [<ffffffff814bb815>] ? pnpacpi_allocated_resource+0x0/0x2cf
[   79.708805]  [<ffffffff814a3cc1>] acpi_walk_resources+0x81/0xc9
[   79.728209]  [<ffffffff814bb648>] pnpacpi_parse_allocated_resource+0x5c/0x85
[   79.748009]  [<ffffffff828076c1>] pnpacpi_add_device_handler+0x192/0x215
[   79.748593]  [<ffffffff8149c1c3>] acpi_ns_get_device_callback+0x14a/0x16c
[   79.767968]  [<ffffffff8149f27d>] acpi_ns_walk_namespace+0xbe/0x17d
[   79.768518]  [<ffffffff8149c079>] ? acpi_ns_get_device_callback+0x0/0x16c
[   79.788261]  [<ffffffff8149c062>] acpi_get_devices+0x66/0x7d
[   79.807674]  [<ffffffff8280752f>] ? pnpacpi_add_device_handler+0x0/0x215
[   79.808189]  [<ffffffff8148001e>] ? register_acpi_bus_type+0x70/0x7e
[   79.837937]  [<ffffffff82807412>] ? pnpacpi_init+0x0/0x8c
[   79.838448]  [<ffffffff82807470>] pnpacpi_init+0x5e/0x8c
[   79.857771]  [<ffffffff810001f2>] do_one_initcall+0x57/0x133
[   79.858157]  [<ffffffff827d38ef>] kernel_init+0x167/0x1f1
[   79.878118]  [<ffffffff81034994>] kernel_thread_helper+0x4/0x10
[   79.878614]  [<ffffffff81ce05bc>] ? restore_args+0x0/0x30
[   79.897624]  [<ffffffff827d3788>] ? kernel_init+0x0/0x1f1
[   79.897994]  [<ffffffff81034990>] ? kernel_thread_helper+0x0/0x10
[   79.917614] ---[ end trace 5003353dd8ff0030 ]---
[   79.917963] pnp 00:03: [irq 8]
[   79.918692] pnp 00:03: Plug and Play ACPI device, IDs PNP0b00 (active)
[   79.937833] pnp 00:04: [io  0x00f0-0x00ff]
[   79.938151] IOAPIC[0]: Set routing entry (8-13 -> 0x3d -> IRQ 13 Mode:0 Active:0)
[   79.957809] pnp 00:04: [irq 13]
[   79.958514] pnp 00:04: Plug and Play ACPI device, IDs PNP0c04 (active)
[   79.978078] pnp 00:05: [io  0x0010-0x001f]
[   79.978454] pnp 00:05: [io  0x0022-0x003f]
[   79.997386] pnp 00:05: [io  0x0044-0x005f]
[   79.997690] pnp 00:05: [io  0x0062-0x0063]
[   79.998074] pnp 00:05: [io  0x0065-0x006f]
[   80.017420] pnp 00:05: [io  0x0072-0x007f]
[   80.017750] pnp 00:05: [io  0x0080]
[   80.017988] pnp 00:05: [io  0x0084-0x0086]
[   80.037443] pnp 00:05: [io  0x0088]
[   80.037791] pnp 00:05: [io  0x008c-0x008e]
[   80.057114] pnp 00:05: [io  0x0090-0x009f]
[   80.057498] pnp 00:05: [io  0x00a2-0x00bf]
[   80.057792] pnp 00:05: [io  0x00e0-0x00ef]
[   80.077168] pnp 00:05: [io  0x04d0-0x04d1]
[   80.077454] pnp 00:05: [io  0x0800-0x087f]
[   80.077801] pnp 00:05: [io  0x0000-0xffffffffffffffff disabled]
[   80.097401] pnp 00:05: [io  0x0500-0x057f]
[   80.097733] pnp 00:05: [mem 0xfed1c000-0xfed1ffff]
[   80.117202] pnp 00:05: [mem 0xfed20000-0xfed3ffff]
[   80.117627] pnp 00:05: [mem 0xfed40000-0xfed8ffff]
[   80.138465] pnp 00:05: Plug and Play ACPI device, IDs PNP0c02 (active)
[   80.139192] pnp 00:06: [mem 0xfed00000-0xfed003ff]
[   80.157924] pnp 00:06: Plug and Play ACPI device, IDs PNP0103 (active)
[   80.158793] pnp 00:07: [io  0x0060]
[   80.177052] pnp 00:07: [io  0x0064]
[   80.177288] pnp 00:07: [mem 0xfec00000-0xfec00fff]
[   80.177676] pnp 00:07: [mem 0xfee00000-0xfee00fff]
[   80.198356] pnp 00:07: Plug and Play ACPI device, IDs PNP0c02 (active)
[   80.198877] pnp 00:08: [io  0x03f8-0x03ff]
[   80.216890] IOAPIC[0]: Set routing entry (8-4 -> 0x34 -> IRQ 4 Mode:0 Active:0)
[   80.217523] pnp 00:08: [irq 4]
[   80.236833] pnp 00:08: [dma 0 disabled]
[   80.237611] pnp 00:08: Plug and Play ACPI device, IDs PNP0501 (active)
[   80.256743] pnp 00:09: [io  0x0ca2]
[   80.257080] pnp 00:09: [io  0x0ca6]
[   80.257821] pnp 00:09: Plug and Play ACPI device, IDs IPI0001 (active)
[   80.277222] pnp 00:0a: [mem 0x80000000-0x8fffffff]
[   80.279023] pnp 00:0a: Plug and Play ACPI device, IDs PNP0c02 (active)
[   80.297523] pnp 00:0b: [mem 0x00000000-0x0009ffff]
[   80.297893] pnp 00:0b: [mem 0x000c0000-0x000cffff]
[   80.316657] pnp 00:0b: [mem 0x000e0000-0x000fffff]
[   80.317020] pnp 00:0b: [mem 0x00100000-0xffffffff]
[   80.336561] pnp 00:0b: [mem 0xfed90000-0xffffffff]
[   80.337082] pnp 00:0b: disabling [mem 0x00000000-0x0009ffff] because it overlaps 0000:c4:00.0 BAR 0 [mem 0x00000000-0x000fffff 64bit]
[   80.356938] pnp 00:0b: disabling [mem 0x000c0000-0x000cffff] because it overlaps 0000:c4:00.0 BAR 0 [mem 0x00000000-0x000fffff 64bit]
[   80.377019] pnp 00:0b: disabling [mem 0x000e0000-0x000fffff] because it overlaps 0000:c4:00.0 BAR 0 [mem 0x00000000-0x000fffff 64bit]
[   80.397045] pnp 00:0b: disabling [mem 0x00000000-0x0009ffff disabled] because it overlaps 0000:c4:00.0 BAR 2 [mem 0x00000000-0x007fffff 64bit pref]
[   80.417131] pnp 00:0b: disabling [mem 0x000c0000-0x000cffff disabled] because it overlaps 0000:c4:00.0 BAR 2 [mem 0x00000000-0x007fffff 64bit pref]
[   80.456390] pnp 00:0b: disabling [mem 0x000e0000-0x000fffff disabled] because it overlaps 0000:c4:00.0 BAR 2 [mem 0x00000000-0x007fffff 64bit pref]
[   80.476537] pnp 00:0b: disabling [mem 0x00100000-0xffffffff] because it overlaps 0000:c4:00.0 BAR 2 [mem 0x00000000-0x007fffff 64bit pref]
[   80.496584] pnp 00:0b: disabling [mem 0x00000000-0x0009ffff disabled] because it overlaps 0000:c4:00.0 BAR 4 [mem 0x00000000-0x0fffffff 64bit pref]
[   80.516724] pnp 00:0b: disabling [mem 0x000c0000-0x000cffff disabled] because it overlaps 0000:c4:00.0 BAR 4 [mem 0x00000000-0x0fffffff 64bit pref]
[   80.536892] pnp 00:0b: disabling [mem 0x000e0000-0x000fffff disabled] because it overlaps 0000:c4:00.0 BAR 4 [mem 0x00000000-0x0fffffff 64bit pref]
[   80.576556] pnp 00:0b: disabling [mem 0x00100000-0xffffffff disabled] because it overlaps 0000:c4:00.0 BAR 4 [mem 0x00000000-0x0fffffff 64bit pref]
[   80.597519] pnp 00:0b: Plug and Play ACPI device, IDs PNP0c01 (active)
[   80.598653] pnp 00:0c: [bus 40-7f]
[   80.616111] pnp 00:0c: [io  0x0000 window]
[   80.616464] pnp 00:0c: [io  0x0000 window]
[   80.616826] pnp 00:0c: [io  0x6000-0x9fff window]
[   80.636240] pnp 00:0c: [mem 0x00000000 window]
[   80.636525] pnp 00:0c: [mem 0x00000000 window]
[   80.655911] pnp 00:0c: [mem 0xb0000000-0xcfffffff window]
[   80.656462] pnp 00:0c: [mem 0x00000000-0xffffffff window]
[   80.675917] pnp 00:0c: [mem 0xfc080000000-0xfc0ffffffff window]
[   80.676936] pnp 00:0c: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
[   80.697473] pnp 00:0d: Plug and Play ACPI device, IDs PNP0c01 (active)
[   80.698718] pnp 00:0e: [bus 80-bf]
[   80.715901] pnp 00:0e: [io  0x0000 window]
[   80.716215] pnp 00:0e: [io  0x0000 window]
[   80.716604] pnp 00:0e: [io  0xa000-0xdfff window]
[   80.735981] pnp 00:0e: [mem 0x00000000 window]
[   80.736349] pnp 00:0e: [mem 0x00000000 window]
[   80.755714] pnp 00:0e: [mem 0xd0000000-0xefffffff window]
[   80.756197] pnp 00:0e: [mem 0x00000000-0xffffffff window]
[   80.775696] pnp 00:0e: [mem 0xfc100000000-0xfc17fffffff window]
[   80.776768] pnp 00:0e: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
[   80.797339] pnp 00:0f: Plug and Play ACPI device, IDs PNP0c01 (active)
[   80.798666] pnp 00:10: [bus c0-f7]
[   80.815710] pnp 00:10: [io  0x0000 window]
[   80.816075] pnp 00:10: [io  0x0000 window]
[   80.816527] pnp 00:10: [io  0xe000-0xffff window]
[   80.835833] pnp 00:10: [mem 0x00000000 window]
[   80.836145] pnp 00:10: [mem 0x00000000 window]
[   80.855581] pnp 00:10: [mem 0xf0000000-0xfbffffff window]
[   80.856100] pnp 00:10: [mem 0x00000000-0xffffffff window]
[   80.875531] pnp 00:10: [mem 0xfc180000000-0xfc1ffffffff window]
[   80.876551] pnp 00:10: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
[   80.897293] pnp 00:11: Plug and Play ACPI device, IDs PNP0c01 (active)
[   80.898293] pnp: PnP ACPI: found 18 devices
[   80.915724] ACPI: ACPI bus type pnp unregistered
[   80.916140] initcall pnpacpi_init+0x0/0x8c returned 0 after 1680029 usecs

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-11  3:50                                     ` Yinghai Lu
  2010-10-11  3:50                                       ` Yinghai Lu
@ 2010-10-11  8:16                                       ` Thomas Gleixner
  2010-10-11 11:34                                         ` Benjamin Herrenschmidt
  2010-10-11 16:19                                         ` Yinghai Lu
  1 sibling, 2 replies; 158+ messages in thread
From: Thomas Gleixner @ 2010-10-11  8:16 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman, Suresh Siddha

On Sun, 10 Oct 2010, Yinghai Lu wrote:

> On 10/10/2010 02:32 AM, Thomas Gleixner wrote:
> > On Sat, 9 Oct 2010, Yinghai Lu wrote:
> >> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
> >>> On Fri, 8 Oct 2010, Yinghai Lu wrote:
> >>>> +	/* only handle fall out from setup_IO_APIC_irqs() */
> >>>
> >>> What's the fallout ? And why are we coming here in the first place
> >>> when the irq is < 16 ?
> >>
> >> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
> >>
> >> it seems IBM's system have apic_id == 1, and sci irq is using 30.
> >>
> >> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
> >> but it seems we set that two time when irq < 16.
> >>
> >>>
> >>>> +	if (!((apic_id > 0) && (irq > 16)))
> >>>> +		return;
> > 
> > I added this into the queue, but simplified it to 
> > 
> >   if (apic_id == 0 || irq < NR_IRQS_LEGACY)
> > 
> > Folded in the other fix and pushed out an updated tree.
> 
> still have the irq_2_iommu_alloc warning from pnpacpi

Hmm, that's probably a problem for all legacy interrupts which are
never torn down once they are set up. And we set them all up during
early boot.

So either we special case the legacy area or remove the warning
alltogether.

Another option I discussed with Suresh recently is to remove the
allocator in intr_remapping.c and just embedd irq_2_iommu into
irq_cfg.

Thanks,

	tglx

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-11  8:16                                       ` Thomas Gleixner
@ 2010-10-11 11:34                                         ` Benjamin Herrenschmidt
  2010-10-11 16:19                                         ` Yinghai Lu
  1 sibling, 0 replies; 158+ messages in thread
From: Benjamin Herrenschmidt @ 2010-10-11 11:34 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Yinghai Lu, Grant Likely, Russell King - ARM Linux, LKML,
	linux-arch, Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Paul Mundt, David Woodhouse, Jesse Barnes, Eric W. Biederman,
	Suresh Siddha


> Hmm, that's probably a problem for all legacy interrupts which are
> never torn down once they are set up. And we set them all up during
> early boot.
> 
> So either we special case the legacy area or remove the warning
> alltogether.
> 
> Another option I discussed with Suresh recently is to remove the
> allocator in intr_remapping.c and just embedd irq_2_iommu into
> irq_cfg.

Just in case that's of use, on powerpc, we just special case the legacy
range. It's keep un-requestable unless somebody comes and explicitely
claims it (using a special flag for our virq scheme, typically only 8259
does it for us) and then we get 1:1 all pre-allocated and mostly
immutable.

Cheers,
Ben.

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-11  8:16                                       ` Thomas Gleixner
  2010-10-11 11:34                                         ` Benjamin Herrenschmidt
@ 2010-10-11 16:19                                         ` Yinghai Lu
  2010-10-11 16:19                                           ` Yinghai Lu
  1 sibling, 1 reply; 158+ messages in thread
From: Yinghai Lu @ 2010-10-11 16:19 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman, Suresh Siddha

On 10/11/2010 01:16 AM, Thomas Gleixner wrote:
> On Sun, 10 Oct 2010, Yinghai Lu wrote:
> 
>> On 10/10/2010 02:32 AM, Thomas Gleixner wrote:
>>> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>>>> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
>>>>> On Fri, 8 Oct 2010, Yinghai Lu wrote:
>>>>>> +	/* only handle fall out from setup_IO_APIC_irqs() */
>>>>>
>>>>> What's the fallout ? And why are we coming here in the first place
>>>>> when the irq is < 16 ?
>>>>
>>>> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
>>>>
>>>> it seems IBM's system have apic_id == 1, and sci irq is using 30.
>>>>
>>>> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
>>>> but it seems we set that two time when irq < 16.
>>>>
>>>>>
>>>>>> +	if (!((apic_id > 0) && (irq > 16)))
>>>>>> +		return;
>>>
>>> I added this into the queue, but simplified it to 
>>>
>>>   if (apic_id == 0 || irq < NR_IRQS_LEGACY)
>>>
>>> Folded in the other fix and pushed out an updated tree.
>>
>> still have the irq_2_iommu_alloc warning from pnpacpi
> 
> Hmm, that's probably a problem for all legacy interrupts which are
> never torn down once they are set up. And we set them all up during
> early boot.
> 
> So either we special case the legacy area or remove the warning
> alltogether.

or use pr_warning instead of WARN_ONCE?

> 
> Another option I discussed with Suresh recently is to remove the
> allocator in intr_remapping.c and just embedd irq_2_iommu into
> irq_cfg.

in setup_IO_APIC_irqs(), pin_programmed is not set.

                /*
                 * don't mark it in pin_programmed, so later acpi could
                 * set it correctly when irq < 16
                 */
                setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx),
                                  irq_polarity(idx));

because we found some systems have strange ioapic setting, their pci devices irq < 16.

Yinghai

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

* Re: [patch 00/47] Sparse irq rework
  2010-10-11 16:19                                         ` Yinghai Lu
@ 2010-10-11 16:19                                           ` Yinghai Lu
  0 siblings, 0 replies; 158+ messages in thread
From: Yinghai Lu @ 2010-10-11 16:19 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Grant Likely, Russell King - ARM Linux, LKML, linux-arch,
	Linus Torvalds, Andrew Morton, x86, Peter Zijlstra,
	Benjamin Herrenschmidt, Paul Mundt, David Woodhouse, Jesse Barnes,
	Eric W. Biederman, Suresh Siddha

On 10/11/2010 01:16 AM, Thomas Gleixner wrote:
> On Sun, 10 Oct 2010, Yinghai Lu wrote:
> 
>> On 10/10/2010 02:32 AM, Thomas Gleixner wrote:
>>> On Sat, 9 Oct 2010, Yinghai Lu wrote:
>>>> On 10/08/2010 11:34 PM, Thomas Gleixner wrote:
>>>>> On Fri, 8 Oct 2010, Yinghai Lu wrote:
>>>>>> +	/* only handle fall out from setup_IO_APIC_irqs() */
>>>>>
>>>>> What's the fallout ? And why are we coming here in the first place
>>>>> when the irq is < 16 ?
>>>>
>>>> setup_IO_APIC_irqs only handle apic_id == 0 or apic_id > 0 but irq < 16 via acpi override.
>>>>
>>>> it seems IBM's system have apic_id == 1, and sci irq is using 30.
>>>>
>>>> so at that time add that setup_IO_APIC_irq_extra() to workaround it.
>>>> but it seems we set that two time when irq < 16.
>>>>
>>>>>
>>>>>> +	if (!((apic_id > 0) && (irq > 16)))
>>>>>> +		return;
>>>
>>> I added this into the queue, but simplified it to 
>>>
>>>   if (apic_id == 0 || irq < NR_IRQS_LEGACY)
>>>
>>> Folded in the other fix and pushed out an updated tree.
>>
>> still have the irq_2_iommu_alloc warning from pnpacpi
> 
> Hmm, that's probably a problem for all legacy interrupts which are
> never torn down once they are set up. And we set them all up during
> early boot.
> 
> So either we special case the legacy area or remove the warning
> alltogether.

or use pr_warning instead of WARN_ONCE?

> 
> Another option I discussed with Suresh recently is to remove the
> allocator in intr_remapping.c and just embedd irq_2_iommu into
> irq_cfg.

in setup_IO_APIC_irqs(), pin_programmed is not set.

                /*
                 * don't mark it in pin_programmed, so later acpi could
                 * set it correctly when irq < 16
                 */
                setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx),
                                  irq_polarity(idx));

because we found some systems have strange ioapic setting, their pci devices irq < 16.

Yinghai

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

* Re: [patch 33/47] pci: Cleanup the irq_desc mess in msi
  2010-09-30 23:17 ` [patch 33/47] pci: Cleanup the irq_desc mess in msi Thomas Gleixner
@ 2010-10-11 17:08   ` Jesse Barnes
  2010-10-11 17:08     ` Jesse Barnes
  0 siblings, 1 reply; 158+ messages in thread
From: Jesse Barnes @ 2010-10-11 17:08 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Yinghai Lu, Grant Likely, Eric W. Biederman

On Thu, 30 Sep 2010 23:17:18 -0000
Thomas Gleixner <tglx@linutronix.de> wrote:

> Handing down irq_desc to msi just so that msi can access
> irq_desc.irq_data.msi_desc is a pretty stupid idea. The calling code
> can hand down a pointer to msi_desc so msi code does not need to know
> about the irq descriptor at all.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---

Looks like a good cleanup.

Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center

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

* Re: [patch 33/47] pci: Cleanup the irq_desc mess in msi
  2010-10-11 17:08   ` Jesse Barnes
@ 2010-10-11 17:08     ` Jesse Barnes
  0 siblings, 0 replies; 158+ messages in thread
From: Jesse Barnes @ 2010-10-11 17:08 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Yinghai Lu, Grant Likely, Eric W. Biederman

On Thu, 30 Sep 2010 23:17:18 -0000
Thomas Gleixner <tglx@linutronix.de> wrote:

> Handing down irq_desc to msi just so that msi can access
> irq_desc.irq_data.msi_desc is a pretty stupid idea. The calling code
> can hand down a pointer to msi_desc so msi code does not need to know
> about the irq descriptor at all.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---

Looks like a good cleanup.

Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center

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

* Re: [patch 29/47] pci: Convert msi to new irq_chip functions
  2010-09-30 23:16 ` [patch 29/47] pci: Convert msi to new irq_chip functions Thomas Gleixner
  2010-09-30 23:16   ` Thomas Gleixner
@ 2010-10-11 17:09   ` Jesse Barnes
  2010-10-11 17:09     ` Jesse Barnes
  1 sibling, 1 reply; 158+ messages in thread
From: Jesse Barnes @ 2010-10-11 17:09 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Yinghai Lu, Grant Likely, Eric W. Biederman

On Thu, 30 Sep 2010 23:16:55 -0000
Thomas Gleixner <tglx@linutronix.de> wrote:

> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  arch/arm/mach-iop13xx/msi.c            |    8 ++++----
>  arch/ia64/kernel/msi_ia64.c            |    4 ++--
>  arch/ia64/sn/kernel/msi_sn.c           |    4 ++--
>  arch/powerpc/platforms/cell/axon_msi.c |    6 +++---
>  arch/powerpc/platforms/pseries/xics.c  |    2 +-
>  arch/powerpc/sysdev/fsl_msi.c          |    4 ++--
>  arch/powerpc/sysdev/mpic_pasemi_msi.c  |   22 +++++++++++-----------
>  arch/powerpc/sysdev/mpic_u3msi.c       |   16 ++++++++--------
>  arch/sparc/kernel/pci_msi.c            |    8 ++++----
>  arch/x86/kernel/apic/io_apic.c         |    8 ++++----
>  drivers/pci/msi.c                      |   14 +++++++-------
>  include/linux/msi.h                    |    5 +++--
>  12 files changed, 51 insertions(+), 50 deletions(-)

I like the MSI bits here too.

Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center

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

* Re: [patch 29/47] pci: Convert msi to new irq_chip functions
  2010-10-11 17:09   ` Jesse Barnes
@ 2010-10-11 17:09     ` Jesse Barnes
  0 siblings, 0 replies; 158+ messages in thread
From: Jesse Barnes @ 2010-10-11 17:09 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Linus Torvalds, Andrew Morton, x86,
	Peter Zijlstra, Benjamin Herrenschmidt, Paul Mundt, Russell King,
	David Woodhouse, Yinghai Lu, Grant Likely, Eric W. Biederman

On Thu, 30 Sep 2010 23:16:55 -0000
Thomas Gleixner <tglx@linutronix.de> wrote:

> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  arch/arm/mach-iop13xx/msi.c            |    8 ++++----
>  arch/ia64/kernel/msi_ia64.c            |    4 ++--
>  arch/ia64/sn/kernel/msi_sn.c           |    4 ++--
>  arch/powerpc/platforms/cell/axon_msi.c |    6 +++---
>  arch/powerpc/platforms/pseries/xics.c  |    2 +-
>  arch/powerpc/sysdev/fsl_msi.c          |    4 ++--
>  arch/powerpc/sysdev/mpic_pasemi_msi.c  |   22 +++++++++++-----------
>  arch/powerpc/sysdev/mpic_u3msi.c       |   16 ++++++++--------
>  arch/sparc/kernel/pci_msi.c            |    8 ++++----
>  arch/x86/kernel/apic/io_apic.c         |    8 ++++----
>  drivers/pci/msi.c                      |   14 +++++++-------
>  include/linux/msi.h                    |    5 +++--
>  12 files changed, 51 insertions(+), 50 deletions(-)

I like the MSI bits here too.

Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center

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

end of thread, other threads:[~2010-10-11 17:09 UTC | newest]

Thread overview: 158+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-30 23:14 [patch 00/47] Sparse irq rework Thomas Gleixner
2010-09-30 23:14 ` [patch 01/47] x86: Plug memory leak in sparse irq Thomas Gleixner
2010-09-30 23:14 ` [patch 02/47] x86: Hpet: Fix bogus error check in hpet_assign_irq() Thomas Gleixner
2010-09-30 23:14   ` Thomas Gleixner
2010-09-30 23:14 ` [patch 03/47] genirq: Provide status modifier Thomas Gleixner
2010-09-30 23:14   ` Thomas Gleixner
2010-09-30 23:14 ` [patch 04/47] arm: Use irq " Thomas Gleixner
2010-09-30 23:14   ` Thomas Gleixner
2010-09-30 23:14 ` [patch 05/47] genirq-sanitize-irq-data-accessors.patch Thomas Gleixner
2010-09-30 23:14   ` Thomas Gleixner
2010-09-30 23:15 ` [patch 06/47] genirq: Distangle kernel/irq/handle.c Thomas Gleixner
2010-09-30 23:15   ` Thomas Gleixner
2010-09-30 23:15 ` [patch 07/47] genirq: Remove early_init_irq_lock_class() Thomas Gleixner
2010-09-30 23:15   ` Thomas Gleixner
2010-09-30 23:15 ` [patch 08/47] genirq: Move core only inlines to kernel/irq Thomas Gleixner
2010-09-30 23:15 ` [patch 09/47] isdn: hisax: Replace the bogus access to irq stats Thomas Gleixner
2010-09-30 23:15   ` Thomas Gleixner
2010-09-30 23:15 ` [patch 10/47] genirq: Remove export of kstat_irqs_cpu Thomas Gleixner
2010-09-30 23:15 ` [patch 11/47] genirq: Provide default irq init flags Thomas Gleixner
2010-09-30 23:15   ` Thomas Gleixner
2010-09-30 23:15 ` [patch 12/47] arm: Use ARCH_IRQ_INIT_FLAGS Thomas Gleixner
2010-09-30 23:15 ` [patch 13/47] powerpc: " Thomas Gleixner
2010-09-30 23:15   ` Thomas Gleixner
2010-09-30 23:15 ` [patch 14/47] genirq: Implement a sane sparse_irq allocator Thomas Gleixner
2010-09-30 23:15   ` Thomas Gleixner
2010-10-01  5:28   ` Yinghai Lu
2010-10-01 20:36     ` Thomas Gleixner
2010-09-30 23:15 ` [patch 15/47] genirq: Prepare proc for real sparse irq support Thomas Gleixner
2010-09-30 23:15 ` [patch 16/47] genirq: Implement sane enumeration Thomas Gleixner
2010-09-30 23:15   ` Thomas Gleixner
2010-10-03 10:55   ` Grant Likely
2010-09-30 23:15 ` [patch 17/47] genirq-update-kerneldoc.patch Thomas Gleixner
2010-09-30 23:15   ` Thomas Gleixner
2010-09-30 23:16 ` [patch 18/47] genirq: Use sane sparse allocator Thomas Gleixner
2010-09-30 23:16   ` Thomas Gleixner
2010-09-30 23:16 ` [patch 19/47] genirq: Query arch for number of early descriptors Thomas Gleixner
2010-09-30 23:16   ` Thomas Gleixner
2010-09-30 23:16 ` [patch 20/47] x86: Remove useless reinitialization of irq descriptors Thomas Gleixner
2010-09-30 23:16   ` Thomas Gleixner
2010-10-03 15:21   ` Eric W. Biederman
2010-10-03 18:26     ` Thomas Gleixner
2010-09-30 23:16 ` [patch 21/47] x86: Sanitize apb timer interrupt handling Thomas Gleixner
2010-09-30 23:16   ` Thomas Gleixner
2010-09-30 23:16 ` [patch 22/47] x86: lguest: Convert to new irq chip functions Thomas Gleixner
2010-09-30 23:16 ` [patch 23/47] x86: Cleanup visws interrupt handling Thomas Gleixner
2010-09-30 23:16   ` Thomas Gleixner
2010-09-30 23:16 ` [patch 24/47] x86: i8259: Convert to new irq_chip functions Thomas Gleixner
2010-09-30 23:16   ` Thomas Gleixner
2010-09-30 23:16 ` [patch 25/47] x86: Cleanup io_apic Thomas Gleixner
2010-09-30 23:16 ` [patch 26/47] x86: io_apic: Convert startup to new irq_chip function Thomas Gleixner
2010-09-30 23:16   ` Thomas Gleixner
2010-09-30 23:16 ` [patch 27/47] x86: ioapic: Convert mask " Thomas Gleixner
2010-09-30 23:16 ` [patch 28/47] x86: ioapic/hpet: Convert to new chip functions Thomas Gleixner
2010-09-30 23:16   ` Thomas Gleixner
2010-09-30 23:16 ` [patch 29/47] pci: Convert msi to new irq_chip functions Thomas Gleixner
2010-09-30 23:16   ` Thomas Gleixner
2010-10-11 17:09   ` Jesse Barnes
2010-10-11 17:09     ` Jesse Barnes
2010-09-30 23:16 ` [patch 30/47] dmar: Convert to new irq chip functions Thomas Gleixner
2010-09-30 23:17 ` [patch 31/47] ht: Convert to new irq_chip functions Thomas Gleixner
2010-09-30 23:17   ` Thomas Gleixner
2010-09-30 23:17 ` [patch 32/47] x86: ioapic: Clean up the direct access to irq_desc Thomas Gleixner
2010-09-30 23:17   ` Thomas Gleixner
2010-09-30 23:17 ` [patch 33/47] pci: Cleanup the irq_desc mess in msi Thomas Gleixner
2010-10-11 17:08   ` Jesse Barnes
2010-10-11 17:08     ` Jesse Barnes
2010-09-30 23:17 ` [patch 34/47] x86: ioapic: Convert irq affinity to new chip functions Thomas Gleixner
2010-09-30 23:17 ` [patch 35/47] x86: ioapic: Cleanup some more Thomas Gleixner
2010-09-30 23:17 ` [patch 36/47] x86: ioapic: Cleanup sparse irq code Thomas Gleixner
2010-09-30 23:17   ` Thomas Gleixner
2010-09-30 23:17 ` [patch 37/47] x86: uv: Clean up the direct access to irq_desc Thomas Gleixner
2010-09-30 23:17 ` [patch 38/47] x86: Use sane enumeration Thomas Gleixner
2010-09-30 23:17 ` [patch 39/47] genirq: Remove arch_init_chip_data() Thomas Gleixner
2010-09-30 23:17 ` [patch 40/47] genirq: Sanitize dynamic irq handling Thomas Gleixner
2010-09-30 23:17   ` Thomas Gleixner
2010-10-01  5:47   ` Yinghai Lu
2010-09-30 23:18 ` [patch 41/47] arm: davinci: Cleanup irq_desc access Thomas Gleixner
2010-09-30 23:18   ` Thomas Gleixner
2010-09-30 23:18 ` [patch 42/47] genirq: Remove the now unused sparse irq leftovers Thomas Gleixner
2010-09-30 23:18   ` Thomas Gleixner
2010-09-30 23:18 ` [patch 43/47] x86: xen: Sanitise sparse_irq handling Thomas Gleixner
2010-09-30 23:18   ` Thomas Gleixner
2010-09-30 23:18 ` [patch 44/47] sh: Sanitize sparse irq Thomas Gleixner
2010-09-30 23:18 ` [patch 45/47] x86: lguest: Use new irq allocator Thomas Gleixner
2010-09-30 23:18   ` Thomas Gleixner
2010-09-30 23:18 ` [patch 46/47] powerpc: " Thomas Gleixner
2010-09-30 23:18   ` Thomas Gleixner
2010-10-01  0:42   ` Benjamin Herrenschmidt
2010-10-01 13:07     ` Thomas Gleixner
2010-10-01 20:46       ` Benjamin Herrenschmidt
2010-10-01 21:11         ` Grant Likely
2010-10-01 21:17           ` Benjamin Herrenschmidt
2010-10-03 16:53       ` Eric W. Biederman
2010-10-03 16:53         ` Eric W. Biederman
2010-10-03 18:34         ` Thomas Gleixner
2010-10-03 20:04           ` Thomas Gleixner
2010-10-03 22:54         ` Benjamin Herrenschmidt
2010-10-03 22:54           ` Benjamin Herrenschmidt
2010-10-04  0:15           ` Eric W. Biederman
2010-10-04  0:37             ` Benjamin Herrenschmidt
2010-10-04 16:46           ` Grant Likely
2010-09-30 23:18 ` [patch 47/47] genirq: Remove the old sparse irq allocator function Thomas Gleixner
2010-09-30 23:18   ` Thomas Gleixner
2010-10-01  3:32 ` [patch 00/47] Sparse irq rework Linus Torvalds
2010-10-01  3:32   ` Linus Torvalds
2010-10-01  5:54 ` Yinghai Lu
2010-10-01  5:54   ` Yinghai Lu
2010-10-01 20:35   ` Thomas Gleixner
2010-10-03 11:23 ` Grant Likely
2010-10-03 11:29   ` Russell King - ARM Linux
2010-10-03 11:29     ` Russell King - ARM Linux
2010-10-03 11:57     ` Grant Likely
2010-10-03 13:48       ` Thomas Gleixner
2010-10-05 10:22         ` Thomas Gleixner
2010-10-05 10:22           ` Thomas Gleixner
2010-10-06 22:45           ` Yinghai Lu
2010-10-06 22:52             ` Thomas Gleixner
2010-10-06 23:37               ` Yinghai Lu
2010-10-07  0:16                 ` Yinghai Lu
2010-10-07  4:01                   ` Thomas Gleixner
2010-10-07  4:38                     ` Yinghai Lu
2010-10-08 21:50                       ` Thomas Gleixner
2010-10-08 21:54                         ` Thomas Gleixner
2010-10-09  4:26                           ` Yinghai Lu
2010-10-09  5:44                             ` Yinghai Lu
2010-10-09  6:34                               ` Thomas Gleixner
2010-10-09  7:08                                 ` Yinghai Lu
2010-10-09  7:08                                   ` Yinghai Lu
2010-10-09 12:08                                   ` Thomas Gleixner
2010-10-10  9:32                                   ` Thomas Gleixner
2010-10-10  9:32                                     ` Thomas Gleixner
2010-10-10 13:30                                     ` Anca Emanuel
2010-10-11  2:20                                     ` Yinghai Lu
2010-10-11  2:20                                       ` Yinghai Lu
2010-10-11  3:50                                     ` Yinghai Lu
2010-10-11  3:50                                       ` Yinghai Lu
2010-10-11  8:16                                       ` Thomas Gleixner
2010-10-11 11:34                                         ` Benjamin Herrenschmidt
2010-10-11 16:19                                         ` Yinghai Lu
2010-10-11 16:19                                           ` Yinghai Lu
2010-10-09  6:10                             ` Thomas Gleixner
2010-10-09  7:03                               ` Yinghai Lu
2010-10-09 12:12                                 ` Thomas Gleixner
2010-10-10  2:32                                   ` Yinghai Lu
2010-10-10  2:32                                     ` Yinghai Lu
2010-10-10  5:11                                   ` Yinghai Lu
2010-10-10  5:11                                     ` Yinghai Lu
2010-10-10  8:20                                     ` Thomas Gleixner
2010-10-03 16:41 ` Eric W. Biederman
2010-10-03 16:41   ` Eric W. Biederman
2010-10-03 19:16   ` Thomas Gleixner
2010-10-03 22:57     ` Benjamin Herrenschmidt
2010-10-04 16:31       ` Grant Likely
2010-10-04  0:49     ` Eric W. Biederman
2010-10-04  8:05       ` Thomas Gleixner
2010-10-04  1:13     ` Eric W. Biederman
2010-10-04  1:13       ` Eric W. Biederman
2010-10-04  6:36       ` Ingo Molnar

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