免费注册 查看新帖 |

Chinaunix

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

关于vortex_interrupt()do-while循环条件的疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-01 11:41 |只看该作者 |倒序浏览
核心代码如下
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》说的当网卡有未决中断,并且是因为新的数据帧到达网卡,才会循环。
不明白我的理解错在哪里,望高手解惑。谢谢

求职 : 通讯/电信开
论坛徽章:
2
2015亚冠之鹿岛鹿角
日期:2015-07-08 11:58:2615-16赛季CBA联赛之佛山
日期:2015-12-21 17:28:04
2 [报告]
发表于 2015-11-01 11:07 |只看该作者
问题解决了吗?我不懂为什么  if (--work_done < 0) 会这样?为什么会小于0.

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
3 [报告]
发表于 2015-11-03 13:01 |只看该作者
是指在轮询的过程中产生了新的中断么(比如包速率太大)?
--workdone看起来用来防止无限的卡在rx中断处理上。

论坛徽章:
0
4 [报告]
发表于 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网络技术内幕》的描述是不太相同,但这个实例就是为了说明中断组合的,低负荷使用中断,高负荷使用定时器。这些都是我个人理解,不知道是否正确,希望别误人子弟。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP