免费注册 查看新帖 |

Chinaunix

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

[中断] Linux下半部——谁先运行 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-02-18 21:00 |只看该作者 |倒序浏览
看博客有写到:一个软中断不会去抢占另一个软中断。
      个人理解如下:《Linux内核设计与实现》中提到,如果软中断存在共享数据,那么需要进行加锁保护,因为同类型的软中断可以同时在不同的CPU下运行。所以,一个软中断不会去抢占另一个软中断,这句话的是在一个CPU上吧?
       以下内容为个人猜想,不对的地方还请指正。假设硬件中断频繁发生,那么就会挤压了多个下半部(tasklet)在等待处理,这些tasklet应该是以队列的形式存放起来的。空闲的CPU从队列中取出一个tasklet进行处理,所以所有CPU都在处理软中断。 假设在一个CPU上,正在运行软中断A,此时来了一个中断,该中断处理也分为硬中断B和软中断B,硬中断B肯定可以抢占CPU运行。  那么接下来,执行软中断A还是软中断B呢?  是软中断A运行完以后,立即运行B,还是会放入队列当中啊?

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
2 [报告]
发表于 2014-02-19 08:39 |只看该作者
“一个软中断不会去抢占另一个软中断,这句话的是在一个CPU上吧?”---对的
软中断运行顺序的问题,记得:首先软中断是分类型的,比如网络、磁盘、定时器等,各类型有一定的优先顺序,其次同类的软中断,应该是以队列方式维护的,也就是FIFO。

论坛徽章:
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
3 [报告]
发表于 2014-02-22 14:38 |只看该作者
本帖最后由 smalloc 于 2014-02-22 14:58 编辑

多处理器的同步只能依赖类似spinlock的机制.
2.6.13中采用test_and_set_bit保护每个用户自注册的tasklet在多处理器环境下自身序列化.非同一个定义的tasklet(以tasklet_init的执行来区分)仍然可以在多处理器上同时运行. 如果数据由同一个tasklet独享,那么就无需多处理器间保护.甚至,此版本中的tasklet_init是注册在per cpu变量中的,那么如果保证同一个CPU上注册的tasklet也是多处理器串行的,即使共享数据也无需要保护.而类似网络处理软中断,可以在多处理器上同时运行自身.(如果不考虑处理的数据包,则2个运行的实例完全相同).

论坛徽章:
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
4 [报告]
发表于 2014-02-22 18:25 |只看该作者
回复 1# yandongxiao


    软中断被中断,返回后会继续执行未完成的软中断. 硬中断可能和被打断的软中断使用同一个堆栈,硬中断返回时数据弹出堆栈,继续原先的软中断

论坛徽章:
0
5 [报告]
发表于 2014-02-28 06:20 |只看该作者
bump u up for 2 points

论坛徽章:
0
6 [报告]
发表于 2014-03-25 21:03 |只看该作者
yandongxiao 发表于 2014-02-18 21:00
那么接下来,执行软中断A还是软中断B呢?  是软中断A运行完以后,立即运行B,还是会放入队列当中啊?


如果你这里的软中断时指softirq的话,那么:
查看了一下代码,流程应该是这样:
1. 当某CPU正在run softirq A,这时来了一个硬件中断,硬件中断打断软件中断;
2. 硬件中断在上半部raise了软中断B的pending标志;
3. 硬件中断运行完毕,call  irq_exit :
  1. void irq_exit(void)
  2. {
  3.         account_system_vtime(current);
  4.         trace_hardirq_exit();
  5.         sub_preempt_count(IRQ_EXIT_OFFSET);
  6.         if (!in_interrupt() && local_softirq_pending())
  7.                 invoke_softirq();

  8.         rcu_irq_exit();
  9. #ifdef CONFIG_NO_HZ
  10.         /* Make sure that timer wheel updates are propagated */
  11.         if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched())
  12.                 tick_nohz_stop_sched_tick(0);
  13. #endif
  14.         preempt_enable_no_resched();
  15. }
复制代码
4. 注意这里的代码:
        if (!in_interrupt() && local_softirq_pending())
                invoke_softirq();
是说如果现在的环境本身就是在中断中(软中断也是在中断环境中),那么!in_interrupt()就会返回false,那么就不会运行invoke_softirq()

5. 硬件中断继续返回到被打断的地方(即先前的softirq A的处理中),kernel继续运行softirq A。
请注意在step 2中kernel已经raise了softirq B的pending位,所以在函数__do_softirq中,会重新check到softirq B的bit,从而运行softirq B的action
  1. restart:
  2.         /* Reset the pending bitmask before enabling irqs */
  3.         set_softirq_pending(0);

  4.         local_irq_enable();

  5.         h = softirq_vec;

  6.         do {
  7.                 if (pending & 1) {
  8.                         int prev_count = preempt_count();
  9.                         kstat_incr_softirqs_this_cpu(h - softirq_vec);

  10.                         trace_softirq_entry(h, softirq_vec);
  11.                         h->action(h);
  12.                         trace_softirq_exit(h, softirq_vec);
  13.                         if (unlikely(prev_count != preempt_count())) {
  14.                                 printk(KERN_ERR "huh, entered softirq %td %s %p"
  15.                                        "with preempt_count %08x,"
  16.                                        " exited with %08x?\n", h - softirq_vec,
  17.                                        softirq_to_name[h - softirq_vec],
  18.                                        h->action, prev_count, preempt_count());
  19.                                 preempt_count() = prev_count;
  20.                         }

  21.                         rcu_bh_qs(cpu);
  22.                 }
  23.                 h++;
  24.                 pending >>= 1;
  25.         } while (pending);

  26.         local_irq_disable();

  27.         pending = local_softirq_pending();
  28.         if (pending && --max_restart)
  29.                 goto restart;
复制代码

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
7 [报告]
发表于 2014-03-25 22:47 |只看该作者
回复 6# studying_linux


    irq_enter()/irq_exit()是硬件中断的入口和出口???

论坛徽章:
0
8 [报告]
发表于 2014-03-26 00:23 |只看该作者
kiongf 发表于 2014-03-25 22:47
回复 6# studying_linux


刚又看了一下代码,好像没看错。。。
如果错了请指正~

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
9 [报告]
发表于 2014-03-26 18:15 |只看该作者
回复 8# studying_linux


    中断不大懂.因为这个函数的调用者是architecture-dependent, 所以想先确认下.

论坛徽章:
0
10 [报告]
发表于 2014-03-26 19:33 |只看该作者
kiongf 发表于 2014-03-26 18:15
回复 8# studying_linux

{:2_178:}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP