request_irq->request_threaded_irq->__setup_irq,在这个函数中和绑定cpu最终要的参数是
首先定义: cpumask_var_t mask;
然后为mask申请空间:
if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {
ret = -ENOMEM;
goto out_thread;
}
3调用 setup_affinity(desc, mask);将irq 默认绑定到cpu0上
static int setup_affinity(struct irq_desc *desc, struct cpumask *mask)
{
struct cpumask *set = irq_default_affinity;
int node = irq_desc_get_node(desc);
/* Excludes PER_CPU and NO_BALANCE interrupts */
if (!__irq_can_set_affinity(desc))
return 0;
/*
* Preserve the managed affinity setting and an userspace affinity
* setup, but make sure that one of the targets is online.
*/
if (irqd_affinity_is_managed(&desc->irq_data) ||
irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) {
if (cpumask_intersects(desc->irq_common_data.affinity,
cpu_online_mask))
set = desc->irq_common_data.affinity;
else
irqd_clear(&desc->irq_data, IRQD_AFFINITY_SET);
}
//可以看到直接调用将cpu_online_mask和set 做与操作后复制给mask,这里的set 可以通过kernel commandline
irqaffinity来制定,如果没有指定的话,会调用init_irq_default_affinity 设置为全F。
cpumask_and(mask, cpu_online_mask, set);
if (node != NUMA_NO_NODE) {
const struct cpumask *nodemask = cpumask_of_node(node);
/* make sure at least one of the cpus in nodemask is online */
if (cpumask_intersects(mask, nodemask))
cpumask_and(mask, mask, nodemask);
}
//最终调用irq_do_set_affinity 来设置irq的affinity
irq_do_set_affinity(&desc->irq_data, mask, false);
return 0;
}
所以总结一下,通过request_irq 申请的中断,如果不制定irq affinity的话,irq的handler就是可以运行在所有cpu上。具体可以通过 cat /proc/interrupts
首先定义: cpumask_var_t mask;
然后为mask申请空间:
if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {
ret = -ENOMEM;
goto out_thread;
}
3调用 setup_affinity(desc, mask);将irq 默认绑定到cpu0上
static int setup_affinity(struct irq_desc *desc, struct cpumask *mask)
{
struct cpumask *set = irq_default_affinity;
int node = irq_desc_get_node(desc);
/* Excludes PER_CPU and NO_BALANCE interrupts */
if (!__irq_can_set_affinity(desc))
return 0;
/*
* Preserve the managed affinity setting and an userspace affinity
* setup, but make sure that one of the targets is online.
*/
if (irqd_affinity_is_managed(&desc->irq_data) ||
irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) {
if (cpumask_intersects(desc->irq_common_data.affinity,
cpu_online_mask))
set = desc->irq_common_data.affinity;
else
irqd_clear(&desc->irq_data, IRQD_AFFINITY_SET);
}
//可以看到直接调用将cpu_online_mask和set 做与操作后复制给mask,这里的set 可以通过kernel commandline
irqaffinity来制定,如果没有指定的话,会调用init_irq_default_affinity 设置为全F。
cpumask_and(mask, cpu_online_mask, set);
if (node != NUMA_NO_NODE) {
const struct cpumask *nodemask = cpumask_of_node(node);
/* make sure at least one of the cpus in nodemask is online */
if (cpumask_intersects(mask, nodemask))
cpumask_and(mask, mask, nodemask);
}
//最终调用irq_do_set_affinity 来设置irq的affinity
irq_do_set_affinity(&desc->irq_data, mask, false);
return 0;
}
所以总结一下,通过request_irq 申请的中断,如果不制定irq affinity的话,irq的handler就是可以运行在所有cpu上。具体可以通过 cat /proc/interrupts