免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: Godbach
打印 上一主题 下一主题

内核定时器与软中断 [复制链接]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
21 [报告]
发表于 2010-09-06 21:14 |只看该作者
你上面的解释说多处理器下需要使用_bh的

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
22 [报告]
发表于 2010-09-06 21:17 |只看该作者
回复 21# Godbach


    发现自己对preempt_count的知识完全错误.上面讲的_BH和多处理器的部分请全部忽略

论坛徽章:
0
23 [报告]
发表于 2010-09-06 22:14 |只看该作者
多谢解释啊。


我上面的第二问是,这个函数执行的时候为什么不会被本地软中断 中断,这个地方禁用了本地 ...
Godbach 发表于 2010-09-06 20:03



    同一个cpu的软中断是串行的,在《Linux内核设计与实现》中有解释。
定时器是通过软中断实现的(2.6)

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
24 [报告]
发表于 2010-09-06 22:38 |只看该作者
asmlinkage void do_softirq(void)
{
        __u32 pending;
        unsigned long flags;

        if (in_interrupt())
                return;

        local_irq_save(flags);

        pending = local_softirq_pending();

        if (pending)
                __do_softirq();

        local_irq_restore(flags);
}



每进程一个抢占计数,其实这个值又有3个字段.

* PREEMPT_MASK: 0x000000ff
* SOFTIRQ_MASK: 0x0000ff00
* HARDIRQ_MASK: 0x0fff0000

_bh就是在SOFTIRQ位段+1

#define irq_count()        (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
#define in_interrupt()                (irq_count())

恩,上次说vfree的in_interrupt在spin_lock_bh后返回判断为1就是这个原因.

LKD上确实说一个处理器的一个软中断不会被其他软中断打断.
所以单处理器和多处理器中软中断上下文确实都不需要_bh

至于如何实现的这一机制的看了半天代码没能完全领悟....

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
25 [报告]
发表于 2010-09-06 23:18 |只看该作者
解释很详细啊
bh中调用vfree是会有问题的。

论坛徽章:
0
26 [报告]
发表于 2010-09-07 10:56 |只看该作者
做个简单的测试。
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/timer.h>
  4. #include <linux/interrupt.h>

  5. static struct timer_list test_timer;

  6. static void showirq(unsigned long __data)
  7. {
  8.         if(in_irq())
  9.                 printk("In IRQ!\n");
  10.         if(in_softirq())
  11.                 printk("In SoftIRQ!\n");
  12.         if(preempt_count())
  13.                 printk("In Preempt %d!\n", preempt_count());
  14. }

  15. int test_init(void)
  16. {
  17.         setup_timer(&test_timer, showirq, 0);
  18.         mod_timer(&test_timer, jiffies+10*HZ);
  19.         return 0;
  20. }

  21. void test_fini(void)
  22. {
  23. }

  24. module_init(test_init);
  25. module_exit(test_fini);
复制代码
dmesg输出如下
  1. In SoftIRQ!
  2. In Preempt 256!
复制代码

评分

参与人数 1可用积分 +30 收起 理由
Godbach + 30 多谢分享

查看全部评分

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
27 [报告]
发表于 2010-09-07 11:19 |只看该作者
这个例子能否说明定时器运行的时候,禁用了软中断?

论坛徽章:
0
28 [报告]
发表于 2010-09-07 11:55 |只看该作者
这个例子能否说明定时器运行的时候,禁用了软中断?
Godbach 发表于 2010-09-07 11:19


可以这样认为,因为raise_softirq时,会检查in_interrupt()。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
29 [报告]
发表于 2010-09-07 11:58 |只看该作者
可以这样认为,因为raise_softirq时,会检查in_interrupt()。

如此如果想需要在定时器中使用 spin lock 的时候,使用 spin_lock 就可以了,没有必要再使用 spin_lock_bh 了

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
30 [报告]
发表于 2010-09-07 22:15 |只看该作者
不需要spin_lock_bh


do_softirq只有两个地方可能执行:  do_IRQ的中断上下文, ksoftirqd的进程上下文

这两个地方依靠SOFTIRQ_OFFSET处的计数来互斥.  
do_IRQ在执行do_softirq时,ksoftirqd在执行do_softirq时,以及local_bh_disabe时,均将递增这个计数器. 这个计数器非零,则本CPU随后将不再调用do_softirq的处理流程.


ksoftirqd及do_RQ之间, do_softoirq的过程为SOFTIRQ_OFFSET处的计数器互斥
do_IRQ及do_IRQ之间, do_softoirq的过程为SOFTIRQ_OFFSET处的计数器互斥
ksoftirqd嵌套ksoftirqd,不可能

评分

参与人数 1可用积分 +30 收起 理由
Godbach + 30 多谢分享

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP