2015-06-01 08:03:51

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 00/36] Split struct irq_data into common part and per-chip part

Hi all,
Now the irq core supports hierarchy irq and stacked irqchips,
so there may be multiple irq_datas associated with the same irq. But
some fields in struct irq_data are per-irq instance and duplicating
those fields into multiple irq_data may cause troubles.
So this patch introduces a new data structure 'struct
irq_common_data' to host per-irq instance data fields, and struct
irq_data will only host per-chip data fields after the conversion.

It's based on tip/x86/apic.

And it passes Fengguang's zeroday test suite.

V2->V3:
1) Add patch 1-2 to fix a regression revealed by this patch set.
It caused me about ten days to shoot down this bug, and it also
proves that this patch set is the right thing to do.
2) Split changes into per-arch slices
3) Kill the last direct reference to data->common->handler_data
from file drivers/sh/intc/virq.c.

V1->V2:
1) Patch "net/mlx4: Cache irq_desc->affinity instead of irq_desc" is
still kept to avoid build failure. It may be dropped if Amir Vadai
changed related code.
2) Reorganize patches according to Thomas's suggestion.
3) Rename irq_data_get_msi() as irq_data_get_msi_desc().

Thanks!
Gerry

Jiang Liu (36):
genirq: Enhance irq_data_to_desc() to support hierarchy irqdomain
genirq: Fix crash caused by irq_move_irq() when hierarch irqdomain is
enabled
genirq: Introduce struct irq_common_data to host shared irq data
genirq: Introduce helper function irq_data_get_node()
x86, irq: Use accessor irq_data_get_node() to hide struct irq_data
detail
sh, irq: Use accessor irq_data_get_node() to hide struct irq_data
detail
genirq: Move field 'node' from struct irq_data into struct
irq_common_data
sparc, irq: Use helper irq_data_get_irq_handler_data() to hide
irq_desc details
x86, irq: Use helper irq_data_get_irq_handler_data() to hide irq_desc
details
x86, irq: Use helper irq_data_get_irq_handler_data() to hide irq_desc
details
sh, irq: Use helper irq_data_get_irq_handler_data() to hide irq_desc
details
genirq: Move field 'handler_data' from struct irq_data into struct
irq_common_data
mn10300: Fix incorrect use of data->affinity
genirq: Introduce helper function irq_data_get_affinity_mask()
alpha, irq: Use access helper irq_data_get_affinity_mask()
ARM, irq: Use access helper irq_data_get_affinity_mask()
ARM64, irq: Use access helper irq_data_get_affinity_mask()
blackfin, irq: Use access helper irq_data_get_affinity_mask()
IA64, irq: Use access helper irq_data_get_affinity_mask()
metag, irq: Use access helper irq_data_get_affinity_mask()
mips, irq: Use access helper irq_data_get_affinity_mask()
mn10300, irq: Use access helper irq_data_get_affinity_mask()
parisc, irq: Use access helper irq_data_get_affinity_mask()
powerpc, irq: Use access helper irq_data_get_affinity_mask()
sh, irq: Use access helper irq_data_get_affinity_mask()
sparc, irq: Use access helper irq_data_get_affinity_mask()
x86, irq: Use access helper irq_data_get_affinity_mask()
xtensa, irq: Use access helper irq_data_get_affinity_mask()
irqchip, irq: Use access helper irq_data_get_affinity_mask()
net/mlx4: Cache irq_desc->affinity instead of irq_desc
genirq: Move field 'affinity' from struct irq_data into struct
irq_common_data
genirq: Rename irq_data_get_msi() as irq_data_get_msi_desc()
genirq: Use helper function to access irq_data->msi_desc
genirq: Move field 'msi_desc' from struct irq_data into struct
irq_common_data
genirq: Pass irq_data to helper function
__irq_set_chip_handler_name_locked()
genirq: Optimize irq_data_to_desc() to avoid irq_to_desc() lookup

arch/alpha/kernel/irq.c | 2 +-
arch/arm/kernel/irq.c | 4 +-
arch/arm64/kernel/irq.c | 4 +-
arch/blackfin/mach-common/ints-priority.c | 3 +-
arch/ia64/kernel/iosapic.c | 8 +-
arch/ia64/kernel/irq.c | 6 +-
arch/ia64/kernel/msi_ia64.c | 6 +-
arch/ia64/sn/kernel/msi_sn.c | 4 +-
arch/metag/kernel/irq.c | 10 ++-
arch/mips/alchemy/common/irq.c | 4 +-
arch/mips/bcm63xx/irq.c | 2 +-
arch/mips/cavium-octeon/octeon-irq.c | 14 ++--
arch/mips/pmcs-msp71xx/msp_irq_cic.c | 3 +-
arch/mn10300/kernel/cevt-mn10300.c | 2 +-
arch/mn10300/kernel/irq.c | 13 +--
arch/parisc/kernel/irq.c | 12 +--
arch/powerpc/kernel/irq.c | 2 +-
arch/powerpc/sysdev/xics/ics-opal.c | 4 +-
arch/powerpc/sysdev/xics/ics-rtas.c | 4 +-
arch/sh/kernel/irq.c | 9 ++-
arch/sparc/kernel/irq_64.c | 27 ++++---
arch/sparc/kernel/leon_kernel.c | 6 +-
arch/sparc/kernel/sun4d_irq.c | 4 +-
arch/sparc/kernel/sun4m_irq.c | 6 +-
arch/tile/kernel/pci_gx.c | 2 +-
arch/x86/kernel/apic/io_apic.c | 2 +-
arch/x86/kernel/apic/msi.c | 2 +-
arch/x86/kernel/apic/vector.c | 13 ++-
arch/x86/kernel/hpet.c | 4 +-
arch/x86/kernel/irq.c | 5 +-
arch/x86/platform/uv/uv_irq.c | 2 +-
arch/xtensa/kernel/irq.c | 10 ++-
drivers/gpio/gpio-davinci.c | 2 +-
drivers/gpio/gpio-zynq.c | 9 +--
drivers/irqchip/irq-metag-ext.c | 5 +-
drivers/irqchip/irq-mips-gic.c | 13 ++-
drivers/net/ethernet/mellanox/mlx4/en_cq.c | 6 +-
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 5 +-
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 2 +-
drivers/parisc/iosapic.c | 2 +-
drivers/pci/host/pcie-designware.c | 2 +-
drivers/pci/msi.c | 4 +-
drivers/sh/intc/chip.c | 6 +-
drivers/sh/intc/virq.c | 12 +--
drivers/xen/events/events_base.c | 4 +-
include/linux/irq.h | 112 +++++++++++++++++---------
include/linux/irqdesc.h | 23 ++++--
kernel/irq/chip.c | 4 +-
kernel/irq/internals.h | 17 ++--
kernel/irq/irqdesc.c | 27 +++----
kernel/irq/irqdomain.c | 5 +-
kernel/irq/manage.c | 14 ++--
kernel/irq/migration.c | 9 ++-
kernel/irq/proc.c | 4 +-
54 files changed, 277 insertions(+), 209 deletions(-)

--
1.7.10.4


2015-06-01 08:04:01

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 01/36] genirq: Enhance irq_data_to_desc() to support hierarchy irqdomain

For irq associated with hierarchy irqdomains, there will be multiple
irq_datas for one irq_desc. So enhance irq_data_to_desc() to support
hierarchy irqdomain. Also export irq_data_to_desc() as an inline
function for later reuse.

Signed-off-by: Jiang Liu <[email protected]>
---
include/linux/irqdesc.h | 9 +++++++++
kernel/irq/internals.h | 2 --
2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index dd1109fb241e..a113a8dc7438 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -93,6 +93,15 @@ struct irq_desc {
extern struct irq_desc irq_desc[NR_IRQS];
#endif

+static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
+{
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+ return irq_to_desc(data->irq);
+#else
+ return container_of(data, struct irq_desc, irq_data);
+#endif
+}
+
static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc)
{
return &desc->irq_data;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index df553b0af936..b93d434e70bd 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -59,8 +59,6 @@ enum {
#include "debug.h"
#include "settings.h"

-#define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data)
-
extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
unsigned long flags);
extern void __disable_irq(struct irq_desc *desc, unsigned int irq);
--
1.7.10.4

2015-06-01 08:04:09

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 02/36] genirq: Fix crash caused by irq_move_irq() when hierarch irqdomain is enabled

Function irq_move_irq() and irq_move_masked_irq() expects that caller
passes the top-level irq_data to them when hierarchy irqdomain is
enabled. But that's not true when called by apic_ack_edge(), and then
causes null pointer dereference by idata->chip->irq_mask(idata).

Instead of fixing callers to passing top-level irq_data, this patch enhances
irq_move_irq()/irq_move_masked_irq() to accept any irq_data.

Signed-off-by: Jiang Liu <[email protected]>
---
kernel/irq/migration.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index ca3f4aaff707..dd203e276b07 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -7,7 +7,7 @@
void irq_move_masked_irq(struct irq_data *idata)
{
struct irq_desc *desc = irq_data_to_desc(idata);
- struct irq_chip *chip = idata->chip;
+ struct irq_chip *chip = desc->irq_data.chip;

if (likely(!irqd_is_setaffinity_pending(&desc->irq_data)))
return;
@@ -52,6 +52,13 @@ void irq_move_irq(struct irq_data *idata)
{
bool masked;

+ /*
+ * Get top level irq_data when CONFIG_IRQ_DOMAIN_HIERARCHY is enabled,
+ * and it should be optimized away when CONFIG_IRQ_DOMAIN_HIERARCHY is
+ * disabled. So we avoid an "#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY" here.
+ */
+ idata = irq_desc_get_irq_data(irq_data_to_desc(idata));
+
if (likely(!irqd_is_setaffinity_pending(idata)))
return;

--
1.7.10.4

2015-06-01 08:04:25

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 03/36] genirq: Introduce struct irq_common_data to host shared irq data

With introduction of hierarchy irqdomain, struct irq_data becomes
per-chip instead of per-irq and there may be multiple irq_datas
associated with the same irq. Some per-irq data stored in
struct irq_data now may get duplicated into multiple irq_datas,
and causes inconsistent view.

So introduce struct irq_common_data to host per-irq common data and to
achieve consistent view among irq_chips.

Other patches in this patch set will move common fields from
struct irq_data into struct irq_common_data one by one.

Signed-off-by: Jiang Liu <[email protected]>
---
include/linux/irq.h | 54 ++++++++++++++++++++++++++++-------------------
include/linux/irqdesc.h | 3 ++-
kernel/irq/internals.h | 10 ++++-----
kernel/irq/irqdesc.c | 1 +
kernel/irq/irqdomain.c | 1 +
5 files changed, 41 insertions(+), 28 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 48cb7d1aa58f..3c7fbe44edae 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -126,13 +126,21 @@ struct msi_desc;
struct irq_domain;

/**
- * struct irq_data - per irq and irq chip data passed down to chip functions
+ * struct irq_common_data - per irq data shared by all irqchips
+ * @state_use_accessors: status information for irq chip functions.
+ * Use accessor functions to deal with it
+ */
+struct irq_common_data {
+ unsigned int state_use_accessors;
+};
+
+/**
+ * struct irq_data - per irq chip data passed down to chip functions
* @mask: precomputed bitmask for accessing the chip registers
* @irq: interrupt number
* @hwirq: hardware interrupt number, local to the interrupt domain
* @node: node index useful for balancing
- * @state_use_accessors: status information for irq chip functions.
- * Use accessor functions to deal with it
+ * @common: point to data shared by all irqchips
* @chip: low level interrupt hardware access
* @domain: Interrupt translation domain; responsible for mapping
* between hwirq number and linux irq number.
@@ -153,7 +161,7 @@ struct irq_data {
unsigned int irq;
unsigned long hwirq;
unsigned int node;
- unsigned int state_use_accessors;
+ struct irq_common_data *common;
struct irq_chip *chip;
struct irq_domain *domain;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
@@ -166,7 +174,7 @@ struct irq_data {
};

/*
- * Bit masks for irq_data.state
+ * Bit masks for irq_common_data.state_use_accessors
*
* IRQD_TRIGGER_MASK - Mask for the trigger type bits
* IRQD_SETAFFINITY_PENDING - Affinity setting is pending
@@ -198,34 +206,36 @@ enum {
IRQD_WAKEUP_ARMED = (1 << 19),
};

+#define __irqd_to_state(d) ((d)->common->state_use_accessors)
+
static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_SETAFFINITY_PENDING;
+ return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING;
}

static inline bool irqd_is_per_cpu(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_PER_CPU;
+ return __irqd_to_state(d) & IRQD_PER_CPU;
}

static inline bool irqd_can_balance(struct irq_data *d)
{
- return !(d->state_use_accessors & (IRQD_PER_CPU | IRQD_NO_BALANCING));
+ return !(__irqd_to_state(d) & (IRQD_PER_CPU | IRQD_NO_BALANCING));
}

static inline bool irqd_affinity_was_set(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_AFFINITY_SET;
+ return __irqd_to_state(d) & IRQD_AFFINITY_SET;
}

static inline void irqd_mark_affinity_was_set(struct irq_data *d)
{
- d->state_use_accessors |= IRQD_AFFINITY_SET;
+ __irqd_to_state(d) |= IRQD_AFFINITY_SET;
}

static inline u32 irqd_get_trigger_type(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_TRIGGER_MASK;
+ return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
}

/*
@@ -233,43 +243,43 @@ static inline u32 irqd_get_trigger_type(struct irq_data *d)
*/
static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
{
- d->state_use_accessors &= ~IRQD_TRIGGER_MASK;
- d->state_use_accessors |= type & IRQD_TRIGGER_MASK;
+ __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
+ __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
}

static inline bool irqd_is_level_type(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_LEVEL;
+ return __irqd_to_state(d) & IRQD_LEVEL;
}

static inline bool irqd_is_wakeup_set(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_WAKEUP_STATE;
+ return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
}

static inline bool irqd_can_move_in_process_context(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_MOVE_PCNTXT;
+ return __irqd_to_state(d) & IRQD_MOVE_PCNTXT;
}

static inline bool irqd_irq_disabled(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_IRQ_DISABLED;
+ return __irqd_to_state(d) & IRQD_IRQ_DISABLED;
}

static inline bool irqd_irq_masked(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_IRQ_MASKED;
+ return __irqd_to_state(d) & IRQD_IRQ_MASKED;
}

static inline bool irqd_irq_inprogress(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_IRQ_INPROGRESS;
+ return __irqd_to_state(d) & IRQD_IRQ_INPROGRESS;
}

static inline bool irqd_is_wakeup_armed(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_WAKEUP_ARMED;
+ return __irqd_to_state(d) & IRQD_WAKEUP_ARMED;
}


@@ -280,12 +290,12 @@ static inline bool irqd_is_wakeup_armed(struct irq_data *d)
*/
static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
{
- d->state_use_accessors |= IRQD_IRQ_INPROGRESS;
+ __irqd_to_state(d) |= IRQD_IRQ_INPROGRESS;
}

static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
{
- d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS;
+ __irqd_to_state(d) &= ~IRQD_IRQ_INPROGRESS;
}

static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index a113a8dc7438..c52d1480f272 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -17,7 +17,7 @@ struct pt_regs;

/**
* struct irq_desc - interrupt descriptor
- * @irq_data: per irq and chip data passed down to chip functions
+ * @irq_common_data: per irq and chip data passed down to chip functions
* @kstat_irqs: irq stats per cpu
* @handle_irq: highlevel irq-events handler
* @preflow_handler: handler called before the flow handler (currently used by sparc)
@@ -47,6 +47,7 @@ struct pt_regs;
* @name: flow handler name for /proc/interrupts output
*/
struct irq_desc {
+ struct irq_common_data irq_common_data;
struct irq_data irq_data;
unsigned int __percpu *kstat_irqs;
irq_flow_handler_t handle_irq;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index b93d434e70bd..a1ed80d11800 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -168,27 +168,27 @@ irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags)
*/
static inline void irqd_set_move_pending(struct irq_data *d)
{
- d->state_use_accessors |= IRQD_SETAFFINITY_PENDING;
+ __irqd_to_state(d) |= IRQD_SETAFFINITY_PENDING;
}

static inline void irqd_clr_move_pending(struct irq_data *d)
{
- d->state_use_accessors &= ~IRQD_SETAFFINITY_PENDING;
+ __irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING;
}

static inline void irqd_clear(struct irq_data *d, unsigned int mask)
{
- d->state_use_accessors &= ~mask;
+ __irqd_to_state(d) &= ~mask;
}

static inline void irqd_set(struct irq_data *d, unsigned int mask)
{
- d->state_use_accessors |= mask;
+ __irqd_to_state(d) |= mask;
}

static inline bool irqd_has_set(struct irq_data *d, unsigned int mask)
{
- return d->state_use_accessors & mask;
+ return __irqd_to_state(d) & mask;
}

static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc)
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 99793b9b6d23..eac1aac906ea 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -76,6 +76,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
{
int cpu;

+ desc->irq_data.common = &desc->irq_common_data;
desc->irq_data.irq = irq;
desc->irq_data.chip = &no_irq_chip;
desc->irq_data.chip_data = NULL;
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 7fac311057b8..3552b8750efd 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -834,6 +834,7 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
if (irq_data) {
child->parent_data = irq_data;
irq_data->irq = child->irq;
+ irq_data->common = child->common;
irq_data->node = child->node;
irq_data->domain = domain;
}
--
1.7.10.4

2015-06-01 08:04:33

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 04/36] genirq: Introduce helper function irq_data_get_node()

Introduce helper function irq_data_get_node() and friends to hide
struct irq_data implementation details.

Signed-off-by: Jiang Liu <[email protected]>
---
include/linux/irq.h | 5 +++++
kernel/irq/internals.h | 5 +++++
kernel/irq/irqdesc.c | 8 +-------
kernel/irq/irqdomain.c | 3 ++-
kernel/irq/manage.c | 2 +-
kernel/irq/proc.c | 2 +-
6 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 3c7fbe44edae..b3b82a5344c8 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -640,6 +640,11 @@ static inline u32 irq_get_trigger_type(unsigned int irq)
return d ? irqd_get_trigger_type(d) : 0;
}

+static inline int irq_data_get_node(struct irq_data *d)
+{
+ return d->node;
+}
+
unsigned int arch_dynirq_lower_bound(unsigned int from);

int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index a1ed80d11800..4834ee828c41 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -197,6 +197,11 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *d
__this_cpu_inc(kstat.irqs_sum);
}

+static inline int irq_desc_get_node(struct irq_desc *desc)
+{
+ return irq_data_get_node(&desc->irq_data);
+}
+
#ifdef CONFIG_PM_SLEEP
bool irq_pm_check_wakeup(struct irq_desc *desc);
void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index eac1aac906ea..b18d3f1d73d9 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -59,16 +59,10 @@ static void desc_smp_init(struct irq_desc *desc, int node)
#endif
}

-static inline int desc_node(struct irq_desc *desc)
-{
- return desc->irq_data.node;
-}
-
#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) { }
-static inline int desc_node(struct irq_desc *desc) { return 0; }
#endif

static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
@@ -300,7 +294,7 @@ static void free_desc(unsigned int irq)
unsigned long flags;

raw_spin_lock_irqsave(&desc->lock, flags);
- desc_set_defaults(irq, desc, desc_node(desc), NULL);
+ desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL);
raw_spin_unlock_irqrestore(&desc->lock, flags);
}

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 3552b8750efd..1b06dfed4574 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -830,7 +830,8 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
{
struct irq_data *irq_data;

- irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL, child->node);
+ irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL,
+ irq_data_get_node(child));
if (irq_data) {
child->parent_data = irq_data;
irq_data->irq = child->irq;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index b1c7e8f46bfb..f9744853b656 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -363,7 +363,7 @@ static int
setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
{
struct cpumask *set = irq_default_affinity;
- int node = desc->irq_data.node;
+ int node = irq_desc_get_node(desc);

/* Excludes PER_CPU and NO_BALANCE interrupts */
if (!irq_can_set_affinity(irq))
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index df2f4642d1e7..0e97c142ce40 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -241,7 +241,7 @@ static int irq_node_proc_show(struct seq_file *m, void *v)
{
struct irq_desc *desc = irq_to_desc((long) m->private);

- seq_printf(m, "%d\n", desc->irq_data.node);
+ seq_printf(m, "%d\n", irq_desc_get_node(desc));
return 0;
}

--
1.7.10.4

2015-06-01 08:05:10

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 05/36] x86, irq: Use accessor irq_data_get_node() to hide struct irq_data detail

Use accessor irq_data_get_node() to hide struct irq_data implementation
detail, so we could easily reconstruct struct irq_data later.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/x86/kernel/apic/vector.c | 8 ++++----
arch/x86/platform/uv/uv_irq.c | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 28eba2d38b15..9b62f690b0ff 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -296,7 +296,7 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
struct irq_alloc_info *info = arg;
struct apic_chip_data *data;
struct irq_data *irq_data;
- int i, err;
+ int i, err, node;

if (disable_apic)
return -ENXIO;
@@ -308,12 +308,13 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
for (i = 0; i < nr_irqs; i++) {
irq_data = irq_domain_get_irq_data(domain, virq + i);
BUG_ON(!irq_data);
+ node = irq_data_get_node(irq_data);
#ifdef CONFIG_X86_IO_APIC
if (virq + i < nr_legacy_irqs() && legacy_irq_data[virq + i])
data = legacy_irq_data[virq + i];
else
#endif
- data = alloc_apic_chip_data(irq_data->node);
+ data = alloc_apic_chip_data(node);
if (!data) {
err = -ENOMEM;
goto error;
@@ -322,8 +323,7 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
irq_data->chip = &lapic_controller;
irq_data->chip_data = data;
irq_data->hwirq = virq + i;
- err = assign_irq_vector_policy(virq, irq_data->node, data,
- info);
+ err = assign_irq_vector_policy(virq, node, data, info);
if (err)
goto error;
}
diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c
index 8570abe68be1..e1c24631afbb 100644
--- a/arch/x86/platform/uv/uv_irq.c
+++ b/arch/x86/platform/uv/uv_irq.c
@@ -89,7 +89,7 @@ static int uv_domain_alloc(struct irq_domain *domain, unsigned int virq,
return -EINVAL;

chip_data = kmalloc_node(sizeof(*chip_data), GFP_KERNEL,
- irq_data->node);
+ irq_data_get_node(irq_data));
if (!chip_data)
return -ENOMEM;

--
1.7.10.4

2015-06-01 08:04:52

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 06/36] sh, irq: Use accessor irq_data_get_node() to hide struct irq_data detail

Use accessor irq_data_get_node() to hide struct irq_data implementation
detail, so we could easily reconstruct struct irq_data later.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/sh/kernel/irq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index eb10ff84015c..8dc677cc136b 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -227,7 +227,7 @@ void migrate_irqs(void)
for_each_active_irq(irq) {
struct irq_data *data = irq_get_irq_data(irq);

- if (data->node == cpu) {
+ if (irq_data_get_node(data) == cpu) {
unsigned int newcpu = cpumask_any_and(data->affinity,
cpu_online_mask);
if (newcpu >= nr_cpu_ids) {
--
1.7.10.4

2015-06-01 08:05:03

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 07/36] genirq: Move field 'node' from struct irq_data into struct irq_common_data

NUMA node information is per-irq instead of per-irqchip, so move it into
struct irq_common_data. Also use CONFIG_NUMA to guard irq_common_data.node.

Signed-off-by: Jiang Liu <[email protected]>
---
include/linux/irq.h | 17 ++++++++++++++---
kernel/irq/internals.h | 2 +-
kernel/irq/irqdesc.c | 4 +++-
kernel/irq/irqdomain.c | 1 -
4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index b3b82a5344c8..bcedf9f952d4 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -129,9 +129,13 @@ struct irq_domain;
* struct irq_common_data - per irq data shared by all irqchips
* @state_use_accessors: status information for irq chip functions.
* Use accessor functions to deal with it
+ * @node: node index useful for balancing
*/
struct irq_common_data {
unsigned int state_use_accessors;
+#ifdef CONFIG_NUMA
+ unsigned int node;
+#endif
};

/**
@@ -139,7 +143,6 @@ struct irq_common_data {
* @mask: precomputed bitmask for accessing the chip registers
* @irq: interrupt number
* @hwirq: hardware interrupt number, local to the interrupt domain
- * @node: node index useful for balancing
* @common: point to data shared by all irqchips
* @chip: low level interrupt hardware access
* @domain: Interrupt translation domain; responsible for mapping
@@ -160,7 +163,6 @@ struct irq_data {
u32 mask;
unsigned int irq;
unsigned long hwirq;
- unsigned int node;
struct irq_common_data *common;
struct irq_chip *chip;
struct irq_domain *domain;
@@ -640,9 +642,18 @@ static inline u32 irq_get_trigger_type(unsigned int irq)
return d ? irqd_get_trigger_type(d) : 0;
}

-static inline int irq_data_get_node(struct irq_data *d)
+static inline int irq_common_data_get_node(struct irq_common_data *d)
{
+#ifdef CONFIG_NUMA
return d->node;
+#else
+ return 0;
+#endif
+}
+
+static inline int irq_data_get_node(struct irq_data *d)
+{
+ return irq_common_data_get_node(d->common);
}

unsigned int arch_dynirq_lower_bound(unsigned int from);
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 4834ee828c41..b117e4c243d8 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -199,7 +199,7 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *d

static inline int irq_desc_get_node(struct irq_desc *desc)
{
- return irq_data_get_node(&desc->irq_data);
+ return irq_common_data_get_node(&desc->irq_common_data);
}

#ifdef CONFIG_PM_SLEEP
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index b18d3f1d73d9..0c3057e42906 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -52,11 +52,13 @@ static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)

static void desc_smp_init(struct irq_desc *desc, int node)
{
- desc->irq_data.node = node;
cpumask_copy(desc->irq_data.affinity, irq_default_affinity);
#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_clear(desc->pending_mask);
#endif
+#ifdef CONFIG_NUMA
+ desc->irq_common_data.node = node;
+#endif
}

#else
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 1b06dfed4574..93ef89059022 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -836,7 +836,6 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
child->parent_data = irq_data;
irq_data->irq = child->irq;
irq_data->common = child->common;
- irq_data->node = child->node;
irq_data->domain = domain;
}

--
1.7.10.4

2015-06-01 08:05:34

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 08/36] sparc, irq: Use helper irq_data_get_irq_handler_data() to hide irq_desc details

Use helper function irq_data_get_irq_handler_data() to hide irq_desc
implementation details.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/sparc/kernel/irq_64.c | 15 +++++++++------
arch/sparc/kernel/sun4d_irq.c | 4 ++--
arch/sparc/kernel/sun4m_irq.c | 6 ++++--
3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 4033c23bdfa6..5130f6e3e68e 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -210,21 +210,21 @@ struct irq_handler_data {

static inline unsigned int irq_data_to_handle(struct irq_data *data)
{
- struct irq_handler_data *ihd = data->handler_data;
+ struct irq_handler_data *ihd = irq_data_get_irq_handler_data(data);

return ihd->dev_handle;
}

static inline unsigned int irq_data_to_ino(struct irq_data *data)
{
- struct irq_handler_data *ihd = data->handler_data;
+ struct irq_handler_data *ihd = irq_data_get_irq_handler_data(data);

return ihd->dev_ino;
}

static inline unsigned long irq_data_to_sysino(struct irq_data *data)
{
- struct irq_handler_data *ihd = data->handler_data;
+ struct irq_handler_data *ihd = irq_data_get_irq_handler_data(data);

return ihd->sysino;
}
@@ -370,8 +370,9 @@ static int irq_choose_cpu(unsigned int irq, const struct cpumask *affinity)

static void sun4u_irq_enable(struct irq_data *data)
{
- struct irq_handler_data *handler_data = data->handler_data;
+ struct irq_handler_data *handler_data;

+ handler_data = irq_data_get_irq_handler_data(data);
if (likely(handler_data)) {
unsigned long cpuid, imap, val;
unsigned int tid;
@@ -393,8 +394,9 @@ static void sun4u_irq_enable(struct irq_data *data)
static int sun4u_set_affinity(struct irq_data *data,
const struct cpumask *mask, bool force)
{
- struct irq_handler_data *handler_data = data->handler_data;
+ struct irq_handler_data *handler_data;

+ handler_data = irq_data_get_irq_handler_data(data);
if (likely(handler_data)) {
unsigned long cpuid, imap, val;
unsigned int tid;
@@ -438,8 +440,9 @@ static void sun4u_irq_disable(struct irq_data *data)

static void sun4u_irq_eoi(struct irq_data *data)
{
- struct irq_handler_data *handler_data = data->handler_data;
+ struct irq_handler_data *handler_data;

+ handler_data = irq_data_get_irq_handler_data(data);
if (likely(handler_data))
upa_writeq(ICLR_IDLE, handler_data->iclr);
}
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index a1bb2675b280..a87d0e47c168 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -188,7 +188,7 @@ void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs)

static void sun4d_mask_irq(struct irq_data *data)
{
- struct sun4d_handler_data *handler_data = data->handler_data;
+ struct sun4d_handler_data *handler_data = irq_data_get_irq_handler_data(data);
unsigned int real_irq;
#ifdef CONFIG_SMP
int cpuid = handler_data->cpuid;
@@ -206,7 +206,7 @@ static void sun4d_mask_irq(struct irq_data *data)

static void sun4d_unmask_irq(struct irq_data *data)
{
- struct sun4d_handler_data *handler_data = data->handler_data;
+ struct sun4d_handler_data *handler_data = irq_data_get_irq_handler_data(data);
unsigned int real_irq;
#ifdef CONFIG_SMP
int cpuid = handler_data->cpuid;
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index 8bb3b3fddea7..da737c712fa8 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -188,9 +188,10 @@ static unsigned long sun4m_imask[0x50] = {

static void sun4m_mask_irq(struct irq_data *data)
{
- struct sun4m_handler_data *handler_data = data->handler_data;
+ struct sun4m_handler_data *handler_data;
int cpu = smp_processor_id();

+ handler_data = irq_data_get_irq_handler_data(data);
if (handler_data->mask) {
unsigned long flags;

@@ -206,9 +207,10 @@ static void sun4m_mask_irq(struct irq_data *data)

static void sun4m_unmask_irq(struct irq_data *data)
{
- struct sun4m_handler_data *handler_data = data->handler_data;
+ struct sun4m_handler_data *handler_data;
int cpu = smp_processor_id();

+ handler_data = irq_data_get_irq_handler_data(data);
if (handler_data->mask) {
unsigned long flags;

--
1.7.10.4

2015-06-01 08:18:49

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 09/36] x86, irq: Use helper irq_data_get_irq_handler_data() to hide irq_desc details

Use helper function irq_data_get_irq_handler_data() to hide irq_desc
implementation details.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/x86/kernel/apic/msi.c | 2 +-
arch/x86/kernel/hpet.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 1a9d735e09c6..5f1feb6854af 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -264,7 +264,7 @@ static inline int hpet_dev_id(struct irq_domain *domain)

static void hpet_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
{
- hpet_msi_write(data->handler_data, msg);
+ hpet_msi_write(irq_data_get_irq_handler_data(data), msg);
}

static struct irq_chip hpet_msi_controller = {
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index e2449cf38b06..40cf79a55fe7 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -426,7 +426,7 @@ static struct irq_domain *hpet_domain;

void hpet_msi_unmask(struct irq_data *data)
{
- struct hpet_dev *hdev = data->handler_data;
+ struct hpet_dev *hdev = irq_data_get_irq_handler_data(data);
unsigned int cfg;

/* unmask it */
@@ -437,7 +437,7 @@ void hpet_msi_unmask(struct irq_data *data)

void hpet_msi_mask(struct irq_data *data)
{
- struct hpet_dev *hdev = data->handler_data;
+ struct hpet_dev *hdev = irq_data_get_irq_handler_data(data);
unsigned int cfg;

/* mask it */
--
1.7.10.4

2015-06-01 08:05:50

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 10/36] x86, irq: Use helper irq_data_get_irq_handler_data() to hide irq_desc details

Use helper function irq_data_get_irq_handler_data() to hide irq_desc
implementation details.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/gpio/gpio-davinci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
index c5e05c82d67c..477d5b8616ab 100644
--- a/drivers/gpio/gpio-davinci.c
+++ b/drivers/gpio/gpio-davinci.c
@@ -396,7 +396,7 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger)
struct davinci_gpio_regs __iomem *g;
u32 mask;

- d = (struct davinci_gpio_controller *)data->handler_data;
+ d = (struct davinci_gpio_controller *)irq_data_get_irq_handler_data(data);
g = (struct davinci_gpio_regs __iomem *)d->regs;
mask = __gpio_mask(data->irq - d->gpio_irq);

--
1.7.10.4

2015-06-01 08:19:32

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 11/36] sh, irq: Use helper irq_data_get_irq_handler_data() to hide irq_desc details

Use helper function irq_data_get_irq_handler_data() to hide irq_desc
implementation details.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/sh/intc/virq.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c
index f30ac9354ff2..bc0601cf0f8f 100644
--- a/drivers/sh/intc/virq.c
+++ b/drivers/sh/intc/virq.c
@@ -83,12 +83,11 @@ EXPORT_SYMBOL_GPL(intc_irq_lookup);

static int add_virq_to_pirq(unsigned int irq, unsigned int virq)
{
- struct intc_virq_list **last, *entry;
- struct irq_data *data = irq_get_irq_data(irq);
+ struct intc_virq_list *entry;
+ struct intc_virq_list **last = NULL;

/* scan for duplicates */
- last = (struct intc_virq_list **)&data->handler_data;
- for_each_virq(entry, data->handler_data) {
+ for_each_virq(entry, irq_get_handler_data(irq)) {
if (entry->irq == virq)
return 0;
last = &entry->next;
@@ -102,7 +101,10 @@ static int add_virq_to_pirq(unsigned int irq, unsigned int virq)

entry->irq = virq;

- *last = entry;
+ if (last)
+ *last = entry;
+ else
+ irq_set_handler_data(irq, entry);

return 0;
}
--
1.7.10.4

2015-06-01 08:18:45

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 12/36] genirq: Move field 'handler_data' from struct irq_data into struct irq_common_data

Handler data (handler_data) is per-irq instead of per irqchip, so move
it into struct irq_common_data.

Signed-off-by: Jiang Liu <[email protected]>
---
include/linux/irq.h | 8 ++++----
include/linux/irqdesc.h | 2 +-
kernel/irq/chip.c | 2 +-
kernel/irq/irqdesc.c | 3 ++-
4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index bcedf9f952d4..68874efe19d3 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -130,12 +130,14 @@ struct irq_domain;
* @state_use_accessors: status information for irq chip functions.
* Use accessor functions to deal with it
* @node: node index useful for balancing
+ * @handler_data: per-IRQ data for the irq_chip methods
*/
struct irq_common_data {
unsigned int state_use_accessors;
#ifdef CONFIG_NUMA
unsigned int node;
#endif
+ void *handler_data;
};

/**
@@ -149,7 +151,6 @@ struct irq_common_data {
* between hwirq number and linux irq number.
* @parent_data: pointer to parent struct irq_data to support hierarchy
* irq_domain
- * @handler_data: per-IRQ data for the irq_chip methods
* @chip_data: platform-specific per-chip private data for the chip
* methods, to allow shared chip implementations
* @msi_desc: MSI descriptor
@@ -169,7 +170,6 @@ struct irq_data {
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
struct irq_data *parent_data;
#endif
- void *handler_data;
void *chip_data;
struct msi_desc *msi_desc;
cpumask_var_t affinity;
@@ -617,12 +617,12 @@ static inline void *irq_data_get_irq_chip_data(struct irq_data *d)
static inline void *irq_get_handler_data(unsigned int irq)
{
struct irq_data *d = irq_get_irq_data(irq);
- return d ? d->handler_data : NULL;
+ return d ? d->common->handler_data : NULL;
}

static inline void *irq_data_get_irq_handler_data(struct irq_data *d)
{
- return d->handler_data;
+ return d->common->handler_data;
}

static inline struct msi_desc *irq_get_msi_desc(unsigned int irq)
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index c52d1480f272..d46fd7eb7959 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -120,7 +120,7 @@ static inline void *irq_desc_get_chip_data(struct irq_desc *desc)

static inline void *irq_desc_get_handler_data(struct irq_desc *desc)
{
- return desc->irq_data.handler_data;
+ return desc->irq_common_data.handler_data;
}

static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 55016b2151f3..895de2ea4e32 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -83,7 +83,7 @@ int irq_set_handler_data(unsigned int irq, void *data)

if (!desc)
return -EINVAL;
- desc->irq_data.handler_data = data;
+ desc->irq_common_data.handler_data = data;
irq_put_desc_unlock(desc, flags);
return 0;
}
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 0c3057e42906..7f881792ad5f 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -72,11 +72,12 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
{
int cpu;

+ desc->irq_common_data.handler_data = NULL;
+
desc->irq_data.common = &desc->irq_common_data;
desc->irq_data.irq = irq;
desc->irq_data.chip = &no_irq_chip;
desc->irq_data.chip_data = NULL;
- desc->irq_data.handler_data = NULL;
desc->irq_data.msi_desc = NULL;
irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS);
irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
--
1.7.10.4

2015-06-01 08:06:24

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 13/36] mn10300: Fix incorrect use of data->affinity

The field affinity in struct irq_data is type of cpumask_var_t, so
we should pass in data->affinity instead of &data->affinity when
calling cpumask_xxxx().

Signed-off-by: Jiang Liu <[email protected]>
---
arch/mn10300/kernel/irq.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index 6ab3b73efcf8..480de70f4059 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -320,11 +320,11 @@ void migrate_irqs(void)
if (irqd_is_per_cpu(data))
continue;

- if (cpumask_test_cpu(self, &data->affinity) &&
+ if (cpumask_test_cpu(self, data->affinity) &&
!cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) {
int cpu_id;
cpu_id = cpumask_first(cpu_online_mask);
- cpumask_set_cpu(cpu_id, &data->affinity);
+ cpumask_set_cpu(cpu_id, data->affinity);
}
/* We need to operate irq_affinity_online atomically. */
arch_local_cli_save(flags);
@@ -335,7 +335,7 @@ void migrate_irqs(void)
GxICR(irq) = x & GxICR_LEVEL;
tmp = GxICR(irq);

- new = cpumask_any_and(&data->affinity,
+ new = cpumask_any_and(data->affinity,
cpu_online_mask);
irq_affinity_online[irq] = new;

--
1.7.10.4

2015-06-01 08:06:10

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 14/36] genirq: Introduce helper function irq_data_get_affinity_mask()

Introduce helper function irq_data_get_affinity_mask() and
irq_get_affinity_mask() to hide implementation details,
so we could move field 'affinity' from struct irq_data into
struct irq_common_data later.

Signed-off-by: Jiang Liu <[email protected]>
Acked-by: Russell King <[email protected]>
---
include/linux/irq.h | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 68874efe19d3..91fbf10bdae0 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -656,6 +656,18 @@ static inline int irq_data_get_node(struct irq_data *d)
return irq_common_data_get_node(d->common);
}

+static inline struct cpumask *irq_get_affinity_mask(int irq)
+{
+ struct irq_data *d = irq_get_irq_data(irq);
+
+ return d ? d->affinity : NULL;
+}
+
+static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
+{
+ return d->affinity;
+}
+
unsigned int arch_dynirq_lower_bound(unsigned int from);

int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
--
1.7.10.4

2015-06-01 08:18:01

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 15/36] alpha, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/alpha/kernel/irq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 7b2be251c30f..bd8e47699cad 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -60,7 +60,7 @@ int irq_select_affinity(unsigned int irq)
cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
last_cpu = cpu;

- cpumask_copy(data->affinity, cpumask_of(cpu));
+ cpumask_copy(irq_data_get_affinity_mask(data), cpumask_of(cpu));
chip->irq_set_affinity(data, cpumask_of(cpu), false);
return 0;
}
--
1.7.10.4

2015-06-01 08:06:19

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 16/36] ARM, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/arm/kernel/irq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 350f188c92d2..baf8edebe26f 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -140,7 +140,7 @@ int __init arch_probe_nr_irqs(void)
static bool migrate_one_irq(struct irq_desc *desc)
{
struct irq_data *d = irq_desc_get_irq_data(desc);
- const struct cpumask *affinity = d->affinity;
+ const struct cpumask *affinity = irq_data_get_affinity_mask(d);
struct irq_chip *c;
bool ret = false;

@@ -160,7 +160,7 @@ static bool migrate_one_irq(struct irq_desc *desc)
if (!c->irq_set_affinity)
pr_debug("IRQ%u: unable to set affinity\n", d->irq);
else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && ret)
- cpumask_copy(d->affinity, affinity);
+ cpumask_copy(irq_data_get_affinity_mask(d), affinity);

return ret;
}
--
1.7.10.4

2015-06-01 08:06:34

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 17/36] ARM64, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/arm64/kernel/irq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index 240b75c0e94f..463fa2e7e34c 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -61,7 +61,7 @@ void __init init_IRQ(void)
static bool migrate_one_irq(struct irq_desc *desc)
{
struct irq_data *d = irq_desc_get_irq_data(desc);
- const struct cpumask *affinity = d->affinity;
+ const struct cpumask *affinity = irq_data_get_affinity_mask(d);
struct irq_chip *c;
bool ret = false;

@@ -81,7 +81,7 @@ static bool migrate_one_irq(struct irq_desc *desc)
if (!c->irq_set_affinity)
pr_debug("IRQ%u: unable to set affinity\n", d->irq);
else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && ret)
- cpumask_copy(d->affinity, affinity);
+ cpumask_copy(irq_data_get_affinity_mask(d), affinity);

return ret;
}
--
1.7.10.4

2015-06-01 08:06:42

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 18/36] blackfin, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/blackfin/mach-common/ints-priority.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 7236bdfc71e6..332a434b4669 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -194,7 +194,8 @@ void bfin_internal_unmask_irq(unsigned int irq)
#ifdef CONFIG_SMP
static void bfin_internal_unmask_irq_chip(struct irq_data *d)
{
- bfin_internal_unmask_irq_affinity(d->irq, d->affinity);
+ bfin_internal_unmask_irq_affinity(d->irq,
+ irq_data_get_affinity_mask(d));
}

static int bfin_internal_set_affinity(struct irq_data *d,
--
1.7.10.4

2015-06-01 08:06:51

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 19/36] IA64, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/ia64/kernel/iosapic.c | 2 +-
arch/ia64/kernel/irq.c | 6 +++---
arch/ia64/kernel/msi_ia64.c | 4 ++--
arch/ia64/sn/kernel/msi_sn.c | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index bc9501e36e77..4d2698d43c39 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -838,7 +838,7 @@ iosapic_unregister_intr (unsigned int gsi)
if (iosapic_intr_info[irq].count == 0) {
#ifdef CONFIG_SMP
/* Clear affinity */
- cpumask_setall(irq_get_irq_data(irq)->affinity);
+ cpumask_setall(irq_get_affinity_mask(irq));
#endif
/* Clear the interrupt information */
iosapic_intr_info[irq].dest = 0;
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index 812a1e6b3179..de4fc00dea98 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -67,7 +67,7 @@ static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
{
if (irq < NR_IRQS) {
- cpumask_copy(irq_get_irq_data(irq)->affinity,
+ cpumask_copy(irq_get_affinity_mask(irq),
cpumask_of(cpu_logical_id(hwid)));
irq_redir[irq] = (char) (redir & 0xff);
}
@@ -119,8 +119,8 @@ static void migrate_irqs(void)
if (irqd_is_per_cpu(data))
continue;

- if (cpumask_any_and(data->affinity, cpu_online_mask)
- >= nr_cpu_ids) {
+ if (cpumask_any_and(irq_data_get_affinity_mask(data),
+ cpu_online_mask) >= nr_cpu_ids) {
/*
* Save it for phase 2 processing
*/
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index d70bf15c690a..6c50d332b7d7 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -36,7 +36,7 @@ static int ia64_set_msi_irq_affinity(struct irq_data *idata,
msg.data = data;

pci_write_msi_msg(irq, &msg);
- cpumask_copy(idata->affinity, cpumask_of(cpu));
+ cpumask_copy(irq_data_get_affinity_mask(idata), cpumask_of(cpu));

return 0;
}
@@ -148,7 +148,7 @@ static int dmar_msi_set_affinity(struct irq_data *data,
msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));

dmar_msi_write(irq, &msg);
- cpumask_copy(data->affinity, mask);
+ cpumask_copy(irq_data_get_affinity_mask(data), mask);

return 0;
}
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index a0eb27b66d13..42b5a13af142 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -206,7 +206,7 @@ static int sn_set_msi_irq_affinity(struct irq_data *data,
msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);

pci_write_msi_msg(irq, &msg);
- cpumask_copy(data->affinity, cpu_mask);
+ cpumask_copy(irq_data_get_affinity_mask(data), cpu_mask);

return 0;
}
--
1.7.10.4

2015-06-01 08:07:14

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 20/36] metag, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/metag/kernel/irq.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/metag/kernel/irq.c b/arch/metag/kernel/irq.c
index 4f8f1f87ef11..a336094a7a6c 100644
--- a/arch/metag/kernel/irq.c
+++ b/arch/metag/kernel/irq.c
@@ -270,23 +270,25 @@ void migrate_irqs(void)

for_each_active_irq(i) {
struct irq_data *data = irq_get_irq_data(i);
+ struct cpumask *mask;
unsigned int newcpu;

if (irqd_is_per_cpu(data))
continue;

- if (!cpumask_test_cpu(cpu, data->affinity))
+ mask = irq_data_get_affinity_mask(data);
+ if (!cpumask_test_cpu(cpu, mask))
continue;

- newcpu = cpumask_any_and(data->affinity, cpu_online_mask);
+ newcpu = cpumask_any_and(mask, cpu_online_mask);

if (newcpu >= nr_cpu_ids) {
pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n",
i, cpu);

- cpumask_setall(data->affinity);
+ cpumask_setall(mask);
}
- irq_set_affinity(i, data->affinity);
+ irq_set_affinity(i, mask);
}
}
#endif /* CONFIG_HOTPLUG_CPU */
--
1.7.10.4

2015-06-01 08:07:20

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 21/36] mips, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/mips/bcm63xx/irq.c | 2 +-
arch/mips/cavium-octeon/octeon-irq.c | 14 ++++++++------
arch/mips/pmcs-msp71xx/msp_irq_cic.c | 3 ++-
3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index e3e808a6c542..02983b90826d 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -60,7 +60,7 @@ static inline int enable_irq_for_cpu(int cpu, struct irq_data *d,
if (m)
enable &= cpumask_test_cpu(cpu, m);
else if (irqd_affinity_was_set(d))
- enable &= cpumask_test_cpu(cpu, d->affinity);
+ enable &= cpumask_test_cpu(cpu, irq_data_get_affinity_mask(d));
#endif
return enable;
}
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 10f762557b92..0643ae614284 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -225,13 +225,14 @@ static int next_cpu_for_irq(struct irq_data *data)

#ifdef CONFIG_SMP
int cpu;
- int weight = cpumask_weight(data->affinity);
+ struct cpumask *mask = irq_data_get_affinity_mask(data);
+ int weight = cpumask_weight(mask);
struct octeon_ciu_chip_data *cd = irq_data_get_irq_chip_data(data);

if (weight > 1) {
cpu = cd->current_cpu;
for (;;) {
- cpu = cpumask_next(cpu, data->affinity);
+ cpu = cpumask_next(cpu, mask);
if (cpu >= nr_cpu_ids) {
cpu = -1;
continue;
@@ -240,7 +241,7 @@ static int next_cpu_for_irq(struct irq_data *data)
}
}
} else if (weight == 1) {
- cpu = cpumask_first(data->affinity);
+ cpu = cpumask_first(mask);
} else {
cpu = smp_processor_id();
}
@@ -710,16 +711,17 @@ static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
{
int cpu = smp_processor_id();
cpumask_t new_affinity;
+ struct cpumask *mask = irq_data_get_affinity_mask(data);

- if (!cpumask_test_cpu(cpu, data->affinity))
+ if (!cpumask_test_cpu(cpu, mask))
return;

- if (cpumask_weight(data->affinity) > 1) {
+ if (cpumask_weight(mask) > 1) {
/*
* It has multi CPU affinity, just remove this CPU
* from the affinity set.
*/
- cpumask_copy(&new_affinity, data->affinity);
+ cpumask_copy(&new_affinity, mask);
cpumask_clear_cpu(cpu, &new_affinity);
} else {
/* Otherwise, put it on lowest numbered online CPU. */
diff --git a/arch/mips/pmcs-msp71xx/msp_irq_cic.c b/arch/mips/pmcs-msp71xx/msp_irq_cic.c
index 1207ec4dfb77..8b9cf6463040 100644
--- a/arch/mips/pmcs-msp71xx/msp_irq_cic.c
+++ b/arch/mips/pmcs-msp71xx/msp_irq_cic.c
@@ -88,7 +88,8 @@ static void unmask_cic_irq(struct irq_data *d)
* Make sure we have IRQ affinity. It may have changed while
* we were processing the IRQ.
*/
- if (!cpumask_test_cpu(smp_processor_id(), d->affinity))
+ if (!cpumask_test_cpu(smp_processor_id(),
+ irq_data_get_affinity_mask(d)))
return;
#endif

--
1.7.10.4

2015-06-01 08:07:27

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 22/36] mn10300, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/mn10300/kernel/cevt-mn10300.c | 2 +-
arch/mn10300/kernel/irq.c | 13 +++++++------
2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/mn10300/kernel/cevt-mn10300.c b/arch/mn10300/kernel/cevt-mn10300.c
index 60f64ca1752a..326677d4a3b2 100644
--- a/arch/mn10300/kernel/cevt-mn10300.c
+++ b/arch/mn10300/kernel/cevt-mn10300.c
@@ -123,7 +123,7 @@ int __init init_clockevents(void)
{
struct irq_data *data;
data = irq_get_irq_data(cd->irq);
- cpumask_copy(data->affinity, cpumask_of(cpu));
+ cpumask_copy(irq_data_get_affinity_mask(data), cpumask_of(cpu));
iact->flags |= IRQF_NOBALANCING;
}
#endif
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index 480de70f4059..c716437baa2c 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -87,7 +87,8 @@ static void mn10300_cpupic_mask_ack(struct irq_data *d)
tmp2 = GxICR(irq);

irq_affinity_online[irq] =
- cpumask_any_and(d->affinity, cpu_online_mask);
+ cpumask_any_and(irq_data_get_affinity_mask(d),
+ cpu_online_mask);
CROSS_GxICR(irq, irq_affinity_online[irq]) =
(tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT;
tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
@@ -124,7 +125,7 @@ static void mn10300_cpupic_unmask_clear(struct irq_data *d)
} else {
tmp = GxICR(irq);

- irq_affinity_online[irq] = cpumask_any_and(d->affinity,
+ irq_affinity_online[irq] = cpumask_any_and(irq_data_get_affinity_mask(d),
cpu_online_mask);
CROSS_GxICR(irq, irq_affinity_online[irq]) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
@@ -316,15 +317,16 @@ void migrate_irqs(void)
self = smp_processor_id();
for (irq = 0; irq < NR_IRQS; irq++) {
struct irq_data *data = irq_get_irq_data(irq);
+ struct cpumask *mask = irq_data_get_affinity_mask(data);

if (irqd_is_per_cpu(data))
continue;

- if (cpumask_test_cpu(self, data->affinity) &&
+ if (cpumask_test_cpu(self, mask) &&
!cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) {
int cpu_id;
cpu_id = cpumask_first(cpu_online_mask);
- cpumask_set_cpu(cpu_id, data->affinity);
+ cpumask_set_cpu(cpu_id, mask);
}
/* We need to operate irq_affinity_online atomically. */
arch_local_cli_save(flags);
@@ -335,8 +337,7 @@ void migrate_irqs(void)
GxICR(irq) = x & GxICR_LEVEL;
tmp = GxICR(irq);

- new = cpumask_any_and(data->affinity,
- cpu_online_mask);
+ new = cpumask_any_and(mask, cpu_online_mask);
irq_affinity_online[irq] = new;

CROSS_GxICR(irq, new) =
--
1.7.10.4

2015-06-01 08:07:32

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 23/36] parisc, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/parisc/kernel/irq.c | 12 ++++++------
drivers/parisc/iosapic.c | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index f3191db6e2e9..413ec3c3f9cc 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -131,7 +131,7 @@ static int cpu_set_affinity_irq(struct irq_data *d, const struct cpumask *dest,
if (cpu_dest < 0)
return -1;

- cpumask_copy(d->affinity, dest);
+ cpumask_copy(irq_data_get_affinity_mask(d), dest);

return 0;
}
@@ -339,7 +339,7 @@ unsigned long txn_affinity_addr(unsigned int irq, int cpu)
{
#ifdef CONFIG_SMP
struct irq_data *d = irq_get_irq_data(irq);
- cpumask_copy(d->affinity, cpumask_of(cpu));
+ cpumask_copy(irq_data_get_affinity_mask(d), cpumask_of(cpu));
#endif

return per_cpu(cpu_data, cpu).txn_addr;
@@ -508,7 +508,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
unsigned long eirr_val;
int irq, cpu = smp_processor_id();
#ifdef CONFIG_SMP
- struct irq_desc *desc;
+ struct irq_data *irq_data;
cpumask_t dest;
#endif

@@ -522,9 +522,9 @@ void do_cpu_irq_mask(struct pt_regs *regs)
irq = eirr_to_irq(eirr_val);

#ifdef CONFIG_SMP
- desc = irq_to_desc(irq);
- cpumask_copy(&dest, desc->irq_data.affinity);
- if (irqd_is_per_cpu(&desc->irq_data) &&
+ irq_data = irq_get_irq_data(irq);
+ cpumask_copy(&dest, irq_data_get_affinity_mask(irq_data));
+ if (irqd_is_per_cpu(irq_data) &&
!cpumask_test_cpu(smp_processor_id(), &dest)) {
int cpu = cpumask_first(&dest);

diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 9ee04b4b68bf..144c77dfe4b1 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -691,7 +691,7 @@ static int iosapic_set_affinity_irq(struct irq_data *d,
if (dest_cpu < 0)
return -1;

- cpumask_copy(d->affinity, cpumask_of(dest_cpu));
+ cpumask_copy(irq_data_get_affinity_mask(d), cpumask_of(dest_cpu));
vi->txn_addr = txn_affinity_addr(d->irq, dest_cpu);

spin_lock_irqsave(&iosapic_lock, flags);
--
1.7.10.4

2015-06-01 08:07:42

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 24/36] powerpc, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/powerpc/kernel/irq.c | 2 +-
arch/powerpc/sysdev/xics/ics-opal.c | 2 +-
arch/powerpc/sysdev/xics/ics-rtas.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 45096033d37b..290559df1e8b 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -441,7 +441,7 @@ void migrate_irqs(void)

chip = irq_data_get_irq_chip(data);

- cpumask_and(mask, data->affinity, map);
+ cpumask_and(mask, irq_data_get_affinity_mask(data), map);
if (cpumask_any(mask) >= nr_cpu_ids) {
pr_warn("Breaking affinity for irq %i\n", irq);
cpumask_copy(mask, map);
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c
index 68c7e5cc98e0..3996393c254d 100644
--- a/arch/powerpc/sysdev/xics/ics-opal.c
+++ b/arch/powerpc/sysdev/xics/ics-opal.c
@@ -54,7 +54,7 @@ static void ics_opal_unmask_irq(struct irq_data *d)
if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
return;

- server = xics_get_irq_server(d->irq, d->affinity, 0);
+ server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);
server = ics_opal_mangle_server(server);

rc = opal_set_xive(hw_irq, server, DEFAULT_PRIORITY);
diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
index 0af97deb83f3..e2665a9dfc0f 100644
--- a/arch/powerpc/sysdev/xics/ics-rtas.c
+++ b/arch/powerpc/sysdev/xics/ics-rtas.c
@@ -47,7 +47,7 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
return;

- server = xics_get_irq_server(d->irq, d->affinity, 0);
+ server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);

call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq, server,
DEFAULT_PRIORITY);
--
1.7.10.4

2015-06-01 08:07:55

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 25/36] sh, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/sh/kernel/irq.c | 7 ++++---
drivers/sh/intc/chip.c | 6 +++---
2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 8dc677cc136b..6c0378c0b8b5 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -228,15 +228,16 @@ void migrate_irqs(void)
struct irq_data *data = irq_get_irq_data(irq);

if (irq_data_get_node(data) == cpu) {
- unsigned int newcpu = cpumask_any_and(data->affinity,
+ struct cpumask *mask = irq_data_get_affinity_mask(data);
+ unsigned int newcpu = cpumask_any_and(mask,
cpu_online_mask);
if (newcpu >= nr_cpu_ids) {
pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n",
irq, cpu);

- cpumask_setall(data->affinity);
+ cpumask_setall(mask);
}
- irq_set_affinity(irq, data->affinity);
+ irq_set_affinity(irq, mask);
}
}
}
diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c
index 46427b48e2f1..358df7510186 100644
--- a/drivers/sh/intc/chip.c
+++ b/drivers/sh/intc/chip.c
@@ -22,7 +22,7 @@ void _intc_enable(struct irq_data *data, unsigned long handle)

for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
#ifdef CONFIG_SMP
- if (!cpumask_test_cpu(cpu, data->affinity))
+ if (!cpumask_test_cpu(cpu, irq_data_get_affinity_mask(data)))
continue;
#endif
addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
@@ -50,7 +50,7 @@ static void intc_disable(struct irq_data *data)

for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
#ifdef CONFIG_SMP
- if (!cpumask_test_cpu(cpu, data->affinity))
+ if (!cpumask_test_cpu(cpu, irq_data_get_affinity_mask(data)))
continue;
#endif
addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
@@ -72,7 +72,7 @@ static int intc_set_affinity(struct irq_data *data,
if (!cpumask_intersects(cpumask, cpu_online_mask))
return -1;

- cpumask_copy(data->affinity, cpumask);
+ cpumask_copy(irq_data_get_affinity_mask(data), cpumask);

return IRQ_SET_MASK_OK_NOCOPY;
}
--
1.7.10.4

2015-06-01 08:08:07

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 26/36] sparc, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/sparc/kernel/irq_64.c | 12 +++++++-----
arch/sparc/kernel/leon_kernel.c | 6 +++---
2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 5130f6e3e68e..e22416ce56ea 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -377,7 +377,8 @@ static void sun4u_irq_enable(struct irq_data *data)
unsigned long cpuid, imap, val;
unsigned int tid;

- cpuid = irq_choose_cpu(data->irq, data->affinity);
+ cpuid = irq_choose_cpu(data->irq,
+ irq_data_get_affinity_mask(data));
imap = handler_data->imap;

tid = sun4u_compute_tid(imap, cpuid);
@@ -449,7 +450,8 @@ static void sun4u_irq_eoi(struct irq_data *data)

static void sun4v_irq_enable(struct irq_data *data)
{
- unsigned long cpuid = irq_choose_cpu(data->irq, data->affinity);
+ unsigned long cpuid = irq_choose_cpu(data->irq,
+ irq_data_get_affinity_mask(data));
unsigned int ino = irq_data_to_sysino(data);
int err;

@@ -511,7 +513,7 @@ static void sun4v_virq_enable(struct irq_data *data)
unsigned long cpuid;
int err;

- cpuid = irq_choose_cpu(data->irq, data->affinity);
+ cpuid = irq_choose_cpu(data->irq, irq_data_get_affinity_mask(data));

err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
if (err != HV_EOK)
@@ -884,8 +886,8 @@ void fixup_irqs(void)
if (desc->action && !irqd_is_per_cpu(data)) {
if (data->chip->irq_set_affinity)
data->chip->irq_set_affinity(data,
- data->affinity,
- false);
+ irq_data_get_affinity_mask(data),
+ false);
}
raw_spin_unlock_irqrestore(&desc->lock, flags);
}
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 9bbb8f2bbfcc..0299f052a2ef 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -126,7 +126,7 @@ static int leon_set_affinity(struct irq_data *data, const struct cpumask *dest,
int oldcpu, newcpu;

mask = (unsigned long)data->chip_data;
- oldcpu = irq_choose_cpu(data->affinity);
+ oldcpu = irq_choose_cpu(irq_data_get_affinity_mask(data));
newcpu = irq_choose_cpu(dest);

if (oldcpu == newcpu)
@@ -149,7 +149,7 @@ static void leon_unmask_irq(struct irq_data *data)
int cpu;

mask = (unsigned long)data->chip_data;
- cpu = irq_choose_cpu(data->affinity);
+ cpu = irq_choose_cpu(irq_data_get_affinity_mask(data));
spin_lock_irqsave(&leon_irq_lock, flags);
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu));
LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask | mask));
@@ -162,7 +162,7 @@ static void leon_mask_irq(struct irq_data *data)
int cpu;

mask = (unsigned long)data->chip_data;
- cpu = irq_choose_cpu(data->affinity);
+ cpu = irq_choose_cpu(irq_data_get_affinity_mask(data));
spin_lock_irqsave(&leon_irq_lock, flags);
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu));
LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask & ~mask));
--
1.7.10.4

2015-06-01 08:08:25

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 27/36] x86, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/x86/kernel/apic/io_apic.c | 2 +-
arch/x86/kernel/apic/vector.c | 5 ++---
arch/x86/kernel/irq.c | 5 +++--
drivers/xen/events/events_base.c | 4 ++--
4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 845dc0df2002..09921de4210f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2541,7 +2541,7 @@ void __init setup_ioapic_dest(void)
* Honour affinities which have been set in early boot
*/
if (!irqd_can_balance(idata) || irqd_affinity_was_set(idata))
- mask = idata->affinity;
+ mask = irq_data_get_affinity_mask(idata);
else
mask = apic->target_cpus();

diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 9b62f690b0ff..dfa3a5f5b3d3 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -494,9 +494,8 @@ static int apic_set_affinity(struct irq_data *irq_data,

err = assign_irq_vector(irq, data, dest);
if (err) {
- struct irq_data *top = irq_get_irq_data(irq);
-
- if (assign_irq_vector(irq, data, top->affinity))
+ if (assign_irq_vector(irq, data,
+ irq_data_get_affinity_mask(irq_data)))
pr_err("Failed to recover vector for irq %d\n", irq);
return err;
}
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 7e10c8b4b318..37685e37550c 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -342,7 +342,8 @@ int check_irq_vectors_for_cpu_disable(void)
continue;

data = irq_desc_get_irq_data(desc);
- cpumask_copy(&affinity_new, data->affinity);
+ cpumask_copy(&affinity_new,
+ irq_data_get_affinity_mask(data));
cpumask_clear_cpu(this_cpu, &affinity_new);

/* Do not count inactive or per-cpu irqs. */
@@ -420,7 +421,7 @@ void fixup_irqs(void)
raw_spin_lock(&desc->lock);

data = irq_desc_get_irq_data(desc);
- affinity = data->affinity;
+ affinity = irq_data_get_affinity_mask(data);
if (!irq_has_action(irq) || irqd_is_per_cpu(data) ||
cpumask_subset(affinity, cpu_online_mask)) {
raw_spin_unlock(&desc->lock);
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 2b8553bd8715..d00e0be8e9ea 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -336,7 +336,7 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)

BUG_ON(irq == -1);
#ifdef CONFIG_SMP
- cpumask_copy(irq_get_irq_data(irq)->affinity, cpumask_of(cpu));
+ cpumask_copy(irq_get_affinity_mask(irq), cpumask_of(cpu));
#endif
xen_evtchn_port_bind_to_cpu(info, cpu);

@@ -373,7 +373,7 @@ static void xen_irq_init(unsigned irq)
struct irq_info *info;
#ifdef CONFIG_SMP
/* By default all event channels notify CPU#0. */
- cpumask_copy(irq_get_irq_data(irq)->affinity, cpumask_of(0));
+ cpumask_copy(irq_get_affinity_mask(irq), cpumask_of(0));
#endif

info = kzalloc(sizeof(*info), GFP_KERNEL);
--
1.7.10.4

2015-06-01 08:08:33

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 28/36] xtensa, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/xtensa/kernel/irq.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index 3eee94f621eb..d7b5a4c8ae5d 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -166,23 +166,25 @@ void migrate_irqs(void)

for_each_active_irq(i) {
struct irq_data *data = irq_get_irq_data(i);
+ struct cpumask *mask;
unsigned int newcpu;

if (irqd_is_per_cpu(data))
continue;

- if (!cpumask_test_cpu(cpu, data->affinity))
+ mask = irq_data_get_affinity_mask(data);
+ if (!cpumask_test_cpu(cpu, mask))
continue;

- newcpu = cpumask_any_and(data->affinity, cpu_online_mask);
+ newcpu = cpumask_any_and(mask, cpu_online_mask);

if (newcpu >= nr_cpu_ids) {
pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n",
i, cpu);

- cpumask_setall(data->affinity);
+ cpumask_setall(mask);
}
- irq_set_affinity(i, data->affinity);
+ irq_set_affinity(i, mask);
}
}
#endif /* CONFIG_HOTPLUG_CPU */
--
1.7.10.4

2015-06-01 08:08:41

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 29/36] irqchip, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/irqchip/irq-mips-gic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 57f09cb54464..09257c301bd2 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -403,7 +403,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
clear_bit(irq, pcpu_masks[i].pcpu_mask);
set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask);

- cpumask_copy(d->affinity, cpumask);
+ cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
spin_unlock_irqrestore(&gic_lock, flags);

return IRQ_SET_MASK_OK_NOCOPY;
--
1.7.10.4

2015-06-01 08:14:34

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 30/36] net/mlx4: Cache irq_desc->affinity instead of irq_desc

The field 'affinity' in irq_desc won't change once the irq_desc data
structure is created. So cache irq_desc->affinity instead of irq_desc.
This also helps to hide struct irq_desc from device drivers.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/net/ethernet/mellanox/mlx4/en_cq.c | 6 +++---
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 5 +----
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 2 +-
3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
index 22da4d0d0f05..a03a01625398 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
@@ -31,6 +31,7 @@
*
*/

+#include <linux/irq.h>
#include <linux/mlx4/cq.h>
#include <linux/mlx4/qp.h>
#include <linux/mlx4/cmd.h>
@@ -135,9 +136,8 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
mdev->dev->caps.num_comp_vectors;
}

- cq->irq_desc =
- irq_to_desc(mlx4_eq_get_irq(mdev->dev,
- cq->vector));
+ cq->irq_affinity = irq_get_affinity_mask(
+ mlx4_eq_get_irq(mdev->dev, cq->vector));
} else {
/* For TX we use the same irq per
ring we assigned for the RX */
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index 2a77a6b19121..5675febf478e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -1044,14 +1044,11 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
/* If we used up all the quota - we're probably not done yet... */
if (done == budget) {
int cpu_curr;
- const struct cpumask *aff;

INC_PERF_COUNTER(priv->pstats.napi_quota);

cpu_curr = smp_processor_id();
- aff = irq_desc_get_irq_data(cq->irq_desc)->affinity;
-
- if (likely(cpumask_test_cpu(cpu_curr, aff)))
+ if (likely(cpumask_test_cpu(cpu_curr, cq->irq_affinity)))
return budget;

/* Current cpu is not according to smp_irq_affinity -
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index d021f079f181..33d544a1fe84 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -357,7 +357,7 @@ struct mlx4_en_cq {
#define CQ_USER_PEND (MLX4_EN_CQ_STATE_POLL | MLX4_EN_CQ_STATE_POLL_YIELD)
spinlock_t poll_lock; /* protects from LLS/napi conflicts */
#endif /* CONFIG_NET_RX_BUSY_POLL */
- struct irq_desc *irq_desc;
+ struct cpumask *irq_affinity;
};

struct mlx4_en_port_profile {
--
1.7.10.4

2015-06-01 08:09:03

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 31/36] genirq: Move field 'affinity' from struct irq_data into struct irq_common_data

Irq affinity mask is per-irq instead of per irqchip, so move it into
struct irq_common_data.

Signed-off-by: Jiang Liu <[email protected]>
---
include/linux/irq.h | 12 ++++++------
kernel/irq/irqdesc.c | 9 +++++----
kernel/irq/manage.c | 12 ++++++------
kernel/irq/proc.c | 2 +-
4 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 91fbf10bdae0..9d01cd8ca8a2 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -110,8 +110,8 @@ enum {
/*
* Return value for chip->irq_set_affinity()
*
- * IRQ_SET_MASK_OK - OK, core updates irq_data.affinity
- * IRQ_SET_MASK_NOCPY - OK, chip did update irq_data.affinity
+ * IRQ_SET_MASK_OK - OK, core updates irq_common_data.affinity
+ * IRQ_SET_MASK_NOCPY - OK, chip did update irq_common_data.affinity
* IRQ_SET_MASK_OK_DONE - Same as IRQ_SET_MASK_OK for core. Special code to
* support stacked irqchips, which indicates skipping
* all descendent irqchips.
@@ -131,6 +131,7 @@ struct irq_domain;
* Use accessor functions to deal with it
* @node: node index useful for balancing
* @handler_data: per-IRQ data for the irq_chip methods
+ * @affinity: IRQ affinity on SMP
*/
struct irq_common_data {
unsigned int state_use_accessors;
@@ -138,6 +139,7 @@ struct irq_common_data {
unsigned int node;
#endif
void *handler_data;
+ cpumask_var_t affinity;
};

/**
@@ -154,7 +156,6 @@ struct irq_common_data {
* @chip_data: platform-specific per-chip private data for the chip
* methods, to allow shared chip implementations
* @msi_desc: MSI descriptor
- * @affinity: IRQ affinity on SMP
*
* The fields here need to overlay the ones in irq_desc until we
* cleaned up the direct references and switched everything over to
@@ -172,7 +173,6 @@ struct irq_data {
#endif
void *chip_data;
struct msi_desc *msi_desc;
- cpumask_var_t affinity;
};

/*
@@ -660,12 +660,12 @@ static inline struct cpumask *irq_get_affinity_mask(int irq)
{
struct irq_data *d = irq_get_irq_data(irq);

- return d ? d->affinity : NULL;
+ return d ? d->common->affinity : NULL;
}

static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
{
- return d->affinity;
+ return d->common->affinity;
}

unsigned int arch_dynirq_lower_bound(unsigned int from);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 7f881792ad5f..2c39a203f78b 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -38,12 +38,13 @@ static void __init init_irq_default_affinity(void)
#ifdef CONFIG_SMP
static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)
{
- if (!zalloc_cpumask_var_node(&desc->irq_data.affinity, gfp, node))
+ if (!zalloc_cpumask_var_node(&desc->irq_common_data.affinity,
+ gfp, node))
return -ENOMEM;

#ifdef CONFIG_GENERIC_PENDING_IRQ
if (!zalloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
- free_cpumask_var(desc->irq_data.affinity);
+ free_cpumask_var(desc->irq_common_data.affinity);
return -ENOMEM;
}
#endif
@@ -52,7 +53,7 @@ static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)

static void desc_smp_init(struct irq_desc *desc, int node)
{
- cpumask_copy(desc->irq_data.affinity, irq_default_affinity);
+ cpumask_copy(desc->irq_common_data.affinity, irq_default_affinity);
#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_clear(desc->pending_mask);
#endif
@@ -124,7 +125,7 @@ static void free_masks(struct irq_desc *desc)
#ifdef CONFIG_GENERIC_PENDING_IRQ
free_cpumask_var(desc->pending_mask);
#endif
- free_cpumask_var(desc->irq_data.affinity);
+ free_cpumask_var(desc->irq_common_data.affinity);
}
#else
static inline void free_masks(struct irq_desc *desc) { }
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index f9744853b656..e7688140bfb6 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -190,7 +190,7 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
switch (ret) {
case IRQ_SET_MASK_OK:
case IRQ_SET_MASK_OK_DONE:
- cpumask_copy(data->affinity, mask);
+ cpumask_copy(desc->irq_common_data.affinity, mask);
case IRQ_SET_MASK_OK_NOCOPY:
irq_set_thread_affinity(desc);
ret = 0;
@@ -302,7 +302,7 @@ static void irq_affinity_notify(struct work_struct *work)
if (irq_move_pending(&desc->irq_data))
irq_get_pending(cpumask, desc);
else
- cpumask_copy(cpumask, desc->irq_data.affinity);
+ cpumask_copy(cpumask, desc->irq_common_data.affinity);
raw_spin_unlock_irqrestore(&desc->lock, flags);

notify->notify(notify, cpumask);
@@ -374,9 +374,9 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
* one of the targets is online.
*/
if (irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) {
- if (cpumask_intersects(desc->irq_data.affinity,
+ if (cpumask_intersects(desc->irq_common_data.affinity,
cpu_online_mask))
- set = desc->irq_data.affinity;
+ set = desc->irq_common_data.affinity;
else
irqd_clear(&desc->irq_data, IRQD_AFFINITY_SET);
}
@@ -827,8 +827,8 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
* This code is triggered unconditionally. Check the affinity
* mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
*/
- if (desc->irq_data.affinity)
- cpumask_copy(mask, desc->irq_data.affinity);
+ if (desc->irq_common_data.affinity)
+ cpumask_copy(mask, desc->irq_common_data.affinity);
else
valid = false;
raw_spin_unlock_irq(&desc->lock);
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 0e97c142ce40..e3a8c9577ba6 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -39,7 +39,7 @@ static struct proc_dir_entry *root_irq_dir;
static int show_irq_affinity(int type, struct seq_file *m, void *v)
{
struct irq_desc *desc = irq_to_desc((long)m->private);
- const struct cpumask *mask = desc->irq_data.affinity;
+ const struct cpumask *mask = desc->irq_common_data.affinity;

#ifdef CONFIG_GENERIC_PENDING_IRQ
if (irqd_is_setaffinity_pending(&desc->irq_data))
--
1.7.10.4

2015-06-01 08:09:14

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 32/36] genirq: Rename irq_data_get_msi() as irq_data_get_msi_desc()

Rename irq_data_get_msi() as irq_data_get_msi_desc() to keep consistency
with other irq_data access helpers.

Signed-off-by: Jiang Liu <[email protected]>
Acked-by: Bjorn Helgaas <[email protected]>
---
drivers/pci/host/pcie-designware.c | 2 +-
drivers/pci/msi.c | 2 +-
include/linux/irq.h | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 2e9f84fdd9ce..7b3432d331fd 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -309,7 +309,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
{
struct irq_data *data = irq_get_irq_data(irq);
- struct msi_desc *msi = irq_data_get_msi(data);
+ struct msi_desc *msi = irq_data_get_msi_desc(data);
struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);

clear_irq_range(pp, irq, 1, data->hwirq);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index c3e7dfcf9ff5..be6034cf5c21 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -270,7 +270,7 @@ static void msix_mask_irq(struct msi_desc *desc, u32 flag)

static void msi_set_mask_bit(struct irq_data *data, u32 flag)
{
- struct msi_desc *desc = irq_data_get_msi(data);
+ struct msi_desc *desc = irq_data_get_msi_desc(data);

if (desc->msi_attrib.is_msix) {
msix_mask_irq(desc, flag);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 9d01cd8ca8a2..2b95fee48c55 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -631,7 +631,7 @@ static inline struct msi_desc *irq_get_msi_desc(unsigned int irq)
return d ? d->msi_desc : NULL;
}

-static inline struct msi_desc *irq_data_get_msi(struct irq_data *d)
+static inline struct msi_desc *irq_data_get_msi_desc(struct irq_data *d)
{
return d->msi_desc;
}
--
1.7.10.4

2015-06-01 08:09:27

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 33/36] genirq: Use helper function to access irq_data->msi_desc

Use irq_data access helper to access irq_data->msi_desc, so we could
move msi_desc from struct irq_data into struct irq_common_data later.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/ia64/kernel/msi_ia64.c | 2 +-
arch/ia64/sn/kernel/msi_sn.c | 2 +-
arch/powerpc/sysdev/xics/ics-opal.c | 2 +-
arch/powerpc/sysdev/xics/ics-rtas.c | 2 +-
arch/tile/kernel/pci_gx.c | 2 +-
drivers/pci/msi.c | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 6c50d332b7d7..af4eaec0f7c3 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -23,7 +23,7 @@ static int ia64_set_msi_irq_affinity(struct irq_data *idata,
if (irq_prepare_move(irq, cpu))
return -1;

- __get_cached_msi_msg(idata->msi_desc, &msg);
+ __get_cached_msi_msg(irq_data_get_msi_desc(idata), &msg);

addr = msg.address_lo;
addr &= MSI_ADDR_DEST_ID_MASK;
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index 42b5a13af142..fb25065b22c6 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -175,7 +175,7 @@ static int sn_set_msi_irq_affinity(struct irq_data *data,
* Release XIO resources for the old MSI PCI address
*/

- __get_cached_msi_msg(data->msi_desc, &msg);
+ __get_cached_msi_msg(irq_data_get_msi_desc(data), &msg);
sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
pdev = sn_pdev->pdi_linux_pcidev;
provider = SN_PCIDEV_BUSPROVIDER(pdev);
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c
index 3996393c254d..27c936c080a6 100644
--- a/arch/powerpc/sysdev/xics/ics-opal.c
+++ b/arch/powerpc/sysdev/xics/ics-opal.c
@@ -72,7 +72,7 @@ static unsigned int ics_opal_startup(struct irq_data *d)
* card, using the MSI mask bits. Firmware doesn't appear to unmask
* at that level, so we do it here by hand.
*/
- if (d->msi_desc)
+ if (irq_data_get_msi_desc(d))
pci_msi_unmask_irq(d);
#endif

diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
index e2665a9dfc0f..3854dd41558d 100644
--- a/arch/powerpc/sysdev/xics/ics-rtas.c
+++ b/arch/powerpc/sysdev/xics/ics-rtas.c
@@ -75,7 +75,7 @@ static unsigned int ics_rtas_startup(struct irq_data *d)
* card, using the MSI mask bits. Firmware doesn't appear to unmask
* at that level, so we do it here by hand.
*/
- if (d->msi_desc)
+ if (irq_data_get_msi_desc(d))
pci_msi_unmask_irq(d);
#endif
/* unmask it */
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index b1df847d0686..65b701b3b5ed 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -1442,7 +1442,7 @@ static struct pci_ops tile_cfg_ops = {
/* MSI support starts here. */
static unsigned int tilegx_msi_startup(struct irq_data *d)
{
- if (d->msi_desc)
+ if (irq_data_get_msi_desc(d))
pci_msi_unmask_irq(d);

return 0;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index be6034cf5c21..c2f0da733d3a 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1178,7 +1178,7 @@ EXPORT_SYMBOL(pci_enable_msix_range);
*/
void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg)
{
- struct msi_desc *desc = irq_data->msi_desc;
+ struct msi_desc *desc = irq_data_get_msi_desc(irq_data);

/*
* For MSI-X desc->irq is always equal to irq_data->irq. For
--
1.7.10.4

2015-06-01 08:09:36

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 34/36] genirq: Move field 'msi_desc' from struct irq_data into struct irq_common_data

MSI descriptors are per-irq instead of per irqchip, so move it into
struct irq_common_data.

Signed-off-by: Jiang Liu <[email protected]>
---
include/linux/irq.h | 8 ++++----
include/linux/irqdesc.h | 2 +-
kernel/irq/chip.c | 2 +-
kernel/irq/irqdesc.c | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 2b95fee48c55..a38610520b33 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -132,6 +132,7 @@ struct irq_domain;
* @node: node index useful for balancing
* @handler_data: per-IRQ data for the irq_chip methods
* @affinity: IRQ affinity on SMP
+ * @msi_desc: MSI descriptor
*/
struct irq_common_data {
unsigned int state_use_accessors;
@@ -139,6 +140,7 @@ struct irq_common_data {
unsigned int node;
#endif
void *handler_data;
+ struct msi_desc *msi_desc;
cpumask_var_t affinity;
};

@@ -155,7 +157,6 @@ struct irq_common_data {
* irq_domain
* @chip_data: platform-specific per-chip private data for the chip
* methods, to allow shared chip implementations
- * @msi_desc: MSI descriptor
*
* The fields here need to overlay the ones in irq_desc until we
* cleaned up the direct references and switched everything over to
@@ -172,7 +173,6 @@ struct irq_data {
struct irq_data *parent_data;
#endif
void *chip_data;
- struct msi_desc *msi_desc;
};

/*
@@ -628,12 +628,12 @@ static inline void *irq_data_get_irq_handler_data(struct irq_data *d)
static inline struct msi_desc *irq_get_msi_desc(unsigned int irq)
{
struct irq_data *d = irq_get_irq_data(irq);
- return d ? d->msi_desc : NULL;
+ return d ? d->common->msi_desc : NULL;
}

static inline struct msi_desc *irq_data_get_msi_desc(struct irq_data *d)
{
- return d->msi_desc;
+ return d->common->msi_desc;
}

static inline u32 irq_get_trigger_type(unsigned int irq)
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index d46fd7eb7959..41544024f464 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -125,7 +125,7 @@ static inline void *irq_desc_get_handler_data(struct irq_desc *desc)

static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc)
{
- return desc->irq_data.msi_desc;
+ return desc->irq_common_data.msi_desc;
}

/*
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 895de2ea4e32..da14c388b579 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -105,7 +105,7 @@ int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset,

if (!desc)
return -EINVAL;
- desc->irq_data.msi_desc = entry;
+ desc->irq_common_data.msi_desc = entry;
if (entry && !irq_offset)
entry->irq = irq_base;
irq_put_desc_unlock(desc, flags);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 2c39a203f78b..358f620c035a 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -74,12 +74,12 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
int cpu;

desc->irq_common_data.handler_data = NULL;
+ desc->irq_common_data.msi_desc = NULL;

desc->irq_data.common = &desc->irq_common_data;
desc->irq_data.irq = irq;
desc->irq_data.chip = &no_irq_chip;
desc->irq_data.chip_data = NULL;
- desc->irq_data.msi_desc = NULL;
irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS);
irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
desc->handle_irq = handle_bad_irq;
--
1.7.10.4

2015-06-01 08:09:53

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 35/36] genirq: Pass irq_data to helper function __irq_set_chip_handler_name_locked()

For most cases, callers pass irq_data->irq to helper function
__irq_set_chip_handler_name_locked() and __irq_set_chip_handler_name_locked()
looks up irq_data again by calling irq_get_irq_data(irq_data->irq).

So pass irq_data directly instead of irq_data->irq to
__irq_set_chip_handler_name_locked().

This also helps to better support hierarchy irqdomain in irq core.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/ia64/kernel/iosapic.c | 6 +++---
arch/mips/alchemy/common/irq.c | 4 ++--
drivers/gpio/gpio-zynq.c | 9 ++++-----
drivers/irqchip/irq-metag-ext.c | 5 ++---
drivers/irqchip/irq-mips-gic.c | 11 ++++-------
include/linux/irqdesc.h | 7 +++----
6 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 4d2698d43c39..317993e92cba 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -610,9 +610,9 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
chip->name, irq_type->name);
chip = irq_type;
}
- __irq_set_chip_handler_name_locked(irq, chip, trigger == IOSAPIC_EDGE ?
- handle_edge_irq : handle_level_irq,
- NULL);
+ __irq_set_chip_handler_name_locked(irq_get_irq_data(irq), chip,
+ trigger == IOSAPIC_EDGE ? handle_edge_irq : handle_level_irq,
+ NULL);
return 0;
}

diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index 6cb60abfdcc9..026c4eed37d5 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -491,7 +491,7 @@ static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
default:
ret = -EINVAL;
}
- __irq_set_chip_handler_name_locked(d->irq, chip, handler, name);
+ __irq_set_chip_handler_name_locked(d, chip, handler, name);

wmb();

@@ -703,7 +703,7 @@ static int au1300_gpic_settype(struct irq_data *d, unsigned int type)
return -EINVAL;
}

- __irq_set_chip_handler_name_locked(d->irq, &au1300_gpic, hdl, name);
+ __irq_set_chip_handler_name_locked(d, &au1300_gpic, hdl, name);

au1300_gpic_chgcfg(d->irq - ALCHEMY_GPIC_INT_BASE, GPIC_CFG_IC_MASK, s);

diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
index 184c4b1b2558..aea6075e5b2e 100644
--- a/drivers/gpio/gpio-zynq.c
+++ b/drivers/gpio/gpio-zynq.c
@@ -422,13 +422,12 @@ static int zynq_gpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
writel_relaxed(int_any,
gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num));

- if (type & IRQ_TYPE_LEVEL_MASK) {
- __irq_set_chip_handler_name_locked(irq_data->irq,
+ if (type & IRQ_TYPE_LEVEL_MASK)
+ __irq_set_chip_handler_name_locked(irq_data,
&zynq_gpio_level_irqchip, handle_fasteoi_irq, NULL);
- } else {
- __irq_set_chip_handler_name_locked(irq_data->irq,
+ else
+ __irq_set_chip_handler_name_locked(irq_data,
&zynq_gpio_edge_irqchip, handle_level_irq, NULL);
- }

return 0;
}
diff --git a/drivers/irqchip/irq-metag-ext.c b/drivers/irqchip/irq-metag-ext.c
index 2cb474ad8809..52e501d8c8f0 100644
--- a/drivers/irqchip/irq-metag-ext.c
+++ b/drivers/irqchip/irq-metag-ext.c
@@ -404,7 +404,6 @@ static int meta_intc_irq_set_type(struct irq_data *data, unsigned int flow_type)
#ifdef CONFIG_METAG_SUSPEND_MEM
struct meta_intc_priv *priv = &meta_intc_priv;
#endif
- unsigned int irq = data->irq;
irq_hw_number_t hw = data->hwirq;
unsigned int bit = 1 << meta_intc_offset(hw);
void __iomem *level_addr = meta_intc_level_addr(hw);
@@ -413,10 +412,10 @@ static int meta_intc_irq_set_type(struct irq_data *data, unsigned int flow_type)

/* update the chip/handler */
if (flow_type & IRQ_TYPE_LEVEL_MASK)
- __irq_set_chip_handler_name_locked(irq, &meta_intc_level_chip,
+ __irq_set_chip_handler_name_locked(data, &meta_intc_level_chip,
handle_level_irq, NULL);
else
- __irq_set_chip_handler_name_locked(irq, &meta_intc_edge_chip,
+ __irq_set_chip_handler_name_locked(data, &meta_intc_edge_chip,
handle_edge_irq, NULL);

/* and clear/set the bit in HWLEVELEXT */
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 09257c301bd2..fb2e64b1f414 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -365,15 +365,12 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
break;
}

- if (is_edge) {
- __irq_set_chip_handler_name_locked(d->irq,
- &gic_edge_irq_controller,
+ if (is_edge)
+ __irq_set_chip_handler_name_locked(d, &gic_edge_irq_controller,
handle_edge_irq, NULL);
- } else {
- __irq_set_chip_handler_name_locked(d->irq,
- &gic_level_irq_controller,
+ else
+ __irq_set_chip_handler_name_locked(d, &gic_level_irq_controller,
handle_level_irq, NULL);
- }
spin_unlock_irqrestore(&gic_lock, flags);

return 0;
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 41544024f464..4dfa46b99a14 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -177,15 +177,14 @@ static inline void __irq_set_handler_locked(unsigned int irq,

/* caller has locked the irq_desc and both params are valid */
static inline void
-__irq_set_chip_handler_name_locked(unsigned int irq, struct irq_chip *chip,
+__irq_set_chip_handler_name_locked(struct irq_data *data, struct irq_chip *chip,
irq_flow_handler_t handler, const char *name)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_data_to_desc(data);

- desc = irq_to_desc(irq);
- irq_desc_get_irq_data(desc)->chip = chip;
desc->handle_irq = handler;
desc->name = name;
+ data->chip = chip;
}

static inline int irq_balancing_disabled(unsigned int irq)
--
1.7.10.4

2015-06-01 08:10:00

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 36/36] genirq: Optimize irq_data_to_desc() to avoid irq_to_desc() lookup

Optimize irq_data_to_desc() to avoid irq_to_desc() lookup.

Signed-off-by: Jiang Liu <[email protected]>
---
include/linux/irqdesc.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 4dfa46b99a14..749755bffbc1 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -97,7 +97,7 @@ extern struct irq_desc irq_desc[NR_IRQS];
static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
{
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
- return irq_to_desc(data->irq);
+ return container_of(data->common, struct irq_desc, irq_common_data);
#else
return container_of(data, struct irq_desc, irq_data);
#endif
--
1.7.10.4

2015-06-01 11:39:13

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [Patch v3 11/36] sh, irq: Use helper irq_data_get_irq_handler_data() to hide irq_desc details

Hello.

On 6/1/2015 11:05 AM, Jiang Liu wrote:

> Use helper function irq_data_get_irq_handler_data() to hide irq_desc
> implementation details.

I'm only seeing calls to irq_{get|set}_handler_data() below...

> Signed-off-by: Jiang Liu <[email protected]>
> ---
> drivers/sh/intc/virq.c | 12 +++++++-----
> 1 file changed, 7 insertions(+), 5 deletions(-)

> diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c
> index f30ac9354ff2..bc0601cf0f8f 100644
> --- a/drivers/sh/intc/virq.c
> +++ b/drivers/sh/intc/virq.c
> @@ -83,12 +83,11 @@ EXPORT_SYMBOL_GPL(intc_irq_lookup);
>
> static int add_virq_to_pirq(unsigned int irq, unsigned int virq)
> {
> - struct intc_virq_list **last, *entry;
> - struct irq_data *data = irq_get_irq_data(irq);
> + struct intc_virq_list *entry;
> + struct intc_virq_list **last = NULL;
>
> /* scan for duplicates */
> - last = (struct intc_virq_list **)&data->handler_data;
> - for_each_virq(entry, data->handler_data) {
> + for_each_virq(entry, irq_get_handler_data(irq)) {
> if (entry->irq == virq)
> return 0;
> last = &entry->next;
> @@ -102,7 +101,10 @@ static int add_virq_to_pirq(unsigned int irq, unsigned int virq)
>
> entry->irq = virq;
>
> - *last = entry;
> + if (last)
> + *last = entry;
> + else
> + irq_set_handler_data(irq, entry);
>
> return 0;
> }

WBR, Sergei

2015-06-01 13:53:49

by Jiang Liu

[permalink] [raw]
Subject: Re: [Patch v3 11/36] sh, irq: Use helper irq_data_get_irq_handler_data() to hide irq_desc details

On 2015/6/1 19:38, Sergei Shtylyov wrote:
> Hello.
>
> On 6/1/2015 11:05 AM, Jiang Liu wrote:
>
>> Use helper function irq_data_get_irq_handler_data() to hide irq_desc
>> implementation details.
>
> I'm only seeing calls to irq_{get|set}_handler_data() below...
Hi Sergei,
Thanks for review, I will fix the commit message.
Thanks!
Gerry

>
>> Signed-off-by: Jiang Liu <[email protected]>
>> ---
>> drivers/sh/intc/virq.c | 12 +++++++-----
>> 1 file changed, 7 insertions(+), 5 deletions(-)
>
>> diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c
>> index f30ac9354ff2..bc0601cf0f8f 100644
>> --- a/drivers/sh/intc/virq.c
>> +++ b/drivers/sh/intc/virq.c
>> @@ -83,12 +83,11 @@ EXPORT_SYMBOL_GPL(intc_irq_lookup);
>>
>> static int add_virq_to_pirq(unsigned int irq, unsigned int virq)
>> {
>> - struct intc_virq_list **last, *entry;
>> - struct irq_data *data = irq_get_irq_data(irq);
>> + struct intc_virq_list *entry;
>> + struct intc_virq_list **last = NULL;
>>
>> /* scan for duplicates */
>> - last = (struct intc_virq_list **)&data->handler_data;
>> - for_each_virq(entry, data->handler_data) {
>> + for_each_virq(entry, irq_get_handler_data(irq)) {
>> if (entry->irq == virq)
>> return 0;
>> last = &entry->next;
>> @@ -102,7 +101,10 @@ static int add_virq_to_pirq(unsigned int irq,
>> unsigned int virq)
>>
>> entry->irq = virq;
>>
>> - *last = entry;
>> + if (last)
>> + *last = entry;
>> + else
>> + irq_set_handler_data(irq, entry);
>>
>> return 0;
>> }
>
> WBR, Sergei
>

2015-06-02 03:45:11

by Michael Ellerman

[permalink] [raw]
Subject: Re: [v3,33/36] genirq: Use helper function to access irq_data->msi_desc

On Mon, 2015-01-06 at 08:05:42 UTC, Jiang Liu wrote:
> Use irq_data access helper to access irq_data->msi_desc, so we could
> move msi_desc from struct irq_data into struct irq_common_data later.
>
> Signed-off-by: Jiang Liu <[email protected]>
> ---
> arch/powerpc/sysdev/xics/ics-opal.c | 2 +-
> arch/powerpc/sysdev/xics/ics-rtas.c | 2 +-
>
> diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c
> index 3996393c254d..27c936c080a6 100644
> --- a/arch/powerpc/sysdev/xics/ics-opal.c
> +++ b/arch/powerpc/sysdev/xics/ics-opal.c
> @@ -72,7 +72,7 @@ static unsigned int ics_opal_startup(struct irq_data *d)
> * card, using the MSI mask bits. Firmware doesn't appear to unmask
> * at that level, so we do it here by hand.
> */
> - if (d->msi_desc)
> + if (irq_data_get_msi_desc(d))
> pci_msi_unmask_irq(d);
> #endif
>
> diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
> index e2665a9dfc0f..3854dd41558d 100644
> --- a/arch/powerpc/sysdev/xics/ics-rtas.c
> +++ b/arch/powerpc/sysdev/xics/ics-rtas.c
> @@ -75,7 +75,7 @@ static unsigned int ics_rtas_startup(struct irq_data *d)
> * card, using the MSI mask bits. Firmware doesn't appear to unmask
> * at that level, so we do it here by hand.
> */
> - if (d->msi_desc)
> + if (irq_data_get_msi_desc(d))
> pci_msi_unmask_irq(d);
> #endif
> /* unmask it */

These look OK.

Though I would point out we already have 16 irq_foo_get_bar() accessors?!

Acked-by: Michael Ellerman <[email protected]>

cheers

2015-06-02 05:46:49

by Jiang Liu

[permalink] [raw]
Subject: Re: [v3,33/36] genirq: Use helper function to access irq_data->msi_desc

On 2015/6/2 11:45, Michael Ellerman wrote:
> On Mon, 2015-01-06 at 08:05:42 UTC, Jiang Liu wrote:
>> Use irq_data access helper to access irq_data->msi_desc, so we could
>> move msi_desc from struct irq_data into struct irq_common_data later.
>>
>> Signed-off-by: Jiang Liu <[email protected]>
>> ---
>> arch/powerpc/sysdev/xics/ics-opal.c | 2 +-
>> arch/powerpc/sysdev/xics/ics-rtas.c | 2 +-
>>
>> diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c
>> index 3996393c254d..27c936c080a6 100644
>> --- a/arch/powerpc/sysdev/xics/ics-opal.c
>> +++ b/arch/powerpc/sysdev/xics/ics-opal.c
>> @@ -72,7 +72,7 @@ static unsigned int ics_opal_startup(struct irq_data *d)
>> * card, using the MSI mask bits. Firmware doesn't appear to unmask
>> * at that level, so we do it here by hand.
>> */
>> - if (d->msi_desc)
>> + if (irq_data_get_msi_desc(d))
>> pci_msi_unmask_irq(d);
>> #endif
>>
>> diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
>> index e2665a9dfc0f..3854dd41558d 100644
>> --- a/arch/powerpc/sysdev/xics/ics-rtas.c
>> +++ b/arch/powerpc/sysdev/xics/ics-rtas.c
>> @@ -75,7 +75,7 @@ static unsigned int ics_rtas_startup(struct irq_data *d)
>> * card, using the MSI mask bits. Firmware doesn't appear to unmask
>> * at that level, so we do it here by hand.
>> */
>> - if (d->msi_desc)
>> + if (irq_data_get_msi_desc(d))
>> pci_msi_unmask_irq(d);
>> #endif
>> /* unmask it */
>
> These look OK.
>
> Though I would point out we already have 16 irq_foo_get_bar() accessors?!
Hi Michael,
Thanks for review. We are trying to solve some issues introduced
by hierarchy irqdomain/irqchip by splitting irq_data into a common part
(irq_common_data) and per-chip part(irq_data). These accessors are used
to ease the transition and hide implementation details.
Thanks!
Gerry

>
> Acked-by: Michael Ellerman <[email protected]>
>
> cheers
>

2015-06-02 06:26:35

by Hanjun Guo

[permalink] [raw]
Subject: Re: [Patch v3 17/36] ARM64, irq: Use access helper irq_data_get_affinity_mask()

On 2015/6/1 16:05, Jiang Liu wrote:
> Use access helper irq_data_get_affinity_mask() to hide implementation
> details of struct irq_desc.
>
> Signed-off-by: Jiang Liu <[email protected]>
> ---
> arch/arm64/kernel/irq.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
> index 240b75c0e94f..463fa2e7e34c 100644
> --- a/arch/arm64/kernel/irq.c
> +++ b/arch/arm64/kernel/irq.c
> @@ -61,7 +61,7 @@ void __init init_IRQ(void)
> static bool migrate_one_irq(struct irq_desc *desc)
> {
> struct irq_data *d = irq_desc_get_irq_data(desc);
> - const struct cpumask *affinity = d->affinity;
> + const struct cpumask *affinity = irq_data_get_affinity_mask(d);
> struct irq_chip *c;
> bool ret = false;
>
> @@ -81,7 +81,7 @@ static bool migrate_one_irq(struct irq_desc *desc)
> if (!c->irq_set_affinity)
> pr_debug("IRQ%u: unable to set affinity\n", d->irq);
> else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && ret)
> - cpumask_copy(d->affinity, affinity);
> + cpumask_copy(irq_data_get_affinity_mask(d), affinity);
>
> return ret;
> }

Reviewed-by: Hanjun Guo <[email protected]>

Thanks
Hanjun


2015-06-02 19:20:17

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [Patch v3 27/36] x86, irq: Use access helper irq_data_get_affinity_mask()

On Mon, 1 Jun 2015, Jiang Liu wrote:

> diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
> index 9b62f690b0ff..dfa3a5f5b3d3 100644
> --- a/arch/x86/kernel/apic/vector.c
> +++ b/arch/x86/kernel/apic/vector.c
> @@ -494,9 +494,8 @@ static int apic_set_affinity(struct irq_data *irq_data,
>
> err = assign_irq_vector(irq, data, dest);
> if (err) {
> - struct irq_data *top = irq_get_irq_data(irq);
> -
> - if (assign_irq_vector(irq, data, top->affinity))
> + if (assign_irq_vector(irq, data,
> + irq_data_get_affinity_mask(irq_data)))

Does this patch work w/o moving the affinity mask to common data? I
doubt so, as you remove the retrieval of 'top'.

Thanks,

tglx

2015-06-03 01:54:05

by Jiang Liu

[permalink] [raw]
Subject: Re: [Patch v3 27/36] x86, irq: Use access helper irq_data_get_affinity_mask()

On 2015/6/3 3:19, Thomas Gleixner wrote:
> On Mon, 1 Jun 2015, Jiang Liu wrote:
>
>> diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
>> index 9b62f690b0ff..dfa3a5f5b3d3 100644
>> --- a/arch/x86/kernel/apic/vector.c
>> +++ b/arch/x86/kernel/apic/vector.c
>> @@ -494,9 +494,8 @@ static int apic_set_affinity(struct irq_data *irq_data,
>>
>> err = assign_irq_vector(irq, data, dest);
>> if (err) {
>> - struct irq_data *top = irq_get_irq_data(irq);
>> -
>> - if (assign_irq_vector(irq, data, top->affinity))
>> + if (assign_irq_vector(irq, data,
>> + irq_data_get_affinity_mask(irq_data)))
>
> Does this patch work w/o moving the affinity mask to common data? I
> doubt so, as you remove the retrieval of 'top'.
Hi Thomas,
This piece of code should be moved into [31/36], otherwise
it will break bisecting. I will redo patch this and [31/36] to
support bisecting.
Thanks!
Gerry

>
> Thanks,
>
> tglx
>

2015-06-03 03:45:03

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 27/36] x86, irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
---
Hi Thomas,
This version changes the patch to correctly support bisecting.
Thanks!
Gerry
---
arch/x86/kernel/apic/io_apic.c | 2 +-
arch/x86/kernel/apic/vector.c | 3 ++-
arch/x86/kernel/irq.c | 5 +++--
drivers/xen/events/events_base.c | 4 ++--
4 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 845dc0df2002..09921de4210f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2541,7 +2541,7 @@ void __init setup_ioapic_dest(void)
* Honour affinities which have been set in early boot
*/
if (!irqd_can_balance(idata) || irqd_affinity_was_set(idata))
- mask = idata->affinity;
+ mask = irq_data_get_affinity_mask(idata);
else
mask = apic->target_cpus();

diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 9b62f690b0ff..7ad911ea4f56 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -496,7 +496,8 @@ static int apic_set_affinity(struct irq_data *irq_data,
if (err) {
struct irq_data *top = irq_get_irq_data(irq);

- if (assign_irq_vector(irq, data, top->affinity))
+ if (assign_irq_vector(irq, data,
+ irq_data_get_affinity_mask(top)))
pr_err("Failed to recover vector for irq %d\n", irq);
return err;
}
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 7e10c8b4b318..37685e37550c 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -342,7 +342,8 @@ int check_irq_vectors_for_cpu_disable(void)
continue;

data = irq_desc_get_irq_data(desc);
- cpumask_copy(&affinity_new, data->affinity);
+ cpumask_copy(&affinity_new,
+ irq_data_get_affinity_mask(data));
cpumask_clear_cpu(this_cpu, &affinity_new);

/* Do not count inactive or per-cpu irqs. */
@@ -420,7 +421,7 @@ void fixup_irqs(void)
raw_spin_lock(&desc->lock);

data = irq_desc_get_irq_data(desc);
- affinity = data->affinity;
+ affinity = irq_data_get_affinity_mask(data);
if (!irq_has_action(irq) || irqd_is_per_cpu(data) ||
cpumask_subset(affinity, cpu_online_mask)) {
raw_spin_unlock(&desc->lock);
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 2b8553bd8715..d00e0be8e9ea 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -336,7 +336,7 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)

BUG_ON(irq == -1);
#ifdef CONFIG_SMP
- cpumask_copy(irq_get_irq_data(irq)->affinity, cpumask_of(cpu));
+ cpumask_copy(irq_get_affinity_mask(irq), cpumask_of(cpu));
#endif
xen_evtchn_port_bind_to_cpu(info, cpu);

@@ -373,7 +373,7 @@ static void xen_irq_init(unsigned irq)
struct irq_info *info;
#ifdef CONFIG_SMP
/* By default all event channels notify CPU#0. */
- cpumask_copy(irq_get_irq_data(irq)->affinity, cpumask_of(0));
+ cpumask_copy(irq_get_affinity_mask(irq), cpumask_of(0));
#endif

info = kzalloc(sizeof(*info), GFP_KERNEL);
--
1.7.10.4

2015-06-03 03:46:15

by Jiang Liu

[permalink] [raw]
Subject: [Patch v3 31/36] genirq: Move field 'affinity' from struct irq_data into struct irq_common_data

Irq affinity mask is per-irq instead of per irqchip, so move it into
struct irq_common_data.

Signed-off-by: Jiang Liu <[email protected]>
---
Hi Thomas,
This version changes the patch to correctly support bisecting.
Thanks!
Gerry
---
arch/x86/kernel/apic/vector.c | 4 +---
include/linux/irq.h | 12 ++++++------
kernel/irq/irqdesc.c | 9 +++++----
kernel/irq/manage.c | 12 ++++++------
kernel/irq/proc.c | 2 +-
5 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 7ad911ea4f56..dfa3a5f5b3d3 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -494,10 +494,8 @@ static int apic_set_affinity(struct irq_data *irq_data,

err = assign_irq_vector(irq, data, dest);
if (err) {
- struct irq_data *top = irq_get_irq_data(irq);
-
if (assign_irq_vector(irq, data,
- irq_data_get_affinity_mask(top)))
+ irq_data_get_affinity_mask(irq_data)))
pr_err("Failed to recover vector for irq %d\n", irq);
return err;
}
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 91fbf10bdae0..9d01cd8ca8a2 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -110,8 +110,8 @@ enum {
/*
* Return value for chip->irq_set_affinity()
*
- * IRQ_SET_MASK_OK - OK, core updates irq_data.affinity
- * IRQ_SET_MASK_NOCPY - OK, chip did update irq_data.affinity
+ * IRQ_SET_MASK_OK - OK, core updates irq_common_data.affinity
+ * IRQ_SET_MASK_NOCPY - OK, chip did update irq_common_data.affinity
* IRQ_SET_MASK_OK_DONE - Same as IRQ_SET_MASK_OK for core. Special code to
* support stacked irqchips, which indicates skipping
* all descendent irqchips.
@@ -131,6 +131,7 @@ struct irq_domain;
* Use accessor functions to deal with it
* @node: node index useful for balancing
* @handler_data: per-IRQ data for the irq_chip methods
+ * @affinity: IRQ affinity on SMP
*/
struct irq_common_data {
unsigned int state_use_accessors;
@@ -138,6 +139,7 @@ struct irq_common_data {
unsigned int node;
#endif
void *handler_data;
+ cpumask_var_t affinity;
};

/**
@@ -154,7 +156,6 @@ struct irq_common_data {
* @chip_data: platform-specific per-chip private data for the chip
* methods, to allow shared chip implementations
* @msi_desc: MSI descriptor
- * @affinity: IRQ affinity on SMP
*
* The fields here need to overlay the ones in irq_desc until we
* cleaned up the direct references and switched everything over to
@@ -172,7 +173,6 @@ struct irq_data {
#endif
void *chip_data;
struct msi_desc *msi_desc;
- cpumask_var_t affinity;
};

/*
@@ -660,12 +660,12 @@ static inline struct cpumask *irq_get_affinity_mask(int irq)
{
struct irq_data *d = irq_get_irq_data(irq);

- return d ? d->affinity : NULL;
+ return d ? d->common->affinity : NULL;
}

static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
{
- return d->affinity;
+ return d->common->affinity;
}

unsigned int arch_dynirq_lower_bound(unsigned int from);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 7f881792ad5f..2c39a203f78b 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -38,12 +38,13 @@ static void __init init_irq_default_affinity(void)
#ifdef CONFIG_SMP
static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)
{
- if (!zalloc_cpumask_var_node(&desc->irq_data.affinity, gfp, node))
+ if (!zalloc_cpumask_var_node(&desc->irq_common_data.affinity,
+ gfp, node))
return -ENOMEM;

#ifdef CONFIG_GENERIC_PENDING_IRQ
if (!zalloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
- free_cpumask_var(desc->irq_data.affinity);
+ free_cpumask_var(desc->irq_common_data.affinity);
return -ENOMEM;
}
#endif
@@ -52,7 +53,7 @@ static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)

static void desc_smp_init(struct irq_desc *desc, int node)
{
- cpumask_copy(desc->irq_data.affinity, irq_default_affinity);
+ cpumask_copy(desc->irq_common_data.affinity, irq_default_affinity);
#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_clear(desc->pending_mask);
#endif
@@ -124,7 +125,7 @@ static void free_masks(struct irq_desc *desc)
#ifdef CONFIG_GENERIC_PENDING_IRQ
free_cpumask_var(desc->pending_mask);
#endif
- free_cpumask_var(desc->irq_data.affinity);
+ free_cpumask_var(desc->irq_common_data.affinity);
}
#else
static inline void free_masks(struct irq_desc *desc) { }
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index f9744853b656..e7688140bfb6 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -190,7 +190,7 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
switch (ret) {
case IRQ_SET_MASK_OK:
case IRQ_SET_MASK_OK_DONE:
- cpumask_copy(data->affinity, mask);
+ cpumask_copy(desc->irq_common_data.affinity, mask);
case IRQ_SET_MASK_OK_NOCOPY:
irq_set_thread_affinity(desc);
ret = 0;
@@ -302,7 +302,7 @@ static void irq_affinity_notify(struct work_struct *work)
if (irq_move_pending(&desc->irq_data))
irq_get_pending(cpumask, desc);
else
- cpumask_copy(cpumask, desc->irq_data.affinity);
+ cpumask_copy(cpumask, desc->irq_common_data.affinity);
raw_spin_unlock_irqrestore(&desc->lock, flags);

notify->notify(notify, cpumask);
@@ -374,9 +374,9 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
* one of the targets is online.
*/
if (irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) {
- if (cpumask_intersects(desc->irq_data.affinity,
+ if (cpumask_intersects(desc->irq_common_data.affinity,
cpu_online_mask))
- set = desc->irq_data.affinity;
+ set = desc->irq_common_data.affinity;
else
irqd_clear(&desc->irq_data, IRQD_AFFINITY_SET);
}
@@ -827,8 +827,8 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
* This code is triggered unconditionally. Check the affinity
* mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
*/
- if (desc->irq_data.affinity)
- cpumask_copy(mask, desc->irq_data.affinity);
+ if (desc->irq_common_data.affinity)
+ cpumask_copy(mask, desc->irq_common_data.affinity);
else
valid = false;
raw_spin_unlock_irq(&desc->lock);
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 0e97c142ce40..e3a8c9577ba6 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -39,7 +39,7 @@ static struct proc_dir_entry *root_irq_dir;
static int show_irq_affinity(int type, struct seq_file *m, void *v)
{
struct irq_desc *desc = irq_to_desc((long)m->private);
- const struct cpumask *mask = desc->irq_data.affinity;
+ const struct cpumask *mask = desc->irq_common_data.affinity;

#ifdef CONFIG_GENERIC_PENDING_IRQ
if (irqd_is_setaffinity_pending(&desc->irq_data))
--
1.7.10.4

2015-06-03 16:54:15

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [v3,33/36] genirq: Use helper function to access irq_data->msi_desc

On Tue, 2 Jun 2015, Michael Ellerman wrote:
> Though I would point out we already have 16 irq_foo_get_bar() accessors?!

Say thanks to the people who mindlessly fiddled in the core managed
fields of irqdesc and irqdata. The hard to track down wreckage they
caused me to enforce accessors.

The new accessors are to help migrating members of irq_data to a new
data structure without breaking the world and some more.

Thanks,

tglx

2015-06-05 08:54:51

by Ralf Baechle

[permalink] [raw]
Subject: Re: [Patch v3 21/36] mips, irq: Use access helper irq_data_get_affinity_mask()

On Mon, Jun 01, 2015 at 04:05:30PM +0800, Jiang Liu wrote:

Acked-by: Ralf Baechle <[email protected]>

Ralf

2015-06-05 08:55:16

by Ralf Baechle

[permalink] [raw]
Subject: Re: [Patch v3 35/36] genirq: Pass irq_data to helper function __irq_set_chip_handler_name_locked()

On Mon, Jun 01, 2015 at 04:05:44PM +0800, Jiang Liu wrote:

For arch/mips/alchemy/common/irq.c:

Acked-by: Ralf Baechle <[email protected]>

Ralf

Subject: [tip:x86/apic] genirq: Prevent crash in irq_move_irq()

Commit-ID: 458526ec81d755dfaa17f3d863302afe6fbefca0
Gitweb: http://git.kernel.org/tip/458526ec81d755dfaa17f3d863302afe6fbefca0
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:11 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Tue, 16 Jun 2015 09:23:28 +0200

genirq: Prevent crash in irq_move_irq()

The functions irq_move_irq() and irq_move_masked_irq() expect that the
caller passes the top-level irq_data to them when hierarchical
irqdomains are enabled. But that's not true when called from
apic_ack_edge(), which results in a null pointer dereference by
idata->chip->irq_mask(idata).

Instead of fixing callers to passing top-level irq_data, we rather
change irq_move_irq()/irq_move_masked_irq() to accept any irq_data.

Fixes: 52f518a3a7c 'x86/MSI: Use hierarchical irqdomains to manage MSI interrupts'
Reported-by: Huang Ying <[email protected]>
Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
kernel/irq/migration.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index ca3f4aa..dd203e2 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -7,7 +7,7 @@
void irq_move_masked_irq(struct irq_data *idata)
{
struct irq_desc *desc = irq_data_to_desc(idata);
- struct irq_chip *chip = idata->chip;
+ struct irq_chip *chip = desc->irq_data.chip;

if (likely(!irqd_is_setaffinity_pending(&desc->irq_data)))
return;
@@ -52,6 +52,13 @@ void irq_move_irq(struct irq_data *idata)
{
bool masked;

+ /*
+ * Get top level irq_data when CONFIG_IRQ_DOMAIN_HIERARCHY is enabled,
+ * and it should be optimized away when CONFIG_IRQ_DOMAIN_HIERARCHY is
+ * disabled. So we avoid an "#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY" here.
+ */
+ idata = irq_desc_get_irq_data(irq_data_to_desc(idata));
+
if (likely(!irqd_is_setaffinity_pending(idata)))
return;

2015-06-16 07:48:03

by Jiang Liu

[permalink] [raw]
Subject: Re: [tip:x86/apic] genirq: Prevent crash in irq_move_irq()

On 2015/6/16 15:31, tip-bot for Jiang Liu wrote:
> Commit-ID: 458526ec81d755dfaa17f3d863302afe6fbefca0
> Gitweb: http://git.kernel.org/tip/458526ec81d755dfaa17f3d863302afe6fbefca0
> Author: Jiang Liu <[email protected]>
> AuthorDate: Mon, 1 Jun 2015 16:05:11 +0800
> Committer: Thomas Gleixner <[email protected]>
> CommitDate: Tue, 16 Jun 2015 09:23:28 +0200
>
> genirq: Prevent crash in irq_move_irq()
>
> The functions irq_move_irq() and irq_move_masked_irq() expect that the
> caller passes the top-level irq_data to them when hierarchical
> irqdomains are enabled. But that's not true when called from
> apic_ack_edge(), which results in a null pointer dereference by
> idata->chip->irq_mask(idata).
>
> Instead of fixing callers to passing top-level irq_data, we rather
> change irq_move_irq()/irq_move_masked_irq() to accept any irq_data.
>
> Fixes: 52f518a3a7c 'x86/MSI: Use hierarchical irqdomains to manage MSI interrupts'
Hi Thomas,
This patch has dependency on patch "[Patch v3 01/36] genirq:
Enhance irq_data_to_desc() to support hierarchy irqdomain" in the
same patch set, otherwise irq_data_to_desc(idata) may return invalid
irq_desc and may cause memory crash.
Thanks!
Gerry

2015-06-16 08:13:24

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [tip:x86/apic] genirq: Prevent crash in irq_move_irq()



On Tue, 16 Jun 2015, Jiang Liu wrote:

> On 2015/6/16 15:31, tip-bot for Jiang Liu wrote:
> > Commit-ID: 458526ec81d755dfaa17f3d863302afe6fbefca0
> > Gitweb: http://git.kernel.org/tip/458526ec81d755dfaa17f3d863302afe6fbefca0
> > Author: Jiang Liu <[email protected]>
> > AuthorDate: Mon, 1 Jun 2015 16:05:11 +0800
> > Committer: Thomas Gleixner <[email protected]>
> > CommitDate: Tue, 16 Jun 2015 09:23:28 +0200
> >
> > genirq: Prevent crash in irq_move_irq()
> >
> > The functions irq_move_irq() and irq_move_masked_irq() expect that the
> > caller passes the top-level irq_data to them when hierarchical
> > irqdomains are enabled. But that's not true when called from
> > apic_ack_edge(), which results in a null pointer dereference by
> > idata->chip->irq_mask(idata).
> >
> > Instead of fixing callers to passing top-level irq_data, we rather
> > change irq_move_irq()/irq_move_masked_irq() to accept any irq_data.
> >
> > Fixes: 52f518a3a7c 'x86/MSI: Use hierarchical irqdomains to manage MSI interrupts'
> Hi Thomas,
> This patch has dependency on patch "[Patch v3 01/36] genirq:
> Enhance irq_data_to_desc() to support hierarchy irqdomain" in the
> same patch set, otherwise irq_data_to_desc(idata) may return invalid
> irq_desc and may cause memory crash.

That's why you should not mix bug fixes with performance improvement series.

Thanks,

tglx

Subject: [tip:x86/apic] genirq: Enhance irq_data_to_desc() to support hierarchy irqdomain

Commit-ID: c7cfc94096db28d3072b402c224eb50349926e24
Gitweb: http://git.kernel.org/tip/c7cfc94096db28d3072b402c224eb50349926e24
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:10 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Tue, 16 Jun 2015 10:10:16 +0200

genirq: Enhance irq_data_to_desc() to support hierarchy irqdomain

For irq associated with hierarchy irqdomains, there will be multiple
irq_datas for one irq_desc. So enhance irq_data_to_desc() to support
hierarchy irqdomain. Also export irq_data_to_desc() as an inline
function for later reuse.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Marc Zyngier <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
include/linux/irqdesc.h | 9 +++++++++
kernel/irq/internals.h | 2 --
2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index dd1109f..a113a8d 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -93,6 +93,15 @@ struct irq_desc {
extern struct irq_desc irq_desc[NR_IRQS];
#endif

+static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
+{
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+ return irq_to_desc(data->irq);
+#else
+ return container_of(data, struct irq_desc, irq_data);
+#endif
+}
+
static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc)
{
return &desc->irq_data;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index df553b0..b93d434 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -59,8 +59,6 @@ enum {
#include "debug.h"
#include "settings.h"

-#define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data)
-
extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
unsigned long flags);
extern void __disable_irq(struct irq_desc *desc, unsigned int irq);

Subject: [tip:x86/apic] genirq: Prevent crash in irq_move_irq()

Commit-ID: f6b1464f647424bbeb609ec832428e4079940701
Gitweb: http://git.kernel.org/tip/f6b1464f647424bbeb609ec832428e4079940701
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:11 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Tue, 16 Jun 2015 10:10:20 +0200

genirq: Prevent crash in irq_move_irq()

The functions irq_move_irq() and irq_move_masked_irq() expect that the
caller passes the top-level irq_data to them when hierarchical
irqdomains are enabled. But that's not true when called from
apic_ack_edge(), which results in a null pointer dereference by
idata->chip->irq_mask(idata).

Instead of fixing callers to passing top-level irq_data, we rather
change irq_move_irq()/irq_move_masked_irq() to accept any irq_data.

Fixes: 52f518a3a7c 'x86/MSI: Use hierarchical irqdomains to manage MSI interrupts'
Reported-by: Huang Ying <[email protected]>
Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
kernel/irq/migration.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index ca3f4aa..dd203e2 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -7,7 +7,7 @@
void irq_move_masked_irq(struct irq_data *idata)
{
struct irq_desc *desc = irq_data_to_desc(idata);
- struct irq_chip *chip = idata->chip;
+ struct irq_chip *chip = desc->irq_data.chip;

if (likely(!irqd_is_setaffinity_pending(&desc->irq_data)))
return;
@@ -52,6 +52,13 @@ void irq_move_irq(struct irq_data *idata)
{
bool masked;

+ /*
+ * Get top level irq_data when CONFIG_IRQ_DOMAIN_HIERARCHY is enabled,
+ * and it should be optimized away when CONFIG_IRQ_DOMAIN_HIERARCHY is
+ * disabled. So we avoid an "#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY" here.
+ */
+ idata = irq_desc_get_irq_data(irq_data_to_desc(idata));
+
if (likely(!irqd_is_setaffinity_pending(idata)))
return;

2015-06-16 08:25:15

by Jiang Liu

[permalink] [raw]
Subject: Re: [tip:x86/apic] genirq: Prevent crash in irq_move_irq()

On 2015/6/16 16:12, Thomas Gleixner wrote:
>
>
> On Tue, 16 Jun 2015, Jiang Liu wrote:
>
>> On 2015/6/16 15:31, tip-bot for Jiang Liu wrote:
>>> Commit-ID: 458526ec81d755dfaa17f3d863302afe6fbefca0
>>> Gitweb: http://git.kernel.org/tip/458526ec81d755dfaa17f3d863302afe6fbefca0
>>> Author: Jiang Liu <[email protected]>
>>> AuthorDate: Mon, 1 Jun 2015 16:05:11 +0800
>>> Committer: Thomas Gleixner <[email protected]>
>>> CommitDate: Tue, 16 Jun 2015 09:23:28 +0200
>>>
>>> genirq: Prevent crash in irq_move_irq()
>>>
>>> The functions irq_move_irq() and irq_move_masked_irq() expect that the
>>> caller passes the top-level irq_data to them when hierarchical
>>> irqdomains are enabled. But that's not true when called from
>>> apic_ack_edge(), which results in a null pointer dereference by
>>> idata->chip->irq_mask(idata).
>>>
>>> Instead of fixing callers to passing top-level irq_data, we rather
>>> change irq_move_irq()/irq_move_masked_irq() to accept any irq_data.
>>>
>>> Fixes: 52f518a3a7c 'x86/MSI: Use hierarchical irqdomains to manage MSI interrupts'
>> Hi Thomas,
>> This patch has dependency on patch "[Patch v3 01/36] genirq:
>> Enhance irq_data_to_desc() to support hierarchy irqdomain" in the
>> same patch set, otherwise irq_data_to_desc(idata) may return invalid
>> irq_desc and may cause memory crash.
>
> That's why you should not mix bug fixes with performance improvement series.
Yes, it's a lesson. I always fall into troubles when managing several
inter-dependent patch sets at the same time.
Thanks!
Gerry

Subject: [tip:irq/core] genirq: Enhance irq_data_to_desc() to support hierarchy irqdomain

Commit-ID: 7bbf1dd24b17b9ec4f47c43ce4e05bf190745553
Gitweb: http://git.kernel.org/tip/7bbf1dd24b17b9ec4f47c43ce4e05bf190745553
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:10 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 12 Jun 2015 16:54:21 +0200

genirq: Enhance irq_data_to_desc() to support hierarchy irqdomain

For irq associated with hierarchy irqdomains, there will be multiple
irq_datas for one irq_desc. So enhance irq_data_to_desc() to support
hierarchy irqdomain. Also export irq_data_to_desc() as an inline
function for later reuse.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Marc Zyngier <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
include/linux/irqdesc.h | 9 +++++++++
kernel/irq/internals.h | 2 --
2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index dd1109f..a113a8d 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -93,6 +93,15 @@ struct irq_desc {
extern struct irq_desc irq_desc[NR_IRQS];
#endif

+static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
+{
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+ return irq_to_desc(data->irq);
+#else
+ return container_of(data, struct irq_desc, irq_data);
+#endif
+}
+
static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc)
{
return &desc->irq_data;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index df553b0..b93d434 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -59,8 +59,6 @@ enum {
#include "debug.h"
#include "settings.h"

-#define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data)
-
extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
unsigned long flags);
extern void __disable_irq(struct irq_desc *desc, unsigned int irq);

Subject: [tip:irq/core] genirq: Prevent crash in irq_move_irq()

Commit-ID: 77ed42f18edd486e9994ccd1f174076309a6343f
Gitweb: http://git.kernel.org/tip/77ed42f18edd486e9994ccd1f174076309a6343f
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:11 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 12 Jun 2015 16:54:21 +0200

genirq: Prevent crash in irq_move_irq()

The functions irq_move_irq() and irq_move_masked_irq() expect that the
caller passes the top-level irq_data to them when hierarchical
irqdomains are enabled. But that's not true when called from
apic_ack_edge(), which results in a null pointer dereference by
idata->chip->irq_mask(idata).

Instead of fixing callers to passing top-level irq_data, we rather
change irq_move_irq()/irq_move_masked_irq() to accept any irq_data.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
kernel/irq/migration.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index ca3f4aa..dd203e2 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -7,7 +7,7 @@
void irq_move_masked_irq(struct irq_data *idata)
{
struct irq_desc *desc = irq_data_to_desc(idata);
- struct irq_chip *chip = idata->chip;
+ struct irq_chip *chip = desc->irq_data.chip;

if (likely(!irqd_is_setaffinity_pending(&desc->irq_data)))
return;
@@ -52,6 +52,13 @@ void irq_move_irq(struct irq_data *idata)
{
bool masked;

+ /*
+ * Get top level irq_data when CONFIG_IRQ_DOMAIN_HIERARCHY is enabled,
+ * and it should be optimized away when CONFIG_IRQ_DOMAIN_HIERARCHY is
+ * disabled. So we avoid an "#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY" here.
+ */
+ idata = irq_desc_get_irq_data(irq_data_to_desc(idata));
+
if (likely(!irqd_is_setaffinity_pending(idata)))
return;

Subject: [tip:irq/core] genirq: Introduce struct irq_common_data to host shared irq data

Commit-ID: 0d0b4c866bcce647f40d73efe5e90aeeb079050a
Gitweb: http://git.kernel.org/tip/0d0b4c866bcce647f40d73efe5e90aeeb079050a
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:12 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 12 Jun 2015 16:54:21 +0200

genirq: Introduce struct irq_common_data to host shared irq data

With the introduction of hierarchy irqdomain, struct irq_data becomes
per-chip instead of per-irq and there may be multiple irq_datas
associated with the same irq. Some per-irq data stored in struct
irq_data now may get duplicated into multiple irq_datas, and causes
inconsistent view.

So introduce struct irq_common_data to host per-irq common data and to
achieve consistent view among irq_chips.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Jason Cooper <[email protected]>
Cc: Kevin Cernekee <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Marc Zyngier <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
include/linux/irq.h | 54 +++++++++++++++++++++++++++++--------------------
include/linux/irqdesc.h | 3 ++-
kernel/irq/internals.h | 10 ++++-----
kernel/irq/irqdesc.c | 1 +
kernel/irq/irqdomain.c | 1 +
5 files changed, 41 insertions(+), 28 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 48cb7d1..3c7fbe4 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -126,13 +126,21 @@ struct msi_desc;
struct irq_domain;

/**
- * struct irq_data - per irq and irq chip data passed down to chip functions
+ * struct irq_common_data - per irq data shared by all irqchips
+ * @state_use_accessors: status information for irq chip functions.
+ * Use accessor functions to deal with it
+ */
+struct irq_common_data {
+ unsigned int state_use_accessors;
+};
+
+/**
+ * struct irq_data - per irq chip data passed down to chip functions
* @mask: precomputed bitmask for accessing the chip registers
* @irq: interrupt number
* @hwirq: hardware interrupt number, local to the interrupt domain
* @node: node index useful for balancing
- * @state_use_accessors: status information for irq chip functions.
- * Use accessor functions to deal with it
+ * @common: point to data shared by all irqchips
* @chip: low level interrupt hardware access
* @domain: Interrupt translation domain; responsible for mapping
* between hwirq number and linux irq number.
@@ -153,7 +161,7 @@ struct irq_data {
unsigned int irq;
unsigned long hwirq;
unsigned int node;
- unsigned int state_use_accessors;
+ struct irq_common_data *common;
struct irq_chip *chip;
struct irq_domain *domain;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
@@ -166,7 +174,7 @@ struct irq_data {
};

/*
- * Bit masks for irq_data.state
+ * Bit masks for irq_common_data.state_use_accessors
*
* IRQD_TRIGGER_MASK - Mask for the trigger type bits
* IRQD_SETAFFINITY_PENDING - Affinity setting is pending
@@ -198,34 +206,36 @@ enum {
IRQD_WAKEUP_ARMED = (1 << 19),
};

+#define __irqd_to_state(d) ((d)->common->state_use_accessors)
+
static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_SETAFFINITY_PENDING;
+ return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING;
}

static inline bool irqd_is_per_cpu(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_PER_CPU;
+ return __irqd_to_state(d) & IRQD_PER_CPU;
}

static inline bool irqd_can_balance(struct irq_data *d)
{
- return !(d->state_use_accessors & (IRQD_PER_CPU | IRQD_NO_BALANCING));
+ return !(__irqd_to_state(d) & (IRQD_PER_CPU | IRQD_NO_BALANCING));
}

static inline bool irqd_affinity_was_set(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_AFFINITY_SET;
+ return __irqd_to_state(d) & IRQD_AFFINITY_SET;
}

static inline void irqd_mark_affinity_was_set(struct irq_data *d)
{
- d->state_use_accessors |= IRQD_AFFINITY_SET;
+ __irqd_to_state(d) |= IRQD_AFFINITY_SET;
}

static inline u32 irqd_get_trigger_type(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_TRIGGER_MASK;
+ return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
}

/*
@@ -233,43 +243,43 @@ static inline u32 irqd_get_trigger_type(struct irq_data *d)
*/
static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
{
- d->state_use_accessors &= ~IRQD_TRIGGER_MASK;
- d->state_use_accessors |= type & IRQD_TRIGGER_MASK;
+ __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
+ __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
}

static inline bool irqd_is_level_type(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_LEVEL;
+ return __irqd_to_state(d) & IRQD_LEVEL;
}

static inline bool irqd_is_wakeup_set(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_WAKEUP_STATE;
+ return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
}

static inline bool irqd_can_move_in_process_context(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_MOVE_PCNTXT;
+ return __irqd_to_state(d) & IRQD_MOVE_PCNTXT;
}

static inline bool irqd_irq_disabled(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_IRQ_DISABLED;
+ return __irqd_to_state(d) & IRQD_IRQ_DISABLED;
}

static inline bool irqd_irq_masked(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_IRQ_MASKED;
+ return __irqd_to_state(d) & IRQD_IRQ_MASKED;
}

static inline bool irqd_irq_inprogress(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_IRQ_INPROGRESS;
+ return __irqd_to_state(d) & IRQD_IRQ_INPROGRESS;
}

static inline bool irqd_is_wakeup_armed(struct irq_data *d)
{
- return d->state_use_accessors & IRQD_WAKEUP_ARMED;
+ return __irqd_to_state(d) & IRQD_WAKEUP_ARMED;
}


@@ -280,12 +290,12 @@ static inline bool irqd_is_wakeup_armed(struct irq_data *d)
*/
static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
{
- d->state_use_accessors |= IRQD_IRQ_INPROGRESS;
+ __irqd_to_state(d) |= IRQD_IRQ_INPROGRESS;
}

static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
{
- d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS;
+ __irqd_to_state(d) &= ~IRQD_IRQ_INPROGRESS;
}

static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index a113a8d..c52d148 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -17,7 +17,7 @@ struct pt_regs;

/**
* struct irq_desc - interrupt descriptor
- * @irq_data: per irq and chip data passed down to chip functions
+ * @irq_common_data: per irq and chip data passed down to chip functions
* @kstat_irqs: irq stats per cpu
* @handle_irq: highlevel irq-events handler
* @preflow_handler: handler called before the flow handler (currently used by sparc)
@@ -47,6 +47,7 @@ struct pt_regs;
* @name: flow handler name for /proc/interrupts output
*/
struct irq_desc {
+ struct irq_common_data irq_common_data;
struct irq_data irq_data;
unsigned int __percpu *kstat_irqs;
irq_flow_handler_t handle_irq;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index b93d434..a1ed80d 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -168,27 +168,27 @@ irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags)
*/
static inline void irqd_set_move_pending(struct irq_data *d)
{
- d->state_use_accessors |= IRQD_SETAFFINITY_PENDING;
+ __irqd_to_state(d) |= IRQD_SETAFFINITY_PENDING;
}

static inline void irqd_clr_move_pending(struct irq_data *d)
{
- d->state_use_accessors &= ~IRQD_SETAFFINITY_PENDING;
+ __irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING;
}

static inline void irqd_clear(struct irq_data *d, unsigned int mask)
{
- d->state_use_accessors &= ~mask;
+ __irqd_to_state(d) &= ~mask;
}

static inline void irqd_set(struct irq_data *d, unsigned int mask)
{
- d->state_use_accessors |= mask;
+ __irqd_to_state(d) |= mask;
}

static inline bool irqd_has_set(struct irq_data *d, unsigned int mask)
{
- return d->state_use_accessors & mask;
+ return __irqd_to_state(d) & mask;
}

static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc)
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 99793b9..eac1aac 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -76,6 +76,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
{
int cpu;

+ desc->irq_data.common = &desc->irq_common_data;
desc->irq_data.irq = irq;
desc->irq_data.chip = &no_irq_chip;
desc->irq_data.chip_data = NULL;
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 7fac311..3552b87 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -834,6 +834,7 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
if (irq_data) {
child->parent_data = irq_data;
irq_data->irq = child->irq;
+ irq_data->common = child->common;
irq_data->node = child->node;
irq_data->domain = domain;
}

Subject: [tip:irq/core] genirq: Introduce helper function irq_data_get_node()

Commit-ID: 6783011b48096b9a0c239d0f7645f93070b6eefd
Gitweb: http://git.kernel.org/tip/6783011b48096b9a0c239d0f7645f93070b6eefd
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:13 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 12 Jun 2015 16:54:21 +0200

genirq: Introduce helper function irq_data_get_node()

Introduce helper function irq_data_get_node() and variants thereof to
hide struct irq_data implementation details.

Convert the core code to use them.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Jason Cooper <[email protected]>
Cc: Kevin Cernekee <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
include/linux/irq.h | 5 +++++
kernel/irq/internals.h | 5 +++++
kernel/irq/irqdesc.c | 8 +-------
kernel/irq/irqdomain.c | 3 ++-
kernel/irq/manage.c | 2 +-
kernel/irq/proc.c | 2 +-
6 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 3c7fbe4..b3b82a5 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -640,6 +640,11 @@ static inline u32 irq_get_trigger_type(unsigned int irq)
return d ? irqd_get_trigger_type(d) : 0;
}

+static inline int irq_data_get_node(struct irq_data *d)
+{
+ return d->node;
+}
+
unsigned int arch_dynirq_lower_bound(unsigned int from);

int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index a1ed80d..4834ee8 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -197,6 +197,11 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *d
__this_cpu_inc(kstat.irqs_sum);
}

+static inline int irq_desc_get_node(struct irq_desc *desc)
+{
+ return irq_data_get_node(&desc->irq_data);
+}
+
#ifdef CONFIG_PM_SLEEP
bool irq_pm_check_wakeup(struct irq_desc *desc);
void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index eac1aac..b18d3f1 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -59,16 +59,10 @@ static void desc_smp_init(struct irq_desc *desc, int node)
#endif
}

-static inline int desc_node(struct irq_desc *desc)
-{
- return desc->irq_data.node;
-}
-
#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) { }
-static inline int desc_node(struct irq_desc *desc) { return 0; }
#endif

static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
@@ -300,7 +294,7 @@ static void free_desc(unsigned int irq)
unsigned long flags;

raw_spin_lock_irqsave(&desc->lock, flags);
- desc_set_defaults(irq, desc, desc_node(desc), NULL);
+ desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL);
raw_spin_unlock_irqrestore(&desc->lock, flags);
}

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 3552b87..1b06dfe 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -830,7 +830,8 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
{
struct irq_data *irq_data;

- irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL, child->node);
+ irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL,
+ irq_data_get_node(child));
if (irq_data) {
child->parent_data = irq_data;
irq_data->irq = child->irq;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index b1c7e8f..f974485 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -363,7 +363,7 @@ static int
setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
{
struct cpumask *set = irq_default_affinity;
- int node = desc->irq_data.node;
+ int node = irq_desc_get_node(desc);

/* Excludes PER_CPU and NO_BALANCE interrupts */
if (!irq_can_set_affinity(irq))
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index df2f464..0e97c14 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -241,7 +241,7 @@ static int irq_node_proc_show(struct seq_file *m, void *v)
{
struct irq_desc *desc = irq_to_desc((long) m->private);

- seq_printf(m, "%d\n", desc->irq_data.node);
+ seq_printf(m, "%d\n", irq_desc_get_node(desc));
return 0;
}

Subject: [tip:irq/core] genirq: Introduce helper function irq_data_get_affinity_mask()

Commit-ID: c64301a230a64dfc2fcf4581cd98a2d703f3c057
Gitweb: http://git.kernel.org/tip/c64301a230a64dfc2fcf4581cd98a2d703f3c057
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:23 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 12 Jun 2015 16:54:21 +0200

genirq: Introduce helper function irq_data_get_affinity_mask()

Introduce helper function irq_data_get_affinity_mask() and
irq_get_affinity_mask() to hide implementation details,
so we could move field 'affinity' from struct irq_data into
struct irq_common_data later.

Signed-off-by: Jiang Liu <[email protected]>
Acked-by: Russell King <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Jason Cooper <[email protected]>
Cc: Kevin Cernekee <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
include/linux/irq.h | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index b3b82a5..1e0ccef 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -645,6 +645,18 @@ static inline int irq_data_get_node(struct irq_data *d)
return d->node;
}

+static inline struct cpumask *irq_get_affinity_mask(int irq)
+{
+ struct irq_data *d = irq_get_irq_data(irq);
+
+ return d ? d->affinity : NULL;
+}
+
+static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
+{
+ return d->affinity;
+}
+
unsigned int arch_dynirq_lower_bound(unsigned int from);

int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,

Subject: [tip:irq/urgent] mn10300: Fix incorrect use of irq_data->affinity

Commit-ID: 856b859df4237ed10176c6afc2c97aa90ab04ffc
Gitweb: http://git.kernel.org/tip/856b859df4237ed10176c6afc2c97aa90ab04ffc
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:22 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Thu, 25 Jun 2015 12:02:43 +0200

mn10300: Fix incorrect use of irq_data->affinity

The field affinity in struct irq_data is type of cpumask_var_t, so
we should pass in data->affinity instead of &data->affinity when
calling cpumask_xxxx().

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: David Howells <[email protected]>
Cc: Koichi Yasutake <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/mn10300/kernel/irq.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index 6ab3b73..480de70 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -320,11 +320,11 @@ void migrate_irqs(void)
if (irqd_is_per_cpu(data))
continue;

- if (cpumask_test_cpu(self, &data->affinity) &&
+ if (cpumask_test_cpu(self, data->affinity) &&
!cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) {
int cpu_id;
cpu_id = cpumask_first(cpu_online_mask);
- cpumask_set_cpu(cpu_id, &data->affinity);
+ cpumask_set_cpu(cpu_id, data->affinity);
}
/* We need to operate irq_affinity_online atomically. */
arch_local_cli_save(flags);
@@ -335,7 +335,7 @@ void migrate_irqs(void)
GxICR(irq) = x & GxICR_LEVEL;
tmp = GxICR(irq);

- new = cpumask_any_and(&data->affinity,
+ new = cpumask_any_and(data->affinity,
cpu_online_mask);
irq_affinity_online[irq] = new;

Subject: [tip:irq/core] irqchip/mips-gic: Use access helper irq_data_get_affinity_mask()

Commit-ID: 72f86db4dd5eafbadd45c9092df73c49f320f638
Gitweb: http://git.kernel.org/tip/72f86db4dd5eafbadd45c9092df73c49f320f638
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:38 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Sat, 11 Jul 2015 23:14:27 +0200

irqchip/mips-gic: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

[ tglx: Verified with coccinelle ]

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Jason Cooper <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
drivers/irqchip/irq-mips-gic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 42dbebc..e6c2df9 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -405,7 +405,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
clear_bit(irq, pcpu_masks[i].pcpu_mask);
set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask);

- cpumask_copy(d->affinity, cpumask);
+ cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
spin_unlock_irqrestore(&gic_lock, flags);

return IRQ_SET_MASK_OK_NOCOPY;

Subject: [tip:irq/core] mn10300/irq: Use access helper irq_data_get_affinity_mask()

Commit-ID: 9d03e784bc225e7ccaa53bcdb64c8ebf96f153d7
Gitweb: http://git.kernel.org/tip/9d03e784bc225e7ccaa53bcdb64c8ebf96f153d7
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:31 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 31 Jul 2015 22:20:04 +0200

mn10300/irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: David Howells <[email protected]>
Cc: Koichi Yasutake <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/mn10300/kernel/cevt-mn10300.c | 2 +-
arch/mn10300/kernel/irq.c | 13 +++++++------
2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/mn10300/kernel/cevt-mn10300.c b/arch/mn10300/kernel/cevt-mn10300.c
index 60f64ca..326677d 100644
--- a/arch/mn10300/kernel/cevt-mn10300.c
+++ b/arch/mn10300/kernel/cevt-mn10300.c
@@ -123,7 +123,7 @@ int __init init_clockevents(void)
{
struct irq_data *data;
data = irq_get_irq_data(cd->irq);
- cpumask_copy(data->affinity, cpumask_of(cpu));
+ cpumask_copy(irq_data_get_affinity_mask(data), cpumask_of(cpu));
iact->flags |= IRQF_NOBALANCING;
}
#endif
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index 480de70..c716437 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -87,7 +87,8 @@ static void mn10300_cpupic_mask_ack(struct irq_data *d)
tmp2 = GxICR(irq);

irq_affinity_online[irq] =
- cpumask_any_and(d->affinity, cpu_online_mask);
+ cpumask_any_and(irq_data_get_affinity_mask(d),
+ cpu_online_mask);
CROSS_GxICR(irq, irq_affinity_online[irq]) =
(tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT;
tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
@@ -124,7 +125,7 @@ static void mn10300_cpupic_unmask_clear(struct irq_data *d)
} else {
tmp = GxICR(irq);

- irq_affinity_online[irq] = cpumask_any_and(d->affinity,
+ irq_affinity_online[irq] = cpumask_any_and(irq_data_get_affinity_mask(d),
cpu_online_mask);
CROSS_GxICR(irq, irq_affinity_online[irq]) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
@@ -316,15 +317,16 @@ void migrate_irqs(void)
self = smp_processor_id();
for (irq = 0; irq < NR_IRQS; irq++) {
struct irq_data *data = irq_get_irq_data(irq);
+ struct cpumask *mask = irq_data_get_affinity_mask(data);

if (irqd_is_per_cpu(data))
continue;

- if (cpumask_test_cpu(self, data->affinity) &&
+ if (cpumask_test_cpu(self, mask) &&
!cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) {
int cpu_id;
cpu_id = cpumask_first(cpu_online_mask);
- cpumask_set_cpu(cpu_id, data->affinity);
+ cpumask_set_cpu(cpu_id, mask);
}
/* We need to operate irq_affinity_online atomically. */
arch_local_cli_save(flags);
@@ -335,8 +337,7 @@ void migrate_irqs(void)
GxICR(irq) = x & GxICR_LEVEL;
tmp = GxICR(irq);

- new = cpumask_any_and(data->affinity,
- cpu_online_mask);
+ new = cpumask_any_and(mask, cpu_online_mask);
irq_affinity_online[irq] = new;

CROSS_GxICR(irq, new) =

Subject: [tip:irq/core] parisc/irq: Use access helper irq_data_get_affinity_mask()

Commit-ID: d2109a12198edf22eb85e475c223eea14b9c3fbe
Gitweb: http://git.kernel.org/tip/d2109a12198edf22eb85e475c223eea14b9c3fbe
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:32 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 31 Jul 2015 22:20:04 +0200

parisc/irq: Use access helper irq_data_get_affinity_mask()

Use access helper irq_data_get_affinity_mask() to hide implementation
details of struct irq_desc.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: James E.J. Bottomley <[email protected]>
Cc: Helge Deller <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/parisc/kernel/irq.c | 12 ++++++------
drivers/parisc/iosapic.c | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index f3191db..413ec3c 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -131,7 +131,7 @@ static int cpu_set_affinity_irq(struct irq_data *d, const struct cpumask *dest,
if (cpu_dest < 0)
return -1;

- cpumask_copy(d->affinity, dest);
+ cpumask_copy(irq_data_get_affinity_mask(d), dest);

return 0;
}
@@ -339,7 +339,7 @@ unsigned long txn_affinity_addr(unsigned int irq, int cpu)
{
#ifdef CONFIG_SMP
struct irq_data *d = irq_get_irq_data(irq);
- cpumask_copy(d->affinity, cpumask_of(cpu));
+ cpumask_copy(irq_data_get_affinity_mask(d), cpumask_of(cpu));
#endif

return per_cpu(cpu_data, cpu).txn_addr;
@@ -508,7 +508,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
unsigned long eirr_val;
int irq, cpu = smp_processor_id();
#ifdef CONFIG_SMP
- struct irq_desc *desc;
+ struct irq_data *irq_data;
cpumask_t dest;
#endif

@@ -522,9 +522,9 @@ void do_cpu_irq_mask(struct pt_regs *regs)
irq = eirr_to_irq(eirr_val);

#ifdef CONFIG_SMP
- desc = irq_to_desc(irq);
- cpumask_copy(&dest, desc->irq_data.affinity);
- if (irqd_is_per_cpu(&desc->irq_data) &&
+ irq_data = irq_get_irq_data(irq);
+ cpumask_copy(&dest, irq_data_get_affinity_mask(irq_data));
+ if (irqd_is_per_cpu(irq_data) &&
!cpumask_test_cpu(smp_processor_id(), &dest)) {
int cpu = cpumask_first(&dest);

diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 9ee04b4..144c77d 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -691,7 +691,7 @@ static int iosapic_set_affinity_irq(struct irq_data *d,
if (dest_cpu < 0)
return -1;

- cpumask_copy(d->affinity, cpumask_of(dest_cpu));
+ cpumask_copy(irq_data_get_affinity_mask(d), cpumask_of(dest_cpu));
vi->txn_addr = txn_affinity_addr(d->irq, dest_cpu);

spin_lock_irqsave(&iosapic_lock, flags);

Subject: [tip:irq/core] sparc/irq: Use helper irq_data_get_irq_handler_data()

Commit-ID: 6a4a5b34c315be04abdc366cda7a00b7249550f3
Gitweb: http://git.kernel.org/tip/6a4a5b34c315be04abdc366cda7a00b7249550f3
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:17 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 31 Jul 2015 22:20:05 +0200

sparc/irq: Use helper irq_data_get_irq_handler_data()

Use helper function irq_data_get_irq_handler_data() to hide irq_desc
implementation details. This allows to move irq_data->handler_data to
irq_data_common, once all usage sites are converted.

Signed-off-by: Jiang Liu <[email protected]>
Cc: David S. Miller <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/sparc/kernel/irq_64.c | 15 +++++++++------
arch/sparc/kernel/sun4d_irq.c | 4 ++--
arch/sparc/kernel/sun4m_irq.c | 6 ++++--
3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 4033c23..5130f6e 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -210,21 +210,21 @@ struct irq_handler_data {

static inline unsigned int irq_data_to_handle(struct irq_data *data)
{
- struct irq_handler_data *ihd = data->handler_data;
+ struct irq_handler_data *ihd = irq_data_get_irq_handler_data(data);

return ihd->dev_handle;
}

static inline unsigned int irq_data_to_ino(struct irq_data *data)
{
- struct irq_handler_data *ihd = data->handler_data;
+ struct irq_handler_data *ihd = irq_data_get_irq_handler_data(data);

return ihd->dev_ino;
}

static inline unsigned long irq_data_to_sysino(struct irq_data *data)
{
- struct irq_handler_data *ihd = data->handler_data;
+ struct irq_handler_data *ihd = irq_data_get_irq_handler_data(data);

return ihd->sysino;
}
@@ -370,8 +370,9 @@ static int irq_choose_cpu(unsigned int irq, const struct cpumask *affinity)

static void sun4u_irq_enable(struct irq_data *data)
{
- struct irq_handler_data *handler_data = data->handler_data;
+ struct irq_handler_data *handler_data;

+ handler_data = irq_data_get_irq_handler_data(data);
if (likely(handler_data)) {
unsigned long cpuid, imap, val;
unsigned int tid;
@@ -393,8 +394,9 @@ static void sun4u_irq_enable(struct irq_data *data)
static int sun4u_set_affinity(struct irq_data *data,
const struct cpumask *mask, bool force)
{
- struct irq_handler_data *handler_data = data->handler_data;
+ struct irq_handler_data *handler_data;

+ handler_data = irq_data_get_irq_handler_data(data);
if (likely(handler_data)) {
unsigned long cpuid, imap, val;
unsigned int tid;
@@ -438,8 +440,9 @@ static void sun4u_irq_disable(struct irq_data *data)

static void sun4u_irq_eoi(struct irq_data *data)
{
- struct irq_handler_data *handler_data = data->handler_data;
+ struct irq_handler_data *handler_data;

+ handler_data = irq_data_get_irq_handler_data(data);
if (likely(handler_data))
upa_writeq(ICLR_IDLE, handler_data->iclr);
}
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index a1bb267..a87d0e4 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -188,7 +188,7 @@ void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs)

static void sun4d_mask_irq(struct irq_data *data)
{
- struct sun4d_handler_data *handler_data = data->handler_data;
+ struct sun4d_handler_data *handler_data = irq_data_get_irq_handler_data(data);
unsigned int real_irq;
#ifdef CONFIG_SMP
int cpuid = handler_data->cpuid;
@@ -206,7 +206,7 @@ static void sun4d_mask_irq(struct irq_data *data)

static void sun4d_unmask_irq(struct irq_data *data)
{
- struct sun4d_handler_data *handler_data = data->handler_data;
+ struct sun4d_handler_data *handler_data = irq_data_get_irq_handler_data(data);
unsigned int real_irq;
#ifdef CONFIG_SMP
int cpuid = handler_data->cpuid;
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index 8bb3b3f..da737c7 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -188,9 +188,10 @@ static unsigned long sun4m_imask[0x50] = {

static void sun4m_mask_irq(struct irq_data *data)
{
- struct sun4m_handler_data *handler_data = data->handler_data;
+ struct sun4m_handler_data *handler_data;
int cpu = smp_processor_id();

+ handler_data = irq_data_get_irq_handler_data(data);
if (handler_data->mask) {
unsigned long flags;

@@ -206,9 +207,10 @@ static void sun4m_mask_irq(struct irq_data *data)

static void sun4m_unmask_irq(struct irq_data *data)
{
- struct sun4m_handler_data *handler_data = data->handler_data;
+ struct sun4m_handler_data *handler_data;
int cpu = smp_processor_id();

+ handler_data = irq_data_get_irq_handler_data(data);
if (handler_data->mask) {
unsigned long flags;

Subject: [tip:irq/core] sparc/irq: Use access helper irq_data_get_affinity_mask()

Commit-ID: d7185a98d576e33982cd28e65889b3e4122fe5d8
Gitweb: http://git.kernel.org/tip/d7185a98d576e33982cd28e65889b3e4122fe5d8
Author: Jiang Liu <[email protected]>
AuthorDate: Mon, 1 Jun 2015 16:05:35 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 31 Jul 2015 22:20:05 +0200

sparc/irq: Use access helper irq_data_get_affinity_mask()

This is a preparatory patch for moving irq_data struct members.

Signed-off-by: Jiang Liu <[email protected]>
Cc: David S. Miller <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/sparc/kernel/irq_64.c | 12 +++++++-----
arch/sparc/kernel/leon_kernel.c | 6 +++---
2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 5130f6e..e22416c 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -377,7 +377,8 @@ static void sun4u_irq_enable(struct irq_data *data)
unsigned long cpuid, imap, val;
unsigned int tid;

- cpuid = irq_choose_cpu(data->irq, data->affinity);
+ cpuid = irq_choose_cpu(data->irq,
+ irq_data_get_affinity_mask(data));
imap = handler_data->imap;

tid = sun4u_compute_tid(imap, cpuid);
@@ -449,7 +450,8 @@ static void sun4u_irq_eoi(struct irq_data *data)

static void sun4v_irq_enable(struct irq_data *data)
{
- unsigned long cpuid = irq_choose_cpu(data->irq, data->affinity);
+ unsigned long cpuid = irq_choose_cpu(data->irq,
+ irq_data_get_affinity_mask(data));
unsigned int ino = irq_data_to_sysino(data);
int err;

@@ -511,7 +513,7 @@ static void sun4v_virq_enable(struct irq_data *data)
unsigned long cpuid;
int err;

- cpuid = irq_choose_cpu(data->irq, data->affinity);
+ cpuid = irq_choose_cpu(data->irq, irq_data_get_affinity_mask(data));

err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
if (err != HV_EOK)
@@ -884,8 +886,8 @@ void fixup_irqs(void)
if (desc->action && !irqd_is_per_cpu(data)) {
if (data->chip->irq_set_affinity)
data->chip->irq_set_affinity(data,
- data->affinity,
- false);
+ irq_data_get_affinity_mask(data),
+ false);
}
raw_spin_unlock_irqrestore(&desc->lock, flags);
}
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 9bbb8f2..0299f05 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -126,7 +126,7 @@ static int leon_set_affinity(struct irq_data *data, const struct cpumask *dest,
int oldcpu, newcpu;

mask = (unsigned long)data->chip_data;
- oldcpu = irq_choose_cpu(data->affinity);
+ oldcpu = irq_choose_cpu(irq_data_get_affinity_mask(data));
newcpu = irq_choose_cpu(dest);

if (oldcpu == newcpu)
@@ -149,7 +149,7 @@ static void leon_unmask_irq(struct irq_data *data)
int cpu;

mask = (unsigned long)data->chip_data;
- cpu = irq_choose_cpu(data->affinity);
+ cpu = irq_choose_cpu(irq_data_get_affinity_mask(data));
spin_lock_irqsave(&leon_irq_lock, flags);
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu));
LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask | mask));
@@ -162,7 +162,7 @@ static void leon_mask_irq(struct irq_data *data)
int cpu;

mask = (unsigned long)data->chip_data;
- cpu = irq_choose_cpu(data->affinity);
+ cpu = irq_choose_cpu(irq_data_get_affinity_mask(data));
spin_lock_irqsave(&leon_irq_lock, flags);
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu));
LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask & ~mask));