diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2007-02-16 04:27:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-16 11:13:56 -0500 |
commit | 950f4427c2ddc921164088a20f01304cf231437c (patch) | |
tree | 8fd3fb1ad045a47dbd2c6ac238c6ff1c1c5aa6c6 | |
parent | b463fc60730bea6cdd73fec6edc6ec4658d47d37 (diff) |
[PATCH] Add irq flag to disable balancing for an interrupt
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 <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/i386/kernel/io_apic.c | 4 | ||||
-rw-r--r-- | include/linux/interrupt.h | 3 | ||||
-rw-r--r-- | include/linux/irq.h | 42 | ||||
-rw-r--r-- | kernel/irq/manage.c | 4 | ||||
-rw-r--r-- | kernel/irq/proc.c | 2 |
5 files changed, 35 insertions, 20 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index e30ccedad0b9..c76be1110922 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -482,8 +482,8 @@ static void do_irq_balance(void) | |||
482 | package_index = CPU_TO_PACKAGEINDEX(i); | 482 | package_index = CPU_TO_PACKAGEINDEX(i); |
483 | for (j = 0; j < NR_IRQS; j++) { | 483 | for (j = 0; j < NR_IRQS; j++) { |
484 | unsigned long value_now, delta; | 484 | unsigned long value_now, delta; |
485 | /* Is this an active IRQ? */ | 485 | /* Is this an active IRQ or balancing disabled ? */ |
486 | if (!irq_desc[j].action) | 486 | if (!irq_desc[j].action || irq_balancing_disabled(j)) |
487 | continue; | 487 | continue; |
488 | if ( package_index == i ) | 488 | if ( package_index == i ) |
489 | IRQ_DELTA(package_index,j) = 0; | 489 | IRQ_DELTA(package_index,j) = 0; |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 5a8ba0b8ccba..690113d07698 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -42,6 +42,8 @@ | |||
42 | * IRQF_SHARED - allow sharing the irq among several devices | 42 | * IRQF_SHARED - allow sharing the irq among several devices |
43 | * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur | 43 | * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur |
44 | * IRQF_TIMER - Flag to mark this interrupt as timer interrupt | 44 | * IRQF_TIMER - Flag to mark this interrupt as timer interrupt |
45 | * IRQF_PERCPU - Interrupt is per cpu | ||
46 | * IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing | ||
45 | */ | 47 | */ |
46 | #define IRQF_DISABLED 0x00000020 | 48 | #define IRQF_DISABLED 0x00000020 |
47 | #define IRQF_SAMPLE_RANDOM 0x00000040 | 49 | #define IRQF_SAMPLE_RANDOM 0x00000040 |
@@ -49,6 +51,7 @@ | |||
49 | #define IRQF_PROBE_SHARED 0x00000100 | 51 | #define IRQF_PROBE_SHARED 0x00000100 |
50 | #define IRQF_TIMER 0x00000200 | 52 | #define IRQF_TIMER 0x00000200 |
51 | #define IRQF_PERCPU 0x00000400 | 53 | #define IRQF_PERCPU 0x00000400 |
54 | #define IRQF_NOBALANCING 0x00000800 | ||
52 | 55 | ||
53 | /* | 56 | /* |
54 | * Migration helpers. Scheduled for removal in 1/2007 | 57 | * Migration helpers. Scheduled for removal in 1/2007 |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 5504b671357f..8930fb0ac9c7 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -31,7 +31,7 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, | |||
31 | /* | 31 | /* |
32 | * IRQ line status. | 32 | * IRQ line status. |
33 | * | 33 | * |
34 | * Bits 0-16 are reserved for the IRQF_* bits in linux/interrupt.h | 34 | * Bits 0-7 are reserved for the IRQF_* bits in linux/interrupt.h |
35 | * | 35 | * |
36 | * IRQ types | 36 | * IRQ types |
37 | */ | 37 | */ |
@@ -45,28 +45,31 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, | |||
45 | #define IRQ_TYPE_PROBE 0x00000010 /* Probing in progress */ | 45 | #define IRQ_TYPE_PROBE 0x00000010 /* Probing in progress */ |
46 | 46 | ||
47 | /* Internal flags */ | 47 | /* Internal flags */ |
48 | #define IRQ_INPROGRESS 0x00010000 /* IRQ handler active - do not enter! */ | 48 | #define IRQ_INPROGRESS 0x00000100 /* IRQ handler active - do not enter! */ |
49 | #define IRQ_DISABLED 0x00020000 /* IRQ disabled - do not enter! */ | 49 | #define IRQ_DISABLED 0x00000200 /* IRQ disabled - do not enter! */ |
50 | #define IRQ_PENDING 0x00040000 /* IRQ pending - replay on enable */ | 50 | #define IRQ_PENDING 0x00000400 /* IRQ pending - replay on enable */ |
51 | #define IRQ_REPLAY 0x00080000 /* IRQ has been replayed but not acked yet */ | 51 | #define IRQ_REPLAY 0x00000800 /* IRQ has been replayed but not acked yet */ |
52 | #define IRQ_AUTODETECT 0x00100000 /* IRQ is being autodetected */ | 52 | #define IRQ_AUTODETECT 0x00001000 /* IRQ is being autodetected */ |
53 | #define IRQ_WAITING 0x00200000 /* IRQ not yet seen - for autodetection */ | 53 | #define IRQ_WAITING 0x00002000 /* IRQ not yet seen - for autodetection */ |
54 | #define IRQ_LEVEL 0x00400000 /* IRQ level triggered */ | 54 | #define IRQ_LEVEL 0x00004000 /* IRQ level triggered */ |
55 | #define IRQ_MASKED 0x00800000 /* IRQ masked - shouldn't be seen again */ | 55 | #define IRQ_MASKED 0x00008000 /* IRQ masked - shouldn't be seen again */ |
56 | #define IRQ_PER_CPU 0x01000000 /* IRQ is per CPU */ | 56 | #define IRQ_PER_CPU 0x00010000 /* IRQ is per CPU */ |
57 | #define IRQ_NOPROBE 0x00020000 /* IRQ is not valid for probing */ | ||
58 | #define IRQ_NOREQUEST 0x00040000 /* IRQ cannot be requested */ | ||
59 | #define IRQ_NOAUTOEN 0x00080000 /* IRQ will not be enabled on request irq */ | ||
60 | #define IRQ_DELAYED_DISABLE 0x00100000 /* IRQ disable (masking) happens delayed. */ | ||
61 | #define IRQ_WAKEUP 0x00200000 /* IRQ triggers system wakeup */ | ||
62 | #define IRQ_MOVE_PENDING 0x00400000 /* need to re-target IRQ destination */ | ||
63 | #define IRQ_NO_BALANCING 0x00800000 /* IRQ is excluded from balancing */ | ||
64 | |||
57 | #ifdef CONFIG_IRQ_PER_CPU | 65 | #ifdef CONFIG_IRQ_PER_CPU |
58 | # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) | 66 | # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) |
67 | # define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) | ||
59 | #else | 68 | #else |
60 | # define CHECK_IRQ_PER_CPU(var) 0 | 69 | # define CHECK_IRQ_PER_CPU(var) 0 |
70 | # define IRQ_NO_BALANCING_MASK IRQ_NO_BALANCING | ||
61 | #endif | 71 | #endif |
62 | 72 | ||
63 | #define IRQ_NOPROBE 0x02000000 /* IRQ is not valid for probing */ | ||
64 | #define IRQ_NOREQUEST 0x04000000 /* IRQ cannot be requested */ | ||
65 | #define IRQ_NOAUTOEN 0x08000000 /* IRQ will not be enabled on request irq */ | ||
66 | #define IRQ_DELAYED_DISABLE 0x10000000 /* IRQ disable (masking) happens delayed. */ | ||
67 | #define IRQ_WAKEUP 0x20000000 /* IRQ triggers system wakeup */ | ||
68 | #define IRQ_MOVE_PENDING 0x40000000 /* need to re-target IRQ destination */ | ||
69 | |||
70 | struct proc_dir_entry; | 73 | struct proc_dir_entry; |
71 | struct msi_desc; | 74 | struct msi_desc; |
72 | 75 | ||
@@ -261,6 +264,11 @@ static inline int select_smp_affinity(unsigned int irq) | |||
261 | 264 | ||
262 | extern int no_irq_affinity; | 265 | extern int no_irq_affinity; |
263 | 266 | ||
267 | static inline int irq_balancing_disabled(unsigned int irq) | ||
268 | { | ||
269 | return irq_desc[irq].status & IRQ_NO_BALANCING_MASK; | ||
270 | } | ||
271 | |||
264 | /* Handle irq action chains: */ | 272 | /* Handle irq action chains: */ |
265 | extern int handle_IRQ_event(unsigned int irq, struct irqaction *action); | 273 | extern int handle_IRQ_event(unsigned int irq, struct irqaction *action); |
266 | 274 | ||
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index acc5d9fe462b..cd790ad0ae57 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -281,6 +281,10 @@ int setup_irq(unsigned int irq, struct irqaction *new) | |||
281 | if (new->flags & IRQF_PERCPU) | 281 | if (new->flags & IRQF_PERCPU) |
282 | desc->status |= IRQ_PER_CPU; | 282 | desc->status |= IRQ_PER_CPU; |
283 | #endif | 283 | #endif |
284 | /* Exclude IRQ from balancing */ | ||
285 | if (new->flags & IRQF_NOBALANCING) | ||
286 | desc->status |= IRQ_NO_BALANCING; | ||
287 | |||
284 | if (!shared) { | 288 | if (!shared) { |
285 | irq_chip_set_defaults(desc->chip); | 289 | irq_chip_set_defaults(desc->chip); |
286 | 290 | ||
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 6d3be06e8ce6..bb44bc995d6e 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -55,7 +55,7 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer, | |||
55 | cpumask_t new_value, tmp; | 55 | cpumask_t new_value, tmp; |
56 | 56 | ||
57 | if (!irq_desc[irq].chip->set_affinity || no_irq_affinity || | 57 | if (!irq_desc[irq].chip->set_affinity || no_irq_affinity || |
58 | CHECK_IRQ_PER_CPU(irq_desc[irq].status)) | 58 | irq_balancing_disabled(irq)) |
59 | return -EIO; | 59 | return -EIO; |
60 | 60 | ||
61 | err = cpumask_parse_user(buffer, count, new_value); | 61 | err = cpumask_parse_user(buffer, count, new_value); |