免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: guotie
打印 上一主题 下一主题

内核netfilter处理问题(暨packet接受与NAPI介绍) [复制链接]

论坛徽章:
0
11 [报告]
发表于 2006-01-11 10:41 |只看该作者
软中断  和 ksoftirqd 内核线程  是不可以相互抢占的吧?

论坛徽章:
0
12 [报告]
发表于 2006-01-11 14:11 |只看该作者
ksoftirqd就算运行在process context了, 只有普通内核线程的优先级, 不如中断上下文的softirq。
我觉得很有可能某个softirq(say A)被重复触发,于是ksoftirqd开始运行, 正好被某个设备中断,中断返回时执行该ISR中raise了的softirq,执行完毕才回到ksofirqd(还有可能不回去,而是被抢占)。

BTW guotie兄,这个帖子有wheelz和xiaozhaoz二位的精彩论述,针对NAPI和报文接受, 我改下题目加个精华好么

论坛徽章:
0
13 [报告]
发表于 2006-01-11 15:59 |只看该作者
同意。

感谢斑竹的辛苦劳动!

向您致敬!

论坛徽章:
0
14 [报告]
发表于 2006-01-11 16:11 |只看该作者
To xiaozhaoz,

我觉得ip_rcv 仅仅是被软中断函数(do_softirq )间接调用,不被其它调用。
是net_rx_action 被do_softirq() 调用,net_rx_action再调用ip_rcv.
可以找出net_rx_action不被do_softirq调用的case吗?

而软中断do_softirq()的调用分为2种情况。
1)被硬中断调用(无context, 无自己stack, 一个函数而已)
2)被kernel thread softirqd调用,有自己stack. 独立的context.

大部分情况下1)为真(上次你追问我过次问题,不是仅仅一种情况)。软中断忙不过来时才会有2)

do_softirq()在处理过程中可以有新中断发生,但do_softirq不会被重入。

我还在看,结论比较齐备后会专门写个帖子或放到blog.

欢迎讨论。


原帖由 xiaozhaoz 于 2006-1-9 12:13 发表
同意你的说法。

to guotie:
ip_rcv,netfilter 不一定都是在软中断中进行:
我上面的描述中已经说了:
当软中断持续被触发时,为了保持系统实时行,会将后续的报文处理放到softirqd任务中进行,这时一个内核 ...

论坛徽章:
0
15 [报告]
发表于 2006-01-11 16:32 |只看该作者
而软中断do_softirq()的调用分为2种情况。
1)被硬中断调用(无context, 无自己stack, 一个函数而已)
2)被kernel thread softirqd调用,有自己stack. 独立的context.


我觉得,第一个说法“被硬中断调用”似乎不妥,软中断的原理决定了它不应该是被调用的,本质上只是在CPU的soft_vec结构上置位,由cpu检查到时执行。

论坛徽章:
0
16 [报告]
发表于 2006-01-11 16:40 |只看该作者
1)当有包进入网卡,引起中断,其调用TREE如下:

stack c03cc000 trace: tcp_v4_rcv | ip_local_deliver_finish | nf_hook_slow | ip_local_deliver | ip_rcv | netif_receive_skb | process_backlog | net_rx_action | do_softirq | do_IRQ | common_interrupt | cpu_idle

看我上一个帖子

论坛徽章:
0
17 [报告]
发表于 2006-01-11 16:43 |只看该作者
这个我知道。
net_rx_action | do_softirq | do_IRQ |
有没有可能是这样的呢:
net_rx_action | do some timer or tasklet | do_softirq | do_IRQ |

论坛徽章:
0
18 [报告]
发表于 2006-01-11 16:47 |只看该作者
这个调用关系不是自己想象的,而是实际trace的结果。
你看do_softirq代码,会有你说的情况吗。

论坛徽章:
0
19 [报告]
发表于 2006-01-11 16:56 |只看该作者
函数源码如下(kernel/softirq.c):
asmlinkage void do_softirq()
{
int cpu = smp_processor_id();
__u32 active, mask;

if (in_interrupt())
return;

local_bh_disable();

local_irq_disable();
mask = softirq_mask(cpu);
active = softirq_active(cpu) & mask;

if (active) {
struct softirq_action *h;

restart:
/* Reset active bitmask before enabling irqs */
softirq_active(cpu) &= ~active;

local_irq_enable();

h = softirq_vec;
mask &= ~active;

do {
if (active & 1)
h->action(h);
h++;
active >>= 1;
} while (active);

local_irq_disable();

active = softirq_active(cpu);
if ((active &= mask) != 0)
goto retry;
}

local_bh_enable();

/* Leave with locally disabled hard irqs. It is critical to close
* window for infinite recursion, while we help local bh count,
* it protected us. Now we are defenceless.
*/
return;

retry:
goto restart;
}
结合上述源码,我们可以看出软中断服务的执行过程如下:
(1)调用宏in_interrupt()来检测当前CPU此次是否已经处于中断服务中。该宏定义在hardirq.h,请参见5.7节。
(2)调用local_bh_disable()宏将当前CPU的中断统计信息结构中的__local_bh_count成员变量加1,表示当前CPU已经处在软中断服务状态。
(3)由于接下来要读写当前CPU的中断统计信息结构中的__softirq_active变量和__softirq_mask变量,因此为了保证这一个操作过程的原子性,先用local_irq_disable()宏(实际上就是cli指令)关闭当前CPU的中断。
(4)然后,读当前CPU的__softirq_active变量值和__softirq_mask变量值。当某个软中断向量被触发时(即 __softirq_active变量中的相应位被置1),只有__softirq_mask变量中的相应位也为1时,它的软中断服务函数才能得到执行。因此,需要将__softirq_active变量和__softirq_mask变量作一次“与”逻辑操作。
(5)如果active变量非 0,说明需要执行软中断服务函数。因此:①先将当前CPU的__softirq_active中的相应位清零,然后用local_irq_enable ()宏(实际上就是sti指令)打开当前CPU的中断。②将局部变量mask中的相应位清零,其目的是:让do_softirq()函数的这一次执行不对同一个软中断向量上的再次软中断请求进行服务,而是将它留待下一次do_softirq()执行时去服务,从而使do_sottirq()函数避免陷入无休止的软中断服务中。③用一个do{}while循环来根据active的值去执行相应的软中断服务函数。④由于接下来又要检测当前CPU的 __softirq_active变量,因此再一次调用local_irq_disable()宏关闭当前CPU的中断。⑤读取当前CPU的 __softirq_active变量的值,并将它与局部变量mask进行与操作,以看看是否又有其他软中断服务被触发了(比如前面所说的那种情形)。如果有的话,那就跳转到entry程序段(实际上是跳转到restart程序段)重新执行软中断服务。如果没有的话,那么此次软中断服务过程就宣告结束。
(6)最后,通过local_bh_enable()宏将当前CPU的__local_bh_count变量值减1,表示当前CPU已经离开软中断服务状态。宏local_bh_enable()也定义在include/asm-i386/softirq.h头文件中。

论坛徽章:
0
20 [报告]
发表于 2006-01-11 16:59 |只看该作者
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP