Skip to contentSkip to conversation

cpumask fallout: Initialize irq_default_affinity earlier et al. (v3)

PATCH Superseded David Daney 1 participant 3 messages Jan 13, 2009

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover cpumask fallout: Initialize irq_default_affinity earlier et al. (v3)

Now that mips/OCTEON support has been merged, this patch set has slightly more urgency.

The interrupt affinity on OCTEON is determined by irq_default_affinity,
because that is what the code in kernel/irq/manage.c uses to set affinity. Since for the majority of devices (Serial, Compact Flash, Network...) we want interrupts to be handled on a single CPU, we set
irq_default_affinity to the boot CPU in init_IRQ(). The problem we
have is that with the new cpumask infrastructure, irq_default_affinity
is being initialized in core_initcall which undoes our initialization.

As I said in 2/2:

Move the initialization of irq_default_affinity to early_irq_init as core_initcall is too late.

irq_default_affinity can be used in init_IRQ and potentially timer and SMP init as well. All of these happen before core_initcall. Moving the initialization to early_irq_init ensures that it is initialized before it is used.

Mike Travis pointed out that irq_default_affinity depends on CONFIG_GENERIC_HARDIRQS in addition to CONFIG_SMP. So to make things consistent, I added 1/2 so that the irq_*_affinity functions and irq_default_affinity are defined for the same conditions that they are declared.

I Took Linus' suggestion to move init_irq_default_affinity over to kernel/irq/handle.c, however due to the way that cpumask_*() are defined, it is still necessary to have the ugly ifdefs, but now they are localized to init_irq_default_affinity.

Mike Travis also suggested that alloc_bootmem_cpumask_var() be used in preference to alloc_cpumask_var, so I incorporated that suggestion as well.

I tested both with and without CONFIG_SMP, on mips/cavium_octeon, Mike tested a similar(but not identical patch) on x86_64.

Changes from v2 of this set are just a small rearrangement of the #ifdefs suggested by Ihar Hrachyshka that make the code look a bit cleaner.

I will reply with the two patches.

David Daney (2):
Make irq_*_affinity depend on CONFIG_GENERIC_HARDIRQS too. cpumask fallout: Initialize irq_default_affinity earlier (v3).

 kernel/irq/handle.c |   16 ++++++++++++++++
 kernel/irq/manage.c |   10 +---------
 2 files changed, 17 insertions(+), 9 deletions(-)
#1 lore raw

PATCH 1/2 Make irq_*_affinity depend on CONFIG_GENERIC_HARDIRQS too.

In interrupt.h these functions are declared only if CONFIG_GENERIC_HARDIRQS is set. We should define them under identical conditions.

---
 kernel/irq/manage.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
kernel/irq/manage.c +1 -1
index cd0cd8d..618a64f 100644
@@ -15,7 +15,7 @@
 
 #include "internals.h"
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
 cpumask_var_t irq_default_affinity;
 
 static int init_irq_default_affinity(void)
Signature · 1 line
1.5.6.6
#2 lore raw

PATCH 2/2 cpumask fallout: Initialize irq_default_affinity earlier (v3).

In reply to David Daney

Move the initialization of irq_default_affinity to early_irq_init as core_initcall is too late.

irq_default_affinity can be used in init_IRQ and potentially timer and SMP init as well. All of these happen before core_initcall. Moving the initialization to early_irq_init ensures that it is initialized before it is used.

---
 kernel/irq/handle.c |   16 ++++++++++++++++
 kernel/irq/manage.c |    8 --------
 2 files changed, 16 insertions(+), 8 deletions(-)
kernel/irq/handle.c +16 -0
index c20db0b..3aba8d1 100644
@@ -39,6 +39,18 @@ void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
 	ack_bad_irq(irq);
 }
 
+#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
+static void __init init_irq_default_affinity(void)
+{
+	alloc_bootmem_cpumask_var(&irq_default_affinity);
+	cpumask_setall(irq_default_affinity);
+}
+#else
+static void __init init_irq_default_affinity(void)
+{
+}
+#endif
+
 /*
  * Linux has a controller-independent interrupt architecture.
  * Every controller has a 'controller-template', that is used
@@ -134,6 +146,8 @@ int __init early_irq_init(void)
 	int legacy_count;
 	int i;
 
+	init_irq_default_affinity();
+
 	desc = irq_desc_legacy;
 	legacy_count = ARRAY_SIZE(irq_desc_legacy);
 
@@ -219,6 +233,8 @@ int __init early_irq_init(void)
 	int count;
 	int i;
 
+	init_irq_default_affinity();
+
 	desc = irq_desc;
 	count = ARRAY_SIZE(irq_desc);
 
kernel/irq/manage.c +0 -8
index 618a64f..291f036 100644
@@ -18,14 +18,6 @@
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
 cpumask_var_t irq_default_affinity;
 
-static int init_irq_default_affinity(void)
-{
-	alloc_cpumask_var(&irq_default_affinity, GFP_KERNEL);
-	cpumask_setall(irq_default_affinity);
-	return 0;
-}
-core_initcall(init_irq_default_affinity);
-
 /**
  *	synchronize_irq - wait for pending IRQ handlers (on other CPUs)
  *	@irq: interrupt number to wait for
Signature · 1 line
1.5.6.6