diff options
| author | Rusty Russell <rusty@rustcorp.com.au> | 2008-12-13 05:50:26 -0500 |
|---|---|---|
| committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-12-13 05:50:26 -0500 |
| commit | 0de26520c7cabf36e1de090ea8092f011a6106ce (patch) | |
| tree | 3d02e509b6315fdfd9cdb8c9e0b9ed0a30cf9384 /kernel/irq | |
| parent | 29c0177e6a4ac094302bed54a1d4bbb6b740a9ef (diff) | |
cpumask: make irq_set_affinity() take a const struct cpumask
Impact: change existing irq_chip API
Not much point with gentle transition here: the struct irq_chip's
setaffinity method signature needs to change.
Fortunately, not widely used code, but hits a few architectures.
Note: In irq_select_affinity() I save a temporary in by mangling
irq_desc[irq].affinity directly. Ingo, does this break anything?
(Folded in fix from KOSAKI Motohiro)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Mike Travis <travis@sgi.com>
Reviewed-by: Grant Grundler <grundler@parisc-linux.org>
Acked-by: Ingo Molnar <mingo@redhat.com>
Cc: ralf@linux-mips.org
Cc: grundler@parisc-linux.org
Cc: jeremy@xensource.com
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Diffstat (limited to 'kernel/irq')
| -rw-r--r-- | kernel/irq/chip.c | 2 | ||||
| -rw-r--r-- | kernel/irq/manage.c | 22 | ||||
| -rw-r--r-- | kernel/irq/migration.c | 14 | ||||
| -rw-r--r-- | kernel/irq/proc.c | 29 |
4 files changed, 37 insertions, 30 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 10b5092e9bfe..58d8e31daa49 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
| @@ -45,7 +45,7 @@ void dynamic_irq_init(unsigned int irq) | |||
| 45 | desc->irq_count = 0; | 45 | desc->irq_count = 0; |
| 46 | desc->irqs_unhandled = 0; | 46 | desc->irqs_unhandled = 0; |
| 47 | #ifdef CONFIG_SMP | 47 | #ifdef CONFIG_SMP |
| 48 | cpus_setall(desc->affinity); | 48 | cpumask_setall(&desc->affinity); |
| 49 | #endif | 49 | #endif |
| 50 | spin_unlock_irqrestore(&desc->lock, flags); | 50 | spin_unlock_irqrestore(&desc->lock, flags); |
| 51 | } | 51 | } |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 801addda3c43..10ad2f87ed9a 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
| @@ -79,7 +79,7 @@ int irq_can_set_affinity(unsigned int irq) | |||
| 79 | * @cpumask: cpumask | 79 | * @cpumask: cpumask |
| 80 | * | 80 | * |
| 81 | */ | 81 | */ |
| 82 | int irq_set_affinity(unsigned int irq, cpumask_t cpumask) | 82 | int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) |
| 83 | { | 83 | { |
| 84 | struct irq_desc *desc = irq_to_desc(irq); | 84 | struct irq_desc *desc = irq_to_desc(irq); |
| 85 | unsigned long flags; | 85 | unsigned long flags; |
| @@ -91,14 +91,14 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask) | |||
| 91 | 91 | ||
| 92 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 92 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
| 93 | if (desc->status & IRQ_MOVE_PCNTXT || desc->status & IRQ_DISABLED) { | 93 | if (desc->status & IRQ_MOVE_PCNTXT || desc->status & IRQ_DISABLED) { |
| 94 | desc->affinity = cpumask; | 94 | cpumask_copy(&desc->affinity, cpumask); |
| 95 | desc->chip->set_affinity(irq, cpumask); | 95 | desc->chip->set_affinity(irq, cpumask); |
| 96 | } else { | 96 | } else { |
| 97 | desc->status |= IRQ_MOVE_PENDING; | 97 | desc->status |= IRQ_MOVE_PENDING; |
| 98 | desc->pending_mask = cpumask; | 98 | cpumask_copy(&desc->pending_mask, cpumask); |
| 99 | } | 99 | } |
| 100 | #else | 100 | #else |
| 101 | desc->affinity = cpumask; | 101 | cpumask_copy(&desc->affinity, cpumask); |
| 102 | desc->chip->set_affinity(irq, cpumask); | 102 | desc->chip->set_affinity(irq, cpumask); |
| 103 | #endif | 103 | #endif |
| 104 | desc->status |= IRQ_AFFINITY_SET; | 104 | desc->status |= IRQ_AFFINITY_SET; |
| @@ -112,26 +112,24 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask) | |||
| 112 | */ | 112 | */ |
| 113 | int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc) | 113 | int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc) |
| 114 | { | 114 | { |
| 115 | cpumask_t mask; | ||
| 116 | |||
| 117 | if (!irq_can_set_affinity(irq)) | 115 | if (!irq_can_set_affinity(irq)) |
| 118 | return 0; | 116 | return 0; |
| 119 | 117 | ||
| 120 | cpus_and(mask, cpu_online_map, irq_default_affinity); | ||
| 121 | |||
| 122 | /* | 118 | /* |
| 123 | * Preserve an userspace affinity setup, but make sure that | 119 | * Preserve an userspace affinity setup, but make sure that |
| 124 | * one of the targets is online. | 120 | * one of the targets is online. |
| 125 | */ | 121 | */ |
| 126 | if (desc->status & (IRQ_AFFINITY_SET | IRQ_NO_BALANCING)) { | 122 | if (desc->status & (IRQ_AFFINITY_SET | IRQ_NO_BALANCING)) { |
| 127 | if (cpus_intersects(desc->affinity, cpu_online_map)) | 123 | if (cpumask_any_and(&desc->affinity, cpu_online_mask) |
| 128 | mask = desc->affinity; | 124 | < nr_cpu_ids) |
| 125 | goto set_affinity; | ||
| 129 | else | 126 | else |
| 130 | desc->status &= ~IRQ_AFFINITY_SET; | 127 | desc->status &= ~IRQ_AFFINITY_SET; |
| 131 | } | 128 | } |
| 132 | 129 | ||
| 133 | desc->affinity = mask; | 130 | cpumask_and(&desc->affinity, cpu_online_mask, &irq_default_affinity); |
| 134 | desc->chip->set_affinity(irq, mask); | 131 | set_affinity: |
| 132 | desc->chip->set_affinity(irq, &desc->affinity); | ||
| 135 | 133 | ||
| 136 | return 0; | 134 | return 0; |
| 137 | } | 135 | } |
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c index 9db681d95814..bd72329e630c 100644 --- a/kernel/irq/migration.c +++ b/kernel/irq/migration.c | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | void move_masked_irq(int irq) | 4 | void move_masked_irq(int irq) |
| 5 | { | 5 | { |
| 6 | struct irq_desc *desc = irq_to_desc(irq); | 6 | struct irq_desc *desc = irq_to_desc(irq); |
| 7 | cpumask_t tmp; | ||
| 8 | 7 | ||
| 9 | if (likely(!(desc->status & IRQ_MOVE_PENDING))) | 8 | if (likely(!(desc->status & IRQ_MOVE_PENDING))) |
| 10 | return; | 9 | return; |
| @@ -19,7 +18,7 @@ void move_masked_irq(int irq) | |||
| 19 | 18 | ||
| 20 | desc->status &= ~IRQ_MOVE_PENDING; | 19 | desc->status &= ~IRQ_MOVE_PENDING; |
| 21 | 20 | ||
| 22 | if (unlikely(cpus_empty(desc->pending_mask))) | 21 | if (unlikely(cpumask_empty(&desc->pending_mask))) |
| 23 | return; | 22 | return; |
| 24 | 23 | ||
| 25 | if (!desc->chip->set_affinity) | 24 | if (!desc->chip->set_affinity) |
| @@ -27,8 +26,6 @@ void move_masked_irq(int irq) | |||
| 27 | 26 | ||
| 28 | assert_spin_locked(&desc->lock); | 27 | assert_spin_locked(&desc->lock); |
| 29 | 28 | ||
| 30 | cpus_and(tmp, desc->pending_mask, cpu_online_map); | ||
| 31 | |||
| 32 | /* | 29 | /* |
| 33 | * If there was a valid mask to work with, please | 30 | * If there was a valid mask to work with, please |
| 34 | * do the disable, re-program, enable sequence. | 31 | * do the disable, re-program, enable sequence. |
| @@ -41,10 +38,13 @@ void move_masked_irq(int irq) | |||
| 41 | * For correct operation this depends on the caller | 38 | * For correct operation this depends on the caller |
| 42 | * masking the irqs. | 39 | * masking the irqs. |
| 43 | */ | 40 | */ |
| 44 | if (likely(!cpus_empty(tmp))) { | 41 | if (likely(cpumask_any_and(&desc->pending_mask, cpu_online_mask) |
| 45 | desc->chip->set_affinity(irq,tmp); | 42 | < nr_cpu_ids)) { |
| 43 | cpumask_and(&desc->affinity, | ||
| 44 | &desc->pending_mask, cpu_online_mask); | ||
| 45 | desc->chip->set_affinity(irq, &desc->affinity); | ||
| 46 | } | 46 | } |
| 47 | cpus_clear(desc->pending_mask); | 47 | cpumask_clear(&desc->pending_mask); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | void move_native_irq(int irq) | 50 | void move_native_irq(int irq) |
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index f293349d49d0..8e91c9762520 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
| @@ -40,33 +40,42 @@ static ssize_t irq_affinity_proc_write(struct file *file, | |||
| 40 | const char __user *buffer, size_t count, loff_t *pos) | 40 | const char __user *buffer, size_t count, loff_t *pos) |
| 41 | { | 41 | { |
| 42 | unsigned int irq = (int)(long)PDE(file->f_path.dentry->d_inode)->data; | 42 | unsigned int irq = (int)(long)PDE(file->f_path.dentry->d_inode)->data; |
| 43 | cpumask_t new_value; | 43 | cpumask_var_t new_value; |
| 44 | int err; | 44 | int err; |
| 45 | 45 | ||
| 46 | if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity || | 46 | if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity || |
| 47 | irq_balancing_disabled(irq)) | 47 | irq_balancing_disabled(irq)) |
| 48 | return -EIO; | 48 | return -EIO; |
| 49 | 49 | ||
| 50 | err = cpumask_parse_user(buffer, count, &new_value); | 50 | if (!alloc_cpumask_var(&new_value, GFP_KERNEL)) |
| 51 | return -ENOMEM; | ||
| 52 | |||
| 53 | err = cpumask_parse_user(buffer, count, new_value); | ||
| 51 | if (err) | 54 | if (err) |
| 52 | return err; | 55 | goto free_cpumask; |
| 53 | 56 | ||
| 54 | if (!is_affinity_mask_valid(new_value)) | 57 | if (!is_affinity_mask_valid(*new_value)) { |
| 55 | return -EINVAL; | 58 | err = -EINVAL; |
| 59 | goto free_cpumask; | ||
| 60 | } | ||
| 56 | 61 | ||
| 57 | /* | 62 | /* |
| 58 | * Do not allow disabling IRQs completely - it's a too easy | 63 | * Do not allow disabling IRQs completely - it's a too easy |
| 59 | * way to make the system unusable accidentally :-) At least | 64 | * way to make the system unusable accidentally :-) At least |
| 60 | * one online CPU still has to be targeted. | 65 | * one online CPU still has to be targeted. |
| 61 | */ | 66 | */ |
| 62 | if (!cpus_intersects(new_value, cpu_online_map)) | 67 | if (!cpumask_intersects(new_value, cpu_online_mask)) { |
| 63 | /* Special case for empty set - allow the architecture | 68 | /* Special case for empty set - allow the architecture |
| 64 | code to set default SMP affinity. */ | 69 | code to set default SMP affinity. */ |
| 65 | return irq_select_affinity_usr(irq) ? -EINVAL : count; | 70 | err = irq_select_affinity_usr(irq) ? -EINVAL : count; |
| 66 | 71 | } else { | |
| 67 | irq_set_affinity(irq, new_value); | 72 | irq_set_affinity(irq, new_value); |
| 73 | err = count; | ||
| 74 | } | ||
| 68 | 75 | ||
| 69 | return count; | 76 | free_cpumask: |
| 77 | free_cpumask_var(new_value); | ||
| 78 | return err; | ||
| 70 | } | 79 | } |
| 71 | 80 | ||
| 72 | static int irq_affinity_proc_open(struct inode *inode, struct file *file) | 81 | static int irq_affinity_proc_open(struct inode *inode, struct file *file) |
