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>
This commit is contained in:
@@ -45,7 +45,7 @@ void dynamic_irq_init(unsigned int irq)
|
||||
desc->irq_count = 0;
|
||||
desc->irqs_unhandled = 0;
|
||||
#ifdef CONFIG_SMP
|
||||
cpus_setall(desc->affinity);
|
||||
cpumask_setall(&desc->affinity);
|
||||
#endif
|
||||
spin_unlock_irqrestore(&desc->lock, flags);
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ int irq_can_set_affinity(unsigned int irq)
|
||||
* @cpumask: cpumask
|
||||
*
|
||||
*/
|
||||
int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
|
||||
int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||
{
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
unsigned long flags;
|
||||
@@ -91,14 +91,14 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
|
||||
|
||||
#ifdef CONFIG_GENERIC_PENDING_IRQ
|
||||
if (desc->status & IRQ_MOVE_PCNTXT || desc->status & IRQ_DISABLED) {
|
||||
desc->affinity = cpumask;
|
||||
cpumask_copy(&desc->affinity, cpumask);
|
||||
desc->chip->set_affinity(irq, cpumask);
|
||||
} else {
|
||||
desc->status |= IRQ_MOVE_PENDING;
|
||||
desc->pending_mask = cpumask;
|
||||
cpumask_copy(&desc->pending_mask, cpumask);
|
||||
}
|
||||
#else
|
||||
desc->affinity = cpumask;
|
||||
cpumask_copy(&desc->affinity, cpumask);
|
||||
desc->chip->set_affinity(irq, cpumask);
|
||||
#endif
|
||||
desc->status |= IRQ_AFFINITY_SET;
|
||||
@@ -112,26 +112,24 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
|
||||
*/
|
||||
int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
cpumask_t mask;
|
||||
|
||||
if (!irq_can_set_affinity(irq))
|
||||
return 0;
|
||||
|
||||
cpus_and(mask, cpu_online_map, irq_default_affinity);
|
||||
|
||||
/*
|
||||
* Preserve an userspace affinity setup, but make sure that
|
||||
* one of the targets is online.
|
||||
*/
|
||||
if (desc->status & (IRQ_AFFINITY_SET | IRQ_NO_BALANCING)) {
|
||||
if (cpus_intersects(desc->affinity, cpu_online_map))
|
||||
mask = desc->affinity;
|
||||
if (cpumask_any_and(&desc->affinity, cpu_online_mask)
|
||||
< nr_cpu_ids)
|
||||
goto set_affinity;
|
||||
else
|
||||
desc->status &= ~IRQ_AFFINITY_SET;
|
||||
}
|
||||
|
||||
desc->affinity = mask;
|
||||
desc->chip->set_affinity(irq, mask);
|
||||
cpumask_and(&desc->affinity, cpu_online_mask, &irq_default_affinity);
|
||||
set_affinity:
|
||||
desc->chip->set_affinity(irq, &desc->affinity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@
|
||||
void move_masked_irq(int irq)
|
||||
{
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
cpumask_t tmp;
|
||||
|
||||
if (likely(!(desc->status & IRQ_MOVE_PENDING)))
|
||||
return;
|
||||
@@ -19,7 +18,7 @@ void move_masked_irq(int irq)
|
||||
|
||||
desc->status &= ~IRQ_MOVE_PENDING;
|
||||
|
||||
if (unlikely(cpus_empty(desc->pending_mask)))
|
||||
if (unlikely(cpumask_empty(&desc->pending_mask)))
|
||||
return;
|
||||
|
||||
if (!desc->chip->set_affinity)
|
||||
@@ -27,8 +26,6 @@ void move_masked_irq(int irq)
|
||||
|
||||
assert_spin_locked(&desc->lock);
|
||||
|
||||
cpus_and(tmp, desc->pending_mask, cpu_online_map);
|
||||
|
||||
/*
|
||||
* If there was a valid mask to work with, please
|
||||
* do the disable, re-program, enable sequence.
|
||||
@@ -41,10 +38,13 @@ void move_masked_irq(int irq)
|
||||
* For correct operation this depends on the caller
|
||||
* masking the irqs.
|
||||
*/
|
||||
if (likely(!cpus_empty(tmp))) {
|
||||
desc->chip->set_affinity(irq,tmp);
|
||||
if (likely(cpumask_any_and(&desc->pending_mask, cpu_online_mask)
|
||||
< nr_cpu_ids)) {
|
||||
cpumask_and(&desc->affinity,
|
||||
&desc->pending_mask, cpu_online_mask);
|
||||
desc->chip->set_affinity(irq, &desc->affinity);
|
||||
}
|
||||
cpus_clear(desc->pending_mask);
|
||||
cpumask_clear(&desc->pending_mask);
|
||||
}
|
||||
|
||||
void move_native_irq(int irq)
|
||||
|
@@ -40,33 +40,42 @@ static ssize_t irq_affinity_proc_write(struct file *file,
|
||||
const char __user *buffer, size_t count, loff_t *pos)
|
||||
{
|
||||
unsigned int irq = (int)(long)PDE(file->f_path.dentry->d_inode)->data;
|
||||
cpumask_t new_value;
|
||||
cpumask_var_t new_value;
|
||||
int err;
|
||||
|
||||
if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity ||
|
||||
irq_balancing_disabled(irq))
|
||||
return -EIO;
|
||||
|
||||
err = cpumask_parse_user(buffer, count, &new_value);
|
||||
if (err)
|
||||
return err;
|
||||
if (!alloc_cpumask_var(&new_value, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
|
||||
if (!is_affinity_mask_valid(new_value))
|
||||
return -EINVAL;
|
||||
err = cpumask_parse_user(buffer, count, new_value);
|
||||
if (err)
|
||||
goto free_cpumask;
|
||||
|
||||
if (!is_affinity_mask_valid(*new_value)) {
|
||||
err = -EINVAL;
|
||||
goto free_cpumask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not allow disabling IRQs completely - it's a too easy
|
||||
* way to make the system unusable accidentally :-) At least
|
||||
* one online CPU still has to be targeted.
|
||||
*/
|
||||
if (!cpus_intersects(new_value, cpu_online_map))
|
||||
if (!cpumask_intersects(new_value, cpu_online_mask)) {
|
||||
/* Special case for empty set - allow the architecture
|
||||
code to set default SMP affinity. */
|
||||
return irq_select_affinity_usr(irq) ? -EINVAL : count;
|
||||
err = irq_select_affinity_usr(irq) ? -EINVAL : count;
|
||||
} else {
|
||||
irq_set_affinity(irq, new_value);
|
||||
err = count;
|
||||
}
|
||||
|
||||
irq_set_affinity(irq, new_value);
|
||||
|
||||
return count;
|
||||
free_cpumask:
|
||||
free_cpumask_var(new_value);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int irq_affinity_proc_open(struct inode *inode, struct file *file)
|
||||
|
@@ -136,7 +136,7 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast)
|
||||
*/
|
||||
static void tick_setup_device(struct tick_device *td,
|
||||
struct clock_event_device *newdev, int cpu,
|
||||
const cpumask_t *cpumask)
|
||||
const struct cpumask *cpumask)
|
||||
{
|
||||
ktime_t next_event;
|
||||
void (*handler)(struct clock_event_device *) = NULL;
|
||||
@@ -171,8 +171,8 @@ static void tick_setup_device(struct tick_device *td,
|
||||
* When the device is not per cpu, pin the interrupt to the
|
||||
* current cpu:
|
||||
*/
|
||||
if (!cpus_equal(newdev->cpumask, *cpumask))
|
||||
irq_set_affinity(newdev->irq, *cpumask);
|
||||
if (!cpumask_equal(&newdev->cpumask, cpumask))
|
||||
irq_set_affinity(newdev->irq, cpumask);
|
||||
|
||||
/*
|
||||
* When global broadcasting is active, check if the current
|
||||
|
Reference in New Issue
Block a user