免费注册 查看新帖 |

Chinaunix

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

[中断] papaya内核笔记 [复制链接]

论坛徽章:
13
程序设计版块每日发帖之星
日期:2016-06-29 06:20:00每日论坛发贴之星
日期:2016-08-14 06:20:00操作系统版块每日发帖之星
日期:2016-08-14 06:20:00每日论坛发贴之星
日期:2016-08-13 06:20:00数据库技术版块每日发帖之星
日期:2016-08-13 06:20:00程序设计版块每日发帖之星
日期:2016-08-13 06:20:00IT运维版块每日发帖之星
日期:2016-08-13 06:20:00每日论坛发贴之星
日期:2016-08-12 06:20:00数据库技术版块每日发帖之星
日期:2016-08-12 06:20:00程序设计版块每日发帖之星
日期:2016-08-12 06:20:00操作系统版块每日发帖之星
日期:2016-08-12 06:20:00综合交流区版块每日发帖之星
日期:2016-08-09 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-06-15 11:44 |只看该作者 |倒序浏览
读了两天的linux代码,一点点心得跟大家分享,高手轻拍~

【感觉到对BH的需求了】
  之前写IDE驱动的时候就有感觉,不过还好。这两天写网卡驱动,更加感到BH的重要。不只是提高中断的响应能力,有些代码放在BH里会特别舒服。像发包中断(TOK)的handler可能要调用netif_wake_queue,这个函数会调用驱动接口start_xmit发包,而start_xmit()我在设计的时候,是默认硬中断已打开,如果不推迟到BH里调用它,而是放在do_IRQ的action里,那start_xmit里就要做irq_save了,但我的irq_save的实现又是依赖于task_struct的,这样一来,就必须进程才能调用网卡驱动,内核本身不能。


【BH没那么糟】
“一旦一个bh在执行,其它所有的bh要等它执行完。” 开始看到这种话,觉得是bh的缺点,现在不禁一笑————不等着能怎么办呢?2.0时期的linux,cpu只有一个核。
tasklet只是多核版本的bh,真正了不起的是softirq才对,那些驱动程序员处理各种并发时,应该很有存在感。

【任务队列的效率似乎不高】
  我开始觉得bh太简单,想实现的是task queue。(我其实想做softirq的,可惜我的内核不支持多核)
  但发现用链表实现bh机制太笨重。我几乎快想好了,就是临界区的时候,把head和tail复制到局部变量,然后遍历。这样BH过程中随便硬中断怎么mark_bh()都行。
  但还是不行,因为mark_bh()(不知道是它是什么函数,就用mark_bh指代吧)的时候,这些tq_struct会从inactive队列,跑到active队列。遍历会失败。
  看linux的源码,它竟然是每执行完一个tq_struct,就直接从队列里删掉。那估计它mark_bh()的时候,也是新生成一个tq_struct插进去。有点儿恐怖,跟BH相比,重的像砖头。
  2.6里它已经被work queue取代了,由一个线程负责,可以延时,休眠的。

【BH更像一个hook】
  觉得bh更像一个“钩子”,在内核routine的某些点调用用户(通常是驱动程序员)注册的函数。要支持这种钩子,两个难点:1, 它全程基本上是开中断的,在次级中断里,用户又会注册一些钩子。我们面临一些变量的“并发”(某种意义上的)读写。第二点,就是内核设计着要对do_BH()前后,内核的流程很熟悉。我们在这里概述一下:
  一个硬件中断的流程: 硬件自动保存断点; 软件SAVE_ALL; 进入DO_IRQ; DO_IRQ调用这个中断通道上注册的所有action; 执行SOFTIRQ(如果有的话); 执行完SOFTIRQ,DO_IRQ也就完了,routine流向ret_from_intr,内核在此处会瞄一眼,看是要回哪儿去。用户空间(ring 3)?那先调到ret_with_reschedue,因为硬中断引发的进程切换是再正常不过的了。仍旧是回到内核空间(ring 0)?那就那就直接跳到restore_all了。linux内核的原则是,内核态的中断不会引发进程调度。(2.4以前)

【linux的do_softirq源码分析】
这段do_softirq,我都是当做do_bh()去读的,竟然觉得每一句都读懂了。
所以下文有一些语病,像比mark_bh,朋友们就自动联想吧,我懒得去找softirq里它叫什么了。
---------------kernel/softirq.c-----
50 asmlinkage void do_softirq()
51 {
52         int cpu = smp_processor_id();
53         __u32 active, mask;
54
55         if (in_interrupt())
56         return;
57
58         local_bh_disable();
59
60         local_irq_disable();
61         mask = softirq_mask(cpu);
62         active = softirq_active(cpu) & mask;
63
64         if (active) {
65         struct softirq_action *h;
66
67         restart:
68         /* Reset active bitmask before enabling irqs */
69         softirq_active(cpu) &= ~active;
70
71         local_irq_enable();
72
73         h = softirq_vec;
74         mask &= ~active;
75
76         do {
77                 if (active & 1)
78                 h->action(h);
79                 h++;
80                 active >>= 1;
81         } while (active);
82
83         local_irq_disable();
84
85         active = softirq_active(cpu);
86         if ((active &= mask) != 0)
87         goto retry;
88         }
89
90         local_bh_enable();
91
92         /* Leave with locally disabled hard irqs. It is critical to close
93         * window for infinite recursion, while we help local bh count,
94         * it protected us. Now we are defenceless.
95         */
96         return;
97
98         retry:
99         goto restart;
100 }

  首先,第52行int cpu = smp_processor_id()获取当前是在哪个核,softirq在设计上,为每个核分配了专属的mask和active,每个核只需要关心自己本地的softirq就行了。
  借用网上的一段话:整个softirq机制的设计与实现中自始自终都贯彻了一个思想:“谁触发,谁执行”(Who marks,Who runs),也即触发软中断的那个CPU负责执行它所触发的软中断,而且每个CPU都由它自己的软中断触发与控制机制。
  接着local_bh_disable()。我们知道,执行do_softirq过程中(几乎)是全程开中断的,我们把发生于这个过程中的硬中断叫“次级中断”,中断的routine都是千篇一律的,当次级中断的routine走到do_IRQ里的do_softirq时,我们要阻止它进入。这就是local_bh_disable()的作用。
  紧接着是local_irq_disable()。因为接下来要操作mask,active这两个关键变量,次级中断里可能会竞争访问(通过mark_bh()),没有别的办法,只能关掉硬中断。
  到71行,再local_irq_enable(),就进入do_irq经典的情景了,开中断干活儿。
  注意61,62行,我们把active和mask两个全局变量复制到局部变量,仍旧是怕次级中断。但硬中断不能再关下去了,只好先复制下来:次级中断,active和mask变量就交给你随便折腾了,我先处理完这一批active bits再说。
  76~81行是执行active bits对应的action,代码很轻巧,不赘述。
  到83行又local_irq_disable(),因为又要读全局变量active了,它反映自local_bh_disable以来,又产生的softirq。复制下来,循环处理。注意,上一批的active bits已经在69行给清掉了。
  最后,第90行,很重要的一句:
  local_bh_enable()。
  系统从do_softirq出去时,硬中断从此就关了,直到iret。此时已接近这次中断routine的尾声。
  中断当然要关,因为接下来的操作都是entry.S里非常脆弱的操作,像restore_all时,是不可能允许中断发生的。
  
  PS: 等测试过了,我再把我的源码贴出来,因为网卡驱动没写完,内核现在还编译不了。

论坛徽章:
146
2015年亚洲杯之日本
日期:2015-04-28 13:32:012015年亚洲杯之朝鲜
日期:2015-05-06 10:16:442015年亚洲杯之日本
日期:2015-05-06 10:21:342015年亚洲杯纪念徽章
日期:2015-05-13 17:16:442015亚冠之北京国安
日期:2015-05-13 17:18:292015亚冠之鹿岛鹿角
日期:2015-05-13 17:19:062015亚冠之德黑兰石油
日期:2015-05-27 16:47:402015亚冠之塔什干棉农
日期:2015-05-28 15:24:122015亚冠之卡尔希纳萨夫
日期:2015-06-01 13:52:392015亚冠之柏斯波利斯
日期:2015-06-04 17:37:292015亚冠之阿尔纳斯尔
日期:2015-06-16 11:31:202015亚冠之塔什干火车头
日期:2015-06-23 10:12:33
2 [报告]
发表于 2016-06-15 12:25 |只看该作者
笔记很到位,期待更新

论坛徽章:
7
IT运维版块每日发帖之星
日期:2016-05-27 06:20:00IT运维版块每日发帖之星
日期:2016-06-09 06:20:00操作系统版块每日发帖之星
日期:2016-06-12 06:20:00程序设计版块每日发帖之星
日期:2016-06-12 06:20:00操作系统版块每日发帖之星
日期:2016-06-13 06:20:00IT运维版块每日发帖之星
日期:2016-06-17 06:20:002015-2016NBA季后赛纪念章
日期:2016-06-28 17:42:27
3 [报告]
发表于 2016-06-15 19:25 |只看该作者
BH是什么鬼。。。。。。。。。。。。

论坛徽章:
7
IT运维版块每日发帖之星
日期:2016-05-27 06:20:00IT运维版块每日发帖之星
日期:2016-06-09 06:20:00操作系统版块每日发帖之星
日期:2016-06-12 06:20:00程序设计版块每日发帖之星
日期:2016-06-12 06:20:00操作系统版块每日发帖之星
日期:2016-06-13 06:20:00IT运维版块每日发帖之星
日期:2016-06-17 06:20:002015-2016NBA季后赛纪念章
日期:2016-06-28 17:42:27
4 [报告]
发表于 2016-06-15 19:50 |只看该作者
bottom half

论坛徽章:
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
5 [报告]
发表于 2016-06-16 18:21 |只看该作者
papaya=? 一种os?

论坛徽章:
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
6 [报告]
发表于 2016-06-16 18:27 |只看该作者
papaya的设计思路跟linux有什么不一样的地方?能否简单的介绍一下?
缺乏这些背景的话,不太好理解楼主的某些design point。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
7 [报告]
发表于 2016-06-18 19:00 |只看该作者
karma303 发表于 2016-06-15 11:44
读了两天的linux代码,一点点心得跟大家分享,高手轻拍~

【感觉到对BH的需求了】



像发包中断(TOK)的handler可能要调用netif_wake_queue

你调用netif_wake_queue干嘛?

另外硬中断里很多地方是开中断的

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
8 [报告]
发表于 2016-06-18 19:05 |只看该作者
本帖最后由 mordorwww 于 2016-06-18 22:24 编辑
karma303 发表于 2016-06-15 11:44
读了两天的linux代码,一点点心得跟大家分享,高手轻拍~

【感觉到对BH的需求了】


【任务队列的效率似乎不高】
  我开始觉得bh太简单,想实现的是task queue。(我其实想做softirq的,可惜我的内核不支持多核)
  但发现用链表实现bh机制太笨重。我几乎快想好了,就是临界区的时候,把head和tail复制到局部变量,然后遍历。这样BH过程中随便硬中断怎么mark_bh()都行。
  但还是不行,因为mark_bh()(不知道是它是什么函数,就用mark_bh指代吧)的时候,这些tq_struct会从inactive队列,跑到active队列。遍历会失败。
  看linux的源码,它竟然是每执行完一个tq_struct,就直接从队列里删掉。那估计它mark_bh()的时候,也是新生成一个tq_struct插进去。有点儿恐怖,跟BH相比,重的像砖头。
2.6里它已经被work queue取代了,由一个线程负责,可以延时,休眠的。

你这什么鬼,work queue是由内核线程处理的。
难道新的内核里软中断完全都是在内核线程里做的?线程化也有她的不足

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
9 [报告]
发表于 2016-06-18 22:25 |只看该作者
karma303 发表于 2016-06-15 11:44
读了两天的linux代码,一点点心得跟大家分享,高手轻拍~

【感觉到对BH的需求了】


谁触发,谁执行

对于网卡和网络协议栈来讲,早就不是这样的了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP