irq_set_affinity_hint设置irq的affinity

在驱动中可以调用irq_set_affinity_hint来来设施cpu的affinity
int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
{
    unsigned long flags;
    struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);

    if (!desc)
        return -EINVAL;
    desc->affinity_hint = m;
    irq_put_desc_unlock(desc, flags);
    /* set the initial affinity to prevent every interrupt being on CPU0 */
如果struct cpumask *m不为0,就调用__irq_set_affinity 来设置affinity,如果为0的话,表示没有affinity,irq 可以运行到任何cpu上,之所以有m为0的case是因为调用request_irq 的时候irq 默认都是绑定到cpu0 上的,设置m为null,可以解除这个绑定
    if (m)
        __irq_set_affinity(irq, m, false);
    return 0;
}

int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force)
{
    struct irq_desc *desc = irq_to_desc(irq);
    unsigned long flags;
    int ret;

    if (!desc)
        return -EINVAL;

    raw_spin_lock_irqsave(&desc->lock, flags);
    ret = irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask, force);
    raw_spin_unlock_irqrestore(&desc->lock, flags);
    return ret;
}
继续调用irq_set_affinity_locked
int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask,
                bool force)
{
    struct irq_chip *chip = irq_data_get_irq_chip(data);
    struct irq_desc *desc = irq_data_to_desc(data);
    int ret = 0;

    if (!chip || !chip->irq_set_affinity)
        return -EINVAL;

    if (irq_can_move_pcntxt(data)) {
        ret = irq_do_set_affinity(data, mask, force);
    } else {
        irqd_set_move_pending(data);
        irq_copy_pending(desc, mask);
    }

    if (desc->affinity_notify) {
        kref_get(&desc->affinity_notify->kref);
        schedule_work(&desc->affinity_notify->work);
    }
    irqd_set(data, IRQD_AFFINITY_SET);

    return ret;
}
假定irq_can_move_pcntxt 返回ture ,则继续调用irq_do_set_affinity
int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
            bool force)
{
    struct irq_desc *desc = irq_data_to_desc(data);
    struct irq_chip *chip = irq_data_get_irq_chip(data);
    int ret;

    ret = chip->irq_set_affinity(data, mask, force);
    switch (ret) {
    case IRQ_SET_MASK_OK:
    case IRQ_SET_MASK_OK_DONE:
        cpumask_copy(desc->irq_common_data.affinity, mask);
    case IRQ_SET_MASK_OK_NOCOPY:
        irq_set_thread_affinity(desc);
        ret = 0;
    }

    return ret;
}
最终即使设定desc->irq_common_data.affinity 这个变量
这样当你调用cat /proc
static int show_irq_affinity(int type, struct seq_file *m, void *v)
{
    struct irq_desc *desc = irq_to_desc((long)m->private);
    const struct cpumask *mask = desc->irq_common_data.affinity;

#ifdef CONFIG_GENERIC_PENDING_IRQ
    if (irqd_is_setaffinity_pending(&desc->irq_data))
        mask = desc->pending_mask;
#endif
    if (type)
        seq_printf(m, "%*pbl\n", cpumask_pr_args(mask));
    else
        seq_printf(m, "%*pb\n", cpumask_pr_args(mask));
    return 0;
}

    /* create /proc/irq/<irq>/smp_affinity */
    proc_create_data("smp_affinity", 0644, desc->dir,
             &irq_affinity_proc_fops, (void *)(long)irq);

这样当你调用proc/irq/<irq>/smp_affinity的时候就可以看到这个irq的affinity
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值