免费注册 查看新帖 |

Chinaunix

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

[中断] 软中断被打断,硬中断中触发新的更高优先级软中断时怎么处理 [复制链接]

论坛徽章:
2
射手座
日期:2014-09-03 00:18:022015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-12 20:33 |只看该作者 |倒序浏览
本帖最后由 wLiu2007 于 2014-08-12 20:56 编辑

假设当前有3个softirq处于pending状态,然后__do_softirq正在处理第1个软中断,这个时候硬中断发生了,硬中断里面trigger了1个新的更高优先级的softirq,当中断返回的时候,检查in_interrupt不为0,所以不会重新调用do_softirq,而是返回中断前的__do_softirq中,

被中断的地方如果是在do_while这个循环中的话,只有等将pending标记的那些softirq都处理完了,才会处理新触发的softirq, 即这个时候需要将前3个softirq都处理完了才会处理这个新的softirq,尽管新触发的softirq优先级更高一些,不知道理解是否正确?
  1. asmlinkage void __do_softirq(void)
  2. {
  3.         struct softirq_action *h;
  4.         __u32 pending;
  5.         int max_restart = MAX_SOFTIRQ_RESTART;
  6.         int cpu;
  7.         unsigned long old_flags = current->flags;

  8.         /*
  9.          * Mask out PF_MEMALLOC s current task context is borrowed for the
  10.          * softirq. A softirq handled such as network RX might set PF_MEMALLOC
  11.          * again if the socket is related to swap
  12.          */
  13.         current->flags &= ~PF_MEMALLOC;

  14.         pending = local_softirq_pending();
  15.         account_system_vtime(current);

  16.         __local_bh_disable((unsigned long)__builtin_return_address(0),
  17.                                 SOFTIRQ_OFFSET);
  18.         lockdep_softirq_enter();

  19.         cpu = smp_processor_id();
  20. restart:
  21.         /* Reset the pending bitmask before enabling irqs */
  22.         set_softirq_pending(0);

  23.         local_irq_enable();

  24.         h = softirq_vec;

  25.         do {
  26.                 if (pending & 1) {
  27.                         unsigned int vec_nr = h - softirq_vec;
  28.                         int prev_count = preempt_count();

  29.                         kstat_incr_softirqs_this_cpu(vec_nr);

  30.                         trace_softirq_entry(vec_nr);
  31.                         h->action(h);
  32.                         trace_softirq_exit(vec_nr);
  33.                         if (unlikely(prev_count != preempt_count())) {
  34.                                 printk(KERN_ERR "huh, entered softirq %u %s %p"
  35.                                        "with preempt_count %08x,"
  36.                                        " exited with %08x?\n", vec_nr,
  37.                                        softirq_to_name[vec_nr], h->action,
  38.                                        prev_count, preempt_count());
  39.                                 preempt_count() = prev_count;
  40.                         }

  41.                         rcu_bh_qs(cpu);
  42.                 }
  43.                 h++;
  44.                 pending >>= 1;
  45.         }while (pending);   ///////////////////////////////////////////////////////////////////////////////////////while

  46.         local_irq_disable();

  47.         pending = local_softirq_pending();
  48.         if (pending && --max_restart)
  49.                 goto restart;

  50.         if (pending)
  51.                 wakeup_softirqd();

  52.         lockdep_softirq_exit();

  53.         account_system_vtime(current);
  54.         __local_bh_enable(SOFTIRQ_OFFSET);
  55.         tsk_restore_flags(current, old_flags, PF_MEMALLOC);
  56. }
复制代码



论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
2 [报告]
发表于 2014-08-12 21:21 |只看该作者
回复 1# wLiu2007

新一批的软中断,无论优先级多高,也得等到前一批的软中断被处理完成之后才能得到处理。而优先级只能帮助软中断在对应的批次中优先得到处理。
   

论坛徽章:
2
射手座
日期:2014-09-03 00:18:022015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2014-08-13 12:41 |只看该作者
这么看来 softirq的优先级是有场景限制的,跟进程的优先级还不太一样;

论坛徽章:
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
4 [报告]
发表于 2014-08-13 12:48 |只看该作者
Linux中,中断没有优先级,而且中断执行过程中默认是关中断的,不会嵌套,而是串行执行。。。。

论坛徽章:
0
5 [报告]
发表于 2014-08-13 16:23 |只看该作者
本帖最后由 oscarvei 于 2014-08-13 16:29 编辑

回复 1# wLiu2007


    假设当前有3个softirq处于pending状态,然后__do_softirq正在处理第1个软中断,这个时候硬中断发生了,硬中断里面trigger了1个<====楼主,硬中断可以被响应
我的理解,激发软中断,但是 irq还是disable的状态。应该无法响应新的硬中断。
373 /*
374  * Exit an interrupt context. Process softirqs if needed and possible:
375  */
376 void irq_exit(void)                 
377 {  
378 #ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
379         local_irq_disable();      
380 #else
381         WARN_ON_ONCE(!irqs_disabled());
382 #endif
383   
384         account_irq_exit_time(current);
385         preempt_count_sub(HARDIRQ_OFFSET);      
386         if (!in_interrupt() && local_softirq_pending())
387                 invoke_softirq();  

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
6 [报告]
发表于 2014-08-13 21:37 |只看该作者
回复 5# oscarvei

呵呵,虽然在此处关闭的中断,但在__do_softirq(void)里还是会打开中断的。软中断的Linux的概念里就是开中断运行的,如果它也是关中断的,那上下半的优点就全部丧失了。下面的代码来自 3.16内核,因为在早期的内核,如我手上的2.6.24内核,irq_exit是没有关中断的代码的。

226 asmlinkage __visible void __do_softirq(void)
227 {
228         unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
229         unsigned long old_flags = current->flags;
230         int max_restart = MAX_SOFTIRQ_RESTART;
231         struct softirq_action *h;
232         bool in_hardirq;
233         __u32 pending;
234         int softirq_bit;
235
236         /*
237          * Mask out PF_MEMALLOC s current task context is borrowed for the
238          * softirq. A softirq handled such as network RX might set PF_MEMALLOC
239          * again if the socket is related to swap
240          */
241         current->flags &= ~PF_MEMALLOC;
242
243         pending = local_softirq_pending();
244         account_irq_enter_time(current);
245
246         __local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET);
247         in_hardirq = lockdep_softirq_start();
248
249 restart:
250         /* Reset the pending bitmask before enabling irqs */
251         set_softirq_pending(0);
252
253         local_irq_enable();
254
255         h = softirq_vec;
256
257         while ((softirq_bit = ffs(pending))) {
258                 unsigned int vec_nr;
259                 int prev_count;

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP