免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2624 | 回复: 1
打印 上一主题 下一主题

请问kernel的handle_edge_irq函数是否有同步问题? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-07-07 18:49 |只看该作者 |倒序浏览
内核文件kernel\irq\chip.c中定义有handle_edge_irq函数。

这个函数使用spin_lock和spin_unlock做同步。但是查看源代码后发现spin_lock和spin_unlock这两个函数并没有关闭中断,那么如果中断发生的话是否会造成handle_edge_irq数据不同步的问题呢?假设的平台是单核arm cpu。

void
handle_edge_irq(unsigned int irq, struct irq_desc *desc)
{
        spin_lock(&desc->lock);

        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);

        /*
         * If we're currently running this IRQ, or its disabled,
         * we shouldn't process the IRQ. Mark it pending, handle
         * the necessary masking and go out
         */
        if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
                    !desc->action)) {
                desc->status |= (IRQ_PENDING | IRQ_MASKED);
                mask_ack_irq(desc, irq);
                goto out_unlock;
        }
        kstat_incr_irqs_this_cpu(irq, desc);

        /* Start handling the irq */
        if (desc->chip->ack)
                desc->chip->ack(irq);

        /* Mark the IRQ currently in progress.*/
        desc->status |= IRQ_INPROGRESS;

        do {
                struct irqaction *action = desc->action;
                irqreturn_t action_ret;

                if (unlikely(!action)) {
                        desc->chip->mask(irq);
                        goto out_unlock;
                }

                /*
                 * When another irq arrived while we were handling
                 * one, we could have masked the irq.
                 * Renable it, if it was not disabled in meantime.
                 */
                if (unlikely((desc->status &
                               (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
                              (IRQ_PENDING | IRQ_MASKED))) {
                        desc->chip->unmask(irq);
                        desc->status &= ~IRQ_MASKED;
                }

                desc->status &= ~IRQ_PENDING;
                spin_unlock(&desc->lock);
                action_ret = handle_IRQ_event(irq, action);
                if (!noirqdebug)
                        note_interrupt(irq, desc, action_ret);
                spin_lock(&desc->lock);

        } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);

        desc->status &= ~IRQ_INPROGRESS;
out_unlock:
        spin_unlock(&desc->lock);
}

论坛徽章:
0
2 [报告]
发表于 2010-08-09 14:16 |只看该作者
我自己来回答吧,碰巧想明白啦。

单核cpu下,执行到这个函数的时候,中断已经被关闭,自然不会有文中提到的冲突问题。
ps:arm平台下,中断发生时就会kernel调用这个中断处理函数,所以中断自然是被关闭的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP