Chinaunix

标题: 关于work queue与softirq的一个问题 [打印本页]

作者: drizztzou    时间: 2006-03-13 16:58
标题: 关于work queue与softirq的一个问题
我正在看LKD2,里面有这么一句:works queues are the only bottom-half mechanisms that run in process context,但是如果softirq在ksoftirqd中运行的话,不是也是在进程上下文中吗?

请高手指点一下
作者: 思一克    时间: 2006-03-13 17:10
softirq如果被softirqd调用,那就不在process context, 而是在softirqd的状态中. 如果被硬件中断直接调用, 那就是是在中断所在的状态
作者: drizztzou    时间: 2006-03-13 17:16
那也就是说interrupt context还分为两种上下文状态:软中断和硬中断

我理解的对吗?
作者: 帅绝人寰    时间: 2006-03-13 17:53
标题: 回复 3楼 drizztzou 的帖子
不对, 再看看代码吧。

我们不可以假定说某个softirq会在softirqd中执行, 而一定要保证: 我写的softirq handler在中断上下文执行不会出错。
作者: richardhesidu    时间: 2006-03-13 17:56
原帖由 drizztzou 于 2006-3-13 16:58 发表
我正在看LKD2,里面有这么一句:works queues are the only bottom-half mechanisms that run in process context,但是如果softirq在ksoftirqd中运行的话,不是也是在进程上下文中吗?

请高手指点一下


ksoftirqd是内核线程,不属于进程上下文的范畴。
作者: richardhesidu    时间: 2006-03-13 18:01
原帖由 drizztzou 于 2006-3-13 17:16 发表
那也就是说interrupt context还分为两种上下文状态:软中断和硬中断

我理解的对吗?


中断上下文分为上半部和下半部,下半部包括软中断,tasklet,work queue

[ 本帖最后由 richardhesidu 于 2006-3-13 20:03 编辑 ]
作者: 通用寄存器    时间: 2006-03-13 18:23
softirq和tasklet应该是在中断上下文中吧,不能睡眠,work queue是跑在内核线程里的,可以睡眠,那么ksoftirqd调用的do_softirq应该是什么状态呢?

[ 本帖最后由 通用寄存器 于 2006-3-13 18:43 编辑 ]
作者: 通用寄存器    时间: 2006-03-14 09:52
原帖由 richardhesidu 于 2006-3-13 17:56 发表


ksoftirqd是内核线程,不属于进程上下文的范畴。


内核线程不属于进程上下文范畴?那属于什么范畴?
作者: albcamus    时间: 2006-03-14 10:01
ksoftirqd也算是process context, 可以睡眠。 可是除非softirq重复触发, 否则在interrupt conetxt中就处理完了, 不用唤起ksoftirqd来处理。

所以尽管softirq有可能在process context执行, 我们还是要保证它在interrupt context中不会出错。
作者: 通用寄存器    时间: 2006-03-14 10:07
原帖由 albcamus 于 2006-3-14 10:01 发表
ksoftirqd也算是process context, 可以睡眠。 可是除非softirq重复触发, 否则在interrupt conetxt中就处理完了, 不用唤起ksoftirqd来处理。

所以尽管softirq有可能在process context执行, 我们还是要保证 ...


呵呵,懂了~
作者: drizztzou    时间: 2006-03-14 10:10
原帖由 albcamus 于 2006-3-14 10:01 发表
ksoftirqd也算是process context, 可以睡眠。 可是除非softirq重复触发, 否则在interrupt conetxt中就处理完了, 不用唤起ksoftirqd来处理。

所以尽管softirq有可能在process context执行, 我们还是要保证 ...


谢谢!懂了~~

呵呵,还是你说的清晰啊
作者: xiaozhaoz    时间: 2006-03-14 10:32
原帖由 albcamus 于 2006-3-14 10:01 发表
ksoftirqd也算是process context, 可以睡眠。 可是除非softirq重复触发, 否则在interrupt conetxt中就处理完了, 不用唤起ksoftirqd来处理。

所以尽管softirq有可能在process context执行, 我们还是要保证 ...


在一些CPU中, softirq和 interrrupt 用的不是一个context. 更确切的说,当内核配置使用4K kernel stack的时候, softirq和interrupt不能使用同一个context.  这里的context指的是 thread_info和stack.   task_struct用的都是被抢占的那个.

ksoftirqd执行的软中断处理函数也是softirq执行的那些函数, 所以ksoftirqd执行这些函数的时候,会在当前CPU屏蔽软中断的执行,在这期间不要让ksoftirqd sleep!

[ 本帖最后由 xiaozhaoz 于 2006-3-14 10:36 编辑 ]
作者: albcamus    时间: 2006-03-14 10:41
原帖由 xiaozhaoz 于 2006-3-14 10:32 发表


在一些CPU中, softirq和 interrrupt 用的不是一个context. 更确切的说,当内核配置使用4K kernel stack的时候, softirq和interrupt不能使用同一个context.  这里的context指的是 thread_info和stack.   task_s ...

>当内核配置使用4K kernel stack的时候, softirq和interrupt不能使用同一个context
这个我看过,呵呵。 当打开这个选项, irq和softirq都有了自己的独立的栈。
>所以ksoftirqd执行这些函数的时候,会在当前CPU屏蔽软中断的执行,在这期间不要让ksoftirqd sleep!
这个我有点不理解: 引入softirqd就是让它可睡眠的啊, 不然的话, 线程化还有什么意义呢?
请教~
作者: drizztzou    时间: 2006-03-14 10:50
原帖由 xiaozhaoz 于 2006-3-14 10:32 发表


在一些CPU中, softirq和 interrrupt 用的不是一个context. 更确切的说,当内核配置使用4K kernel stack的时候, softirq和interrupt不能使用同一个context.  这里的context指的是 thread_info和stack.   task_s ...


使用4k stack的时候,是不是说interrupt handler被分配了一个属于自己的4k stack,而softirq使用抢占的进程的stack?
作者: albcamus    时间: 2006-03-14 11:01
原帖由 drizztzou 于 2006-3-14 10:50 发表


使用4k stack的时候,是不是说interrupt handler被分配了一个属于自己的4k stack,而softirq使用抢占的进程的stack?


不是。 4k栈的意思是, 每个进程的栈是4k, 当发生硬件中断, 则给它分配栈; 发生softirq也是给它分配独立的栈。 只有一种情形除外: 中断是嵌套发生的,亦即当前已经在中断中了。
作者: xiaozhaoz    时间: 2006-03-14 11:14
原帖由 albcamus 于 2006-3-14 10:41 发表

>当内核配置使用4K kernel stack的时候, softirq和interrupt不能使用同一个context
这个我看过,呵呵。 当打开这个选项, irq和softirq都有了自己的独立的栈。
>所以ksoftirqd执行这些函数的时候,会在当 ...


我觉得, 引入Ksoftirqd不是让softirq可以sleep, 而是让softirq不要占用太多CPU, 用ksoftirqd后, 处理softirq内容的部分工作由ksoftirqd完成,ksoftirqd是一个prority = 120的普通任务, 在某些点可以被用户空间 或其他内核线程抢占,同样是running状态. 更确切的说, 来回处理十次, 可以被抢占一次. 代码如下:
ksoftirqd()
                while (local_softirq_pending()) {
                        /* Preempt disable stops cpu going offline.
                           If already offline, we'll be on wrong CPU:
                           don't process */
                        if (cpu_is_offline((long)__bind_cpu))
                                goto wait_to_die;
                        do_softirq();
                        //打开可抢占
                        preempt_enable_no_resched();
                       //检查是否要被调度出去,通过检查 TIF_NEED_RESCHED 标志, 这个标志被时钟中断中的调度部分scheduler_tick()设置
                        cond_resched();
                        preempt_disable();
                }

这样不会出现如网口流量很大,上层shell没有响应的问题.


在 stack = 4K的时候, softirq和hardirq都有自己的thread_info和stack, 这样可以防止堆栈溢出.
作者: albcamus    时间: 2006-03-14 11:22
>>用ksoftirqd后, 处理softirq内容的部分工作由ksoftirqd完成,ksoftirqd是一个prority = 120的普通任务, 在某些点可以被用户空间 或其他内核线程抢占,同样是running状态.

我明白了, 多谢!!
作者: xiaozhaoz    时间: 2006-03-14 11:31
sorry, 弄错了, ksoftirqd的 priority = 139, 是优先级最低的任务.
作者: drizztzou    时间: 2006-03-14 12:00
原帖由 xiaozhaoz 于 2006-3-14 11:14 发表


我觉得, 引入Ksoftirqd不是让softirq可以sleep, 而是让softirq不要占用太多CPU, 用ksoftirqd后, 处理softirq内容的部分工作由ksoftirqd完成,ksoftirqd是一个prority = 120的普通任务, 在某些点可以被用户空间 ...


是不是这个意思:softirq本来是不可以被用户空间或其他内核线程抢占,但是放在ksoftirqd里执行就可以被用户空间或其他内核线程抢占了
作者: albcamus    时间: 2006-03-14 12:18
标题: 回复 19楼 drizztzou 的帖子
对, 就是这个意思。
作者: 思一克    时间: 2006-03-14 14:25
softirq函数本身还是不能被抢占的,但可以被中断。可以抢占的是softirqd进程。后者调用前者,前者在执行过程中preempt_disable()了。
作者: richardhesidu    时间: 2006-03-14 18:58
原帖由 albcamus 于 2006-3-14 10:01 发表
ksoftirqd也算是process context, 可以睡眠。 可是除非softirq重复触发, 否则在interrupt conetxt中就处理完了, 不用唤起ksoftirqd来处理。

所以尽管softirq有可能在process context执行, 我们还是要保证 ...


我觉得这是一个概念的问题吧。我的理解是这样的:上下文是相对于进程和内核线程的概念。严格地说,某个进程或是内核线程都不是属于context的。context特指进程和内核线程以外的内核代码。比如system call的那部分进程上下文不属于特定进程,而interrupt top half, 向内核注册的softirq,tasklet,work queue代码也不属于特定的内核线程。context更像是这些进程和内核线程运行的环境。所以很难说某个进程或是内核线程“属于”,“在”或是“是”上下文。

就像书上说的,软中断是不可以休眠的,但是ksoftirqd确是可以休眠的。前面指的是软中断的上下文,后者指的是ksoftirqd内核线程。

我有点钻牛角尖了,不知道理解得对不对。

[ 本帖最后由 richardhesidu 于 2006-3-15 00:03 编辑 ]
作者: drizztzou    时间: 2006-03-15 09:04
原帖由 richardhesidu 于 2006-3-14 18:58 发表


我觉得这是一个概念的问题吧。我的理解是这样的:上下文是相对于进程和内核线程的概念。严格地说,某个进程或是内核线程都不是属于context的。context特指进程和内核线程以外的内核代码。比如system call的那 ...


和我的理解很不一样,上下文应该是进程或者内核线程的一个运行环境,包括hardware context、thread info、stack等,所谓进程在某种context中运行,应该是对这个进程运行环境的一种描述
作者: richardhesidu    时间: 2006-03-15 10:30
原帖由 drizztzou 于 2006-3-15 09:04 发表


和我的理解很不一样,上下文应该是进程或者内核线程的一个运行环境,包括hardware context、thread info、stack等,所谓进程在某种context中运行,应该是对这个进程运行环境的一种描述


感觉你的理解跟我的理解没有什么不同啊。
作者: 通用寄存器    时间: 2006-03-15 11:19
Bach在《UNIX操作系统设计》里讲,进程上下文是由其用户地址空间的内容、硬件寄存器的内容以及与该进程有关的内核数据结构组成。他把进程上下文分为用户级上下文、寄存器上下文以及系统级上下文三部分




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2