免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 瀚海书香

[中断] 线上讨论之linux中断总结分享 [复制链接]

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
发表于 2011-11-29 08:23 |显示全部楼层
回复 11# tempname2
要想理解中断线程化,需要首先了解linux内核的中断处理机制。
linux中断处理是无优先级的嵌套处理,也就说每当有中断到达的时候,不管你在执行什么任务,都需要停下来去执行中断。那么这就出现了一个问题:一个对实时性要求非常高且优先级非常高的任务,可能会被一个不太重要的中断打断,这显然不是开发者希望的结果。

为了解决这个问题,内核从2.6.24之后(具体是在哪个版本添加的,可以去看log,至少在2.6.34中是包含的)引入了中断线程化处理。

中断线程化的处理,可以理解为在中断处理的上半部,又分成了两部分,一部分为简单的处理,一部分为线程处理。对于一个线程化的中断处理流程为:

do_IRQ-->handle_IRQ_event-->handler-->wake_up_thread
也就是说,线程化的中断,将中断的大部分处理动作,放到thread中,减少因为中断处理给实时任务的影响。

总结:从线程化中断的处理可以看出,它可以减少对实时任务的影响,但是它仍然会打断实时任务的运行。所以中断线程化只是治标不治本,要想从根本上解决中断对实时任务的影响,需要引入硬件优先级的概念。

论坛徽章:
0
发表于 2011-11-29 16:52 |显示全部楼层
问题提的很好,对深入理解中断很有帮助,期待有好的答案出现 。。。

论坛徽章:
0
发表于 2011-11-29 16:53 |显示全部楼层
问题提的很好,对深入理解中断很有帮助,期待有好的答案出现 。。。

论坛徽章:
154
2022北京冬奥会纪念版徽章
日期:2015-08-07 17:10:5720周年集字徽章-年
日期:2022-10-26 16:44:2015-16赛季CBA联赛之深圳
日期:2022-11-02 14:02:4515-16赛季CBA联赛之八一
日期:2022-11-28 12:07:4820周年集字徽章-20	
日期:2023-07-19 08:49:4515-16赛季CBA联赛之八一
日期:2023-11-04 19:23:5115-16赛季CBA联赛之广夏
日期:2023-12-13 18:09:34
发表于 2011-11-29 20:49 |显示全部楼层
很久不看中断了,典型的消息处理师祖啊

论坛徽章:
0
发表于 2011-11-29 21:59 |显示全部楼层
1.在ULK3的P138中提到:可以有选择地禁止IRQ线,但禁止的中断是丢失不了的,它们一旦激活,PIC就由将它们发送到CPU。请问PIC或内核是如何做到这一点的?
2.请问内核是如何保证同种中断串行化执行?

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
发表于 2011-11-29 22:33 |显示全部楼层
好活动,就我的理解说说讨论的这几个话题,抛砖引玉


1.什么是硬中断,什么是软中断?
硬中断指的是外部中断引脚引起的中断,是对CPU产生的中断,是硬件级别的。无论有无/任何操作系统均存在的。软中断在Linux内核中指的是softirq,处理一些相对于对硬件中断响应来说比较次要操作。

2.不同的硬中断是否可以嵌套?相同的硬中断是否可以嵌套?硬中断最多可能嵌套几级?
我认为,不同的硬件中断可以嵌套的,例如在第一个中断的ISR中打开中断,那么就可以允许别的中断进来处理。
我认为相同硬中断应该是不可以嵌套的,印象中一般发生一个中断,响应的中断控制器会自动屏蔽该中断,一般在中断处理结束后打开中断。不对请指正
最多可能嵌套多少级?这个我觉得应该是可以一直嵌套下去吧,只要栈允许。当然如果相同中断不允许嵌套的话,中断源也不会超过 preempt_count()字段中的HARDIRQ_MASK吧。

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
发表于 2011-11-29 22:33 |显示全部楼层
本帖最后由 amarant 于 2011-11-30 21:50 编辑

3.不同的软中断是否可以嵌套?相同的软中断是否可以嵌套?
在进入软中断处理前,do_softirq会判断
        if (in_interrupt())
                return;
如果当前正在执行中断,那么就直接返回。
也就是说,在执行软中断时,发生了一个硬件中断,在ISR执行完以后,会去检查是不是有软中断:
        if (!in_interrupt() && local_softirq_pending())
                invoke_softirq();
如果当前正处于中断处理上下文中(hardirq/softirq)那么就不会执行软中断。
但是一个软中断的处理中(h->action(h);)也可以调用__local_bh_enable(SOFTIRQ_OFFSET); 打开软中断。
那么从软中断的实现上来分析分析,在一个软中断处理的时候是通过一个pending存下当前存在的软中断,在根据该变量中的每一个位逐一处理。
如下代码段,如果软中断被嵌套了,那么假设被中断的是a,中断者是b。a处理了其中的一个软中断,b中断了a后,处理所有的软中断。那么返回a后,a仍旧以为还需要处理剩下的软中断,那么就重复处理了。
由此看来,软中断是不能嵌套的。

  1. pending = local_softirq_pending();
  2.         h = softirq_vec;

  3.         do {
  4.                 if (pending & 1) {
  5.                         unsigned int vec_nr = h - softirq_vec;
  6.                         int prev_count = preempt_count();
  7.         
  8.                         kstat_incr_softirqs_this_cpu(vec_nr);
  9.                         
  10.                         trace_softirq_entry(vec_nr);
  11.                         h->action(h);
  12.                         trace_softirq_exit(vec_nr);
  13.                         if (unlikely(prev_count != preempt_count())) {
  14.                                 printk(KERN_ERR "huh, entered softirq %u %s %p"
  15.                                        "with preempt_count %08x,"
  16.                                        " exited with %08x?\n", vec_nr,
  17.                                        softirq_to_name[vec_nr], h->action,
  18.                                        prev_count, preempt_count());
  19.                                 preempt_count() = prev_count;
  20.                         }

  21.                         rcu_bh_qs(cpu);
  22.                 }
  23.                 h++;
  24.                 pending >>= 1;
  25.         } while (pending);
复制代码
4.软中断在什么时间点被调度?
这个可以从cscope查看 :cs f c do_softirq
Cscope tag: do_softirq
   #   line  filename / context / line
   1    175  kernel/softirq.c <<_local_bh_enable_ip>>
             do_softirq();
   2    329  kernel/softirq.c <<invoke_softirq>>
             do_softirq();
   3   3039  net/core/dev.c <<netif_rx_ni>>
             do_softirq();
Type number and <Enter> (empty cancels):


do_softirq可以显式调用。
一般来说就是中断处理结束的时候会调用do_softrq,处理一定数量(MAX_SOFTIRQ_RESTART)次的软中断后,激活软中断守护进程(wakeup_softirqd())。该守护进程会在cpu空闲时开始处理没来得及处理的软中断。

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
发表于 2011-11-30 07:50 |显示全部楼层
回复 26# amarant
一般发生一个中断,响应的中断控制器会自动屏蔽该中断,一般在中断处理结束后打开中断。

对于有些中断来说,如果允许中断被打断,也就说 IRQF_DISABLED没有置位,那么在中断处理开启之前就会,打开中断。如果设置了IRQF_DISABLED,那么就会在执行完后才开启中断。
代码示例如下:
  1. irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
  2. {
  3.         irqreturn_t ret, retval = IRQ_NONE;
  4.         unsigned int status = 0;

  5.         handle_dynamic_tick(action);

  6.         if (!(action->flags & IRQF_DISABLED)) //这里判断是否需要开启中断
  7.                 local_irq_enable_in_hardirq();

  8.         do {
  9.                 ret = action->handler(irq, action->dev_id);
  10.                 if (ret == IRQ_HANDLED)
  11.                         status |= action->flags;
  12.                 retval |= ret;
  13.                 action = action->next;
  14.         } while (action);

  15.         if (status & IRQF_SAMPLE_RANDOM)
  16.                 add_interrupt_randomness(irq);
  17.         local_irq_disable();

  18.         return retval;
  19. }
复制代码

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
发表于 2011-11-30 08:03 |显示全部楼层
回复 25# flikelinux
1.在ULK3的P138中提到:可以有选择地禁止IRQ线,但禁止的中断是丢失不了的,它们一旦激活,PIC就由将它们发送到CPU。请问PIC或内核是如何做到这一点的?

内核通过两个标志位IRQ_DISABLED和IRQ_PENDING来找回丢失的中断。
当一个中断到来,但是该IRQ线被禁用,那么就会职位IRQ_PENDING,然后返回。当内核再次enable那条中断线的时候,会判断对应的irq是否有IRQ_PENDING标志位,如果有,说明丢失了中断,会强制PIC再产生一次中断。
2.请问内核是如何保证同种中断串行化执行?

内核通过IRQ_INPROGRESS标志位来确保中断执行的串行化。每当中断执行的时候,都会置位IRQ_INPROGRESS;而每当一个新的中断将要执行的时候,都会先检查对应的IRQ_INPROGRESS是否被置位,如果IRQ_INPROGESS被置位,说明该中断类型正在被处理,那么新的中断就会置位IRQ_PENDING,然后返回。保证串行化执行

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
发表于 2011-11-30 08:03 |显示全部楼层
回复 28# 瀚海书香

谢谢
    好久也没看中断这部分了,理解的不是很深。以前看的是2.6.10的,昨天看了下新的代码,既有do_IRQ又有handle_irq_event,请教下现在的内核是怎么组织他们的?我看entry. S还是call do_IRQ
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP