From: Thomas Gleixner <[EMAIL PROTECTED]>

Add a flag so we can prevent the irq balancing of an interrupt. Move
the bits, so we have room for more :)

Necessary for the ability to setup clocksources more flexible (e.g. use
the different HPET channels per CPU)

Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>

---
 arch/i386/kernel/io_apic.c |    4 ++--
 include/linux/interrupt.h  |    3 +++
 include/linux/irq.h        |   40 ++++++++++++++++++++++++----------------
 kernel/irq/manage.c        |    4 ++++
 kernel/irq/proc.c          |    2 +-
 5 files changed, 34 insertions(+), 19 deletions(-)

Index: linux-2.6.20-rc4-mm1-bo/arch/i386/kernel/io_apic.c
===================================================================
--- linux-2.6.20-rc4-mm1-bo.orig/arch/i386/kernel/io_apic.c
+++ linux-2.6.20-rc4-mm1-bo/arch/i386/kernel/io_apic.c
@@ -482,8 +482,8 @@ static void do_irq_balance(void)
                package_index = CPU_TO_PACKAGEINDEX(i);
                for (j = 0; j < NR_IRQS; j++) {
                        unsigned long value_now, delta;
-                       /* Is this an active IRQ? */
-                       if (!irq_desc[j].action)
+                       /* Is this an active IRQ or balancing disabled ? */
+                       if (!irq_desc[j].action || irq_balancing_disabled(j))
                                continue;
                        if ( package_index == i )
                                IRQ_DELTA(package_index,j) = 0;
Index: linux-2.6.20-rc4-mm1-bo/include/linux/interrupt.h
===================================================================
--- linux-2.6.20-rc4-mm1-bo.orig/include/linux/interrupt.h
+++ linux-2.6.20-rc4-mm1-bo/include/linux/interrupt.h
@@ -41,6 +41,8 @@
  * IRQF_SHARED - allow sharing the irq among several devices
  * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to 
occur
  * IRQF_TIMER - Flag to mark this interrupt as timer interrupt
+ * IRQF_PERCPU - Interrupt is per cpu
+ * IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing
  */
 #define IRQF_DISABLED          0x00000020
 #define IRQF_SAMPLE_RANDOM     0x00000040
@@ -48,6 +50,7 @@
 #define IRQF_PROBE_SHARED      0x00000100
 #define IRQF_TIMER             0x00000200
 #define IRQF_PERCPU            0x00000400
+#define IRQF_NOBALANCING       0x00000800
 
 typedef irqreturn_t (*irq_handler_t)(int, void *);
 
Index: linux-2.6.20-rc4-mm1-bo/include/linux/irq.h
===================================================================
--- linux-2.6.20-rc4-mm1-bo.orig/include/linux/irq.h
+++ linux-2.6.20-rc4-mm1-bo/include/linux/irq.h
@@ -31,7 +31,7 @@ typedef       void fastcall (*irq_flow_handler
 /*
  * IRQ line status.
  *
- * Bits 0-16 are reserved for the IRQF_* bits in linux/interrupt.h
+ * Bits 0-7 are reserved for the IRQF_* bits in linux/interrupt.h
  *
  * IRQ types
  */
@@ -45,27 +45,35 @@ typedef     void fastcall (*irq_flow_handler
 #define IRQ_TYPE_PROBE         0x00000010      /* Probing in progress */
 
 /* Internal flags */
-#define IRQ_INPROGRESS         0x00010000      /* IRQ handler active - do not 
enter! */
-#define IRQ_DISABLED           0x00020000      /* IRQ disabled - do not enter! 
*/
-#define IRQ_PENDING            0x00040000      /* IRQ pending - replay on 
enable */
-#define IRQ_REPLAY             0x00080000      /* IRQ has been replayed but 
not acked yet */
-#define IRQ_AUTODETECT         0x00100000      /* IRQ is being autodetected */
-#define IRQ_WAITING            0x00200000      /* IRQ not yet seen - for 
autodetection */
-#define IRQ_LEVEL              0x00400000      /* IRQ level triggered */
-#define IRQ_MASKED             0x00800000      /* IRQ masked - shouldn't be 
seen again */
-#define IRQ_PER_CPU            0x01000000      /* IRQ is per CPU */
+#define IRQ_INPROGRESS         0x00000100      /* IRQ handler active - do not 
enter! */
+#define IRQ_DISABLED           0x00000200      /* IRQ disabled - do not enter! 
*/
+#define IRQ_PENDING            0x00000400      /* IRQ pending - replay on 
enable */
+#define IRQ_REPLAY             0x00000800      /* IRQ has been replayed but 
not acked yet */
+#define IRQ_AUTODETECT         0x00001000      /* IRQ is being autodetected */
+#define IRQ_WAITING            0x00002000      /* IRQ not yet seen - for 
autodetection */
+#define IRQ_LEVEL              0x00004000      /* IRQ level triggered */
+#define IRQ_MASKED             0x00008000      /* IRQ masked - shouldn't be 
seen again */
+#define IRQ_PER_CPU            0x00010000      /* IRQ is per CPU */
+#define IRQ_NOPROBE            0x00020000      /* IRQ is not valid for probing 
*/
+#define IRQ_NOREQUEST          0x00040000      /* IRQ cannot be requested */
+#define IRQ_NOAUTOEN           0x00080000      /* IRQ will not be enabled on 
request irq */
+#define IRQ_DELAYED_DISABLE    0x00100000      /* IRQ disable (masking) 
happens delayed. */
+#define IRQ_WAKEUP             0x00200000      /* IRQ triggers system wakeup */
+#define IRQ_MOVE_PENDING       0x00400000      /* need to re-target IRQ 
destination */
+#define IRQ_NO_BALANCING       0x00800000      /* IRQ is excluded from 
balancing */
+
 #ifdef CONFIG_IRQ_PER_CPU
 # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
+# define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)
 #else
 # define CHECK_IRQ_PER_CPU(var) 0
+# define IRQ_NO_BALANCING_MASK IRQ_NO_BALANCING
 #endif
 
-#define IRQ_NOPROBE            0x02000000      /* IRQ is not valid for probing 
*/
-#define IRQ_NOREQUEST          0x04000000      /* IRQ cannot be requested */
-#define IRQ_NOAUTOEN           0x08000000      /* IRQ will not be enabled on 
request irq */
-#define IRQ_DELAYED_DISABLE    0x10000000      /* IRQ disable (masking) 
happens delayed. */
-#define IRQ_WAKEUP             0x20000000      /* IRQ triggers system wakeup */
-#define IRQ_MOVE_PENDING       0x40000000      /* need to re-target IRQ 
destination */
+static inline int irq_balancing_disabled(unsigned int irq)
+{
+       return irq_desc[irq].status & IRQ_NO_BALANCING_MASK;
+}
 
 struct proc_dir_entry;
 
Index: linux-2.6.20-rc4-mm1-bo/kernel/irq/manage.c
===================================================================
--- linux-2.6.20-rc4-mm1-bo.orig/kernel/irq/manage.c
+++ linux-2.6.20-rc4-mm1-bo/kernel/irq/manage.c
@@ -281,6 +281,10 @@ int setup_irq(unsigned int irq, struct i
        if (new->flags & IRQF_PERCPU)
                desc->status |= IRQ_PER_CPU;
 #endif
+       /* Exclude IRQ from balancing */
+       if (new->flags & IRQF_NOBALANCING)
+               desc->status |= IRQ_NO_BALANCING;
+
        if (!shared) {
                irq_chip_set_defaults(desc->chip);
 
Index: linux-2.6.20-rc4-mm1-bo/kernel/irq/proc.c
===================================================================
--- linux-2.6.20-rc4-mm1-bo.orig/kernel/irq/proc.c
+++ linux-2.6.20-rc4-mm1-bo/kernel/irq/proc.c
@@ -55,7 +55,7 @@ static int irq_affinity_write_proc(struc
        cpumask_t new_value, tmp;
 
        if (!irq_desc[irq].chip->set_affinity || no_irq_affinity ||
-                               CHECK_IRQ_PER_CPU(irq_desc[irq].status))
+           irq_balancing_disabled(irq))
                return -EIO;
 
        err = cpumask_parse_user(buffer, count, new_value);

--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to