+ -
当前位置:首页 → 问答吧 → 请问kernel的handle_edge_irq函数是否有同步问题?

请问kernel的handle_edge_irq函数是否有同步问题?

时间:2010-07-07

来源:互联网

内核文件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);
}

作者: tassard   发布时间: 2010-07-07

我自己来回答吧,碰巧想明白啦。

单核cpu下,执行到这个函数的时候,中断已经被关闭,自然不会有文中提到的冲突问题。
ps:arm平台下,中断发生时就会kernel调用这个中断处理函数,所以中断自然是被关闭的。

作者: tassard   发布时间: 2010-08-09

热门下载

更多