gao1371wei 发表于 2009-06-01 11:41

关于vortex_interrupt()do-while循环条件的疑问

核心代码如下
static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    int work_done = max_interrupt_work;
    ioaddr = dev->base_addr;
    ... ... ...
    status = inw(ioaddr + EL3_STATUS);
    do {
      ... ... ...
      if (status & RxComplete)
            vortex_rx(dev);
      if (--work_done < 0) {
            /* Disable all pending interrupts. */
            ... ... ...
            /* The timer will re-enable interrupts. */
            mod_timer(&vp->timer, jiffies + 1*HZ);
            break;
      }
      ... ... ...
    } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
    ... ... ...
}
我的问题是,当网卡有一个未决中断,无论是和种原因产生的,那么((status = inw(ioaddr + EL3_STATUS)) & IntLatch是否非0呢?如果是非0的话,那么((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete))肯定也就非0,那么循环条件就不是像《Understanding Linux Network Internals》说的当网卡有未决中断,并且是因为新的数据帧到达网卡,才会循环。
不明白我的理解错在哪里,望高手解惑。谢谢

九阳神功爱喝茶 发表于 2015-11-01 11:07

问题解决了吗?我不懂为什么if (--work_done < 0) 会这样?为什么会小于0.

nswcfd 发表于 2015-11-03 13:01

是指在轮询的过程中产生了新的中断么(比如包速率太大)?
--workdone看起来用来防止无限的卡在rx中断处理上。

JIANGXIN04211 发表于 2015-12-08 11:23

本帖最后由 JIANGXIN04211 于 2015-12-08 11:32 编辑

这一个范例出自《深入理解linux网络技术内幕》,是为了说明中断组合的,即好的组合就是在低负荷下使用中断技术,在高负载在切换定时器驱动的中断事件。
实例代码
static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    int work_done = max_interrupt_work;//轮询的最大次数,默认为32
    ioaddr = dev->base_addr;
    ... ... ...
    status = inw(ioaddr + EL3_STATUS);//读取寄存器从而得到当前的中断状态
    do {
      ... ... ...
        //代表着新的帧已经接收,驱动可以去取了。因此调用vortex_rx得到数据,在这个函数里面会屏蔽掉中断,虽然屏蔽掉中断,我们的函数依然可以轮询硬件的中断寄存器,从而继续得到相应的中断状态。       
      if (status & RxComplete)
            vortex_rx(dev);
      if (--work_done < 0) {
            /* Disable all pending interrupts. */
            ... ... ...
            /* The timer will re-enable interrupts. */
            mod_timer(&vp->timer, jiffies + 1*HZ);
            break;
      }
      ... ... ...
    } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
      //这里是判断条件,当有未决中断,并且新的网络帧已经可以接受,我们就会一直循环
    ... ... ...
}
        上面代码时中断处理函数,中断处理函数要求尽量快的进行完成。定义一个默认值max_interrupt_work=32,为了在高负载的情况下通过--work_done能够退出循环。
        while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));对于这个判断条件的,我的个人理解是检测寄存器中有未决中断,并且新的网络帧已经可以接受,就会一直循环,--work_done小于0就说明当前在高负荷下工作,就要切换成定时器模式,释放cpu,可以使cpu响应其他中断。好像和《深入理解linux网络技术内幕》的描述是不太相同,但这个实例就是为了说明中断组合的,低负荷使用中断,高负荷使用定时器。这些都是我个人理解,不知道是否正确,希望别误人子弟。
页: [1]
查看完整版本: 关于vortex_interrupt()do-while循环条件的疑问