From 16bfa3d58bc3cb20403c4e6fece87773f410a078 Mon Sep 17 00:00:00 2001 From: xinqiu Date: Sun, 19 Jun 2016 21:07:44 +0800 Subject: [PATCH] change links --- interrupts/interrupts-9.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/interrupts/interrupts-9.md b/interrupts/interrupts-9.md index 2214742..cd6f0c8 100644 --- a/interrupts/interrupts-9.md +++ b/interrupts/interrupts-9.md @@ -4,7 +4,7 @@ 延后中断(软中断,Tasklets 和工作队列)介绍 -------------------------------------------------------------------------------- -这是 Linux 内核[中断和中断处理](https://www.gitbook.com/book/xinqiu/linux-insides-cn/content/interrupts/index.html)的第九节,在[上一节](https://www.gitbook.com/book/xinqiu/linux-nsides-cn/content/interrupts/interrupts-8.html)我们分析了源文件 [arch/x86/kernel/irqinit.c](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/irqinit.c) 中的 `init_IRQ` 实现。接下来的这一节我们将继续深入学习外部硬件中断的初始化。 +这是 Linux 内核[中断和中断处理](https://xinqiu.gitbooks.io/linux-insides-cn/content/interrupts/index.html)的第九节,在[上一节](https://xinqiu.gitbooks.io/linux-insides-cn/content/interrupts/interrupts-8.html)我们分析了源文件 [arch/x86/kernel/irqinit.c](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/irqinit.c) 中的 `init_IRQ` 实现。接下来的这一节我们将继续深入学习外部硬件中断的初始化。 中断处理会有一些特点,其中最主要的两个是: @@ -226,7 +226,7 @@ void __init softirq_init(void) } ``` -可以看到在函数开头定义了一个名为 cpu 的 integer 类型变量。接下来他会作为参数传递给宏 `for_each_possible_cpu` 来获得系统中所有的处理器。如果 `possible_cpu` 对你来说是一个新的术语,你可以阅读 [CPU masks](https://www.gitbook.com/book/xinqiu/linux-insides-cn/content/Concepts/cpumask.html) 章节来了解更多知识。简单的说,`possible_cpu` 是系统运行期间插入的处理器集合。所有的 `possible processor` 存储在 `cpu_possible_bits` 位图中,你可以在 [kernel/cpu.c](https://github.com/torvalds/linux/blob/master/kernel/cpu.c) 中找到他的定义: +可以看到在函数开头定义了一个名为 cpu 的 integer 类型变量。接下来他会作为参数传递给宏 `for_each_possible_cpu` 来获得系统中所有的处理器。如果 `possible_cpu` 对你来说是一个新的术语,你可以阅读 [CPU masks](https://xinqiu.gitbooks.io/linux-insides-cn/content/Concepts/cpumask.html) 章节来了解更多知识。简单的说,`possible_cpu` 是系统运行期间插入的处理器集合。所有的 `possible processor` 存储在 `cpu_possible_bits` 位图中,你可以在 [kernel/cpu.c](https://github.com/torvalds/linux/blob/master/kernel/cpu.c) 中找到他的定义: ```C static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly; @@ -363,7 +363,7 @@ static void tasklet_action(struct softirq_action *a) } ``` -在 `tasklet_action` 开始时利用 `local_irq_disable` 宏禁用了当前处理器的中断(你可以阅读本书[第二部分](https://www.gitbook.com/book/xinqiu/linux-insides-cn/content/interrupts/interrupts-2.html)了解更多关于此宏的信息)。接下来获取到当前处理器对应的普通优先级 tasklet 列表并把它设置为 `NULL` ,这是因为所有的 tasklet 都将被执行。然后使能当前处理器的中断,循环遍历 tasklet 列表,每一次遍历都会对当前 tasklet 调用 `tasklet_trylock` 函数来更新它的状态为 `TASKLET_STATE_RUN`: +在 `tasklet_action` 开始时利用 `local_irq_disable` 宏禁用了当前处理器的中断(你可以阅读本书[第二部分](https://xinqiu.gitbooks.io/linux-insides-cn/content/interrupts/interrupts-2.html)了解更多关于此宏的信息)。接下来获取到当前处理器对应的普通优先级 tasklet 列表并把它设置为 `NULL` ,这是因为所有的 tasklet 都将被执行。然后使能当前处理器的中断,循环遍历 tasklet 列表,每一次遍历都会对当前 tasklet 调用 `tasklet_trylock` 函数来更新它的状态为 `TASKLET_STATE_RUN`: ```C static inline int tasklet_trylock(struct tasklet_struct *t) @@ -477,7 +477,7 @@ bool queue_work_on(int cpu, struct workqueue_struct *wq, } ``` -`__queue_work` 函数得到参数 `work poll`。是的,是 `work poll` 而不是 `workqueue`。实际上,所有的 `works` 都没有放在 `workqueue` 中,而是放在 Linux 内核中由 `worker_pool` 数据结构所定义的 `work poll`。如上所述,`workqueue_struct` 数据结构的 `pwqs` 成员是一个 `worker_pool` 列表。当我们创建一个 `workqueue`,他针对每一个处理器都创建了 `worker_pool`。每一个和 `worker_pool` 相关联的 `pool_workqueue` 都分配在相同的处理器上对应的优先级队列,`workqueue` 通过他们和 `worker_pool` 交互。在 `__queue_work` 函数里使用 `raw_smp_processor_id` 设置 cpu 为当前处理器在[第四章](https://www.gitbook.com/book/xinqiu/linux-insides-cn/content/Initialization/linux-initialization-4.html)你可以找到更多相关信息),得到与所给 `work_struct` 对应的 `pool_workqueue` 并将 `work` 插入到 `workqueue`: +`__queue_work` 函数得到参数 `work poll`。是的,是 `work poll` 而不是 `workqueue`。实际上,所有的 `works` 都没有放在 `workqueue` 中,而是放在 Linux 内核中由 `worker_pool` 数据结构所定义的 `work poll`。如上所述,`workqueue_struct` 数据结构的 `pwqs` 成员是一个 `worker_pool` 列表。当我们创建一个 `workqueue`,他针对每一个处理器都创建了 `worker_pool`。每一个和 `worker_pool` 相关联的 `pool_workqueue` 都分配在相同的处理器上对应的优先级队列,`workqueue` 通过他们和 `worker_pool` 交互。在 `__queue_work` 函数里使用 `raw_smp_processor_id` 设置 cpu 为当前处理器在[第四章](https://xinqiu.gitbooks.io/linux-insides-cn/content/Initialization/linux-initialization-4.html)你可以找到更多相关信息),得到与所给 `work_struct` 对应的 `pool_workqueue` 并将 `work` 插入到 `workqueue`: ```C static void __queue_work(int cpu, struct workqueue_struct *wq, @@ -505,13 +505,13 @@ insert_work(pwq, work, worklist, work_flags); 总结 -------------------------------------------------------------------------------- -现在结束了[中断和中断处理](https://www.gitbook.com/book/xinqiu/linux-insides-cn/content/interrupts/index.html)的第九节。这一节中我们继续讨论了外部硬件中断。在之前部分我们看到了 `IRQs` 的初始化和 `irq_desc` 数据结构,在这一节我们看到了用于延后函数的三个概念:`软中断`,`tasklet` 和`工作队列`。 +现在结束了[中断和中断处理](https://xinqiu.gitbooks.io/linux-insides-cn/content/interrupts/index.html)的第九节。这一节中我们继续讨论了外部硬件中断。在之前部分我们看到了 `IRQs` 的初始化和 `irq_desc` 数据结构,在这一节我们看到了用于延后函数的三个概念:`软中断`,`tasklet` 和`工作队列`。 下一节将是 `中断和中断处理` 的最后一节。我们将会了解真正的硬件驱动,并试着学习它是怎样和中断子系统一起工作的。 如果你有任何问题或建议,请给我发评论或者给我发 [Twitter](https://twitter.com/0xAX)。 -**请注意英语并不是我的母语,我为任何表达不清楚的地方感到抱歉。如果你发现任何错误请发 PR 到 [linux-insides](https://github.com/0xAX/linux-insides)。(译者注:翻译问题请发 PR 到 [linux-insides-cn](https://www.gitbook.com/book/xinqiu/linux-insides-cn))** +**请注意英语并不是我的母语,我为任何表达不清楚的地方感到抱歉。如果你发现任何错误请发 PR 到 [linux-insides](https://github.com/MintCN/linux-insides-zh)。(译者注:翻译问题请发 PR 到 [linux-insides-cn](https://www.gitbook.com/book/xinqiu/linux-insides-cn))** 链接 @@ -520,7 +520,7 @@ insert_work(pwq, work, worklist, work_flags); * [initcall](http://www.compsoc.man.ac.uk/~moz/kernelnewbies/documents/initcall/index.html) * [IF](https://en.wikipedia.org/wiki/Interrupt_flag) * [eflags](https://en.wikipedia.org/wiki/FLAGS_register) -* [CPU masks](http://0xax.gitbooks.io/linux-insides/content/Concepts/cpumask.html) -* [per-cpu](http://0xax.gitbooks.io/linux-insides/content/Concepts/per-cpu.html) +* [CPU masks](http://xinqiu.gitbooks.io/linux-insides-cn/content/Concepts/cpumask.html) +* [per-cpu](http://xinqiu.gitbooks.io/linux-insides-cn/content/Concepts/per-cpu.html) * [Workqueue](https://github.com/torvalds/linux/blob/master/Documentation/workqueue.txt) -* [Previous part](http://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-8.html) +* [Previous part](http://xinqiu.gitbooks.io/linux-insides-cn/content/interrupts/interrupts-8.html)