免费注册 查看新帖 |

Chinaunix

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

[内核模块] 碰到一个死锁的情况,大侠们帮看看我的分析思路对吗?怎么越分析越糊涂 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2013-11-01 16:09 |只看该作者
回复 10# humjb_1983

看了一些资料,觉得在netif_receive_skb前禁止所有中断确实不太合适。但是,不直接调用netif_receive_skb还有什么办法?调用netif_rx可以吗?希望能多多指点

   

论坛徽章:
0
12 [报告]
发表于 2013-11-02 15:08 |只看该作者
[ 3182.659796]  [<c14f00d8>] ? tcp_connect+0x318/0x490
[ 3182.661011]  [<c14e6841>] ? tcp_validate_incoming+0x71/0x340
[ 3182.662421]  [<c14f8010>] ? tcp_check_req+0x260/0x4b0
[ 3182.663676]  [<c14ecaf7>] ? tcp_rcv_state_process+0x47/0xb80
[ 3182.665078]  [<c14f8093>] ? tcp_check_req+0x2e3/0x4b0
[ 3182.666338]  [<c14f7ced>] ? tcp_child_process+0x8d/0x150
[ 3182.667660]  [<c14f5d8a>] ? tcp_v4_do_rcv+0x2aa/0x3c0
[ 3182.668922]  [<c12c149b>] ? do_raw_spin_lock+0x3b/0xf0
[ 3182.670202]  [<c159eefd>] ? _raw_spin_lock_nested+0x3d/0x50
[ 3182.671603]  [<c14f6f4a>] ? tcp_v4_rcv+0x78a/0xaa0
[ 3182.672800]  [<c14d4b8f>] ? ip_local_deliver_finish+0xdf/0x380
[ 3182.674263]  [<c14d4aec>] ? ip_local_deliver_finish+0x3c/0x380
[ 3182.675713]  [<c14d4fbf>] ? ip_local_deliver+0x7f/0x90
[ 3182.676991]  [<c14d46be>] ? ip_rcv_finish+0x16e/0x560
[ 3182.678259]  [<c14d522a>] ? ip_rcv+0x25a/0x320
[ 3182.679371]  [<c14d4550>] ? inet_del_protocol+0x30/0x30
[ 3182.680670]  [<c14a63d2>] ? __netif_receive_skb+0x4c2/0x570
[ 3182.682057]  [<c14a5fec>] ? __netif_receive_skb+0xdc/0x570
[ 3182.683436]  [<c14a707b>] ? netif_receive_skb+0xcb/0xe0
[ 3182.684730]  [<c14a6fcf>] ? netif_receive_skb+0x1f/0xe0
[ 3182.686027]  [<f848e33e>] ? SendSkb2Middle+0x162/0x176 [kksfilter]
[ 3182.687568]  [<f848f867>] ? KksNatHandler+0x6cd/0x86d [kksfilter]

[ 3182.689094]  [<c1095000>] ? futex_wait_requeue_pi+0x1c0/0x380
[ 3182.690526]  [<f848fa67>] ? kks_tx+0x60/0x81 [kksfilter]
[ 3182.691859]  [<f848fa07>] ? KksNatHandler+0x86d/0x86d [kksfilter]
[ 3182.693386]  [<c1079df8>] ? kthread+0x78/0x80
[ 3182.694488]  [<c1079d80>] ? __init_kthread_worker+0x60/0x60
[ 3182.695876]  [<c15a6d82>] ? kernel_thread_helper+0x6/0x10

这个调用栈是异常的,netif_receive_skb是运行在软中断上下文了,而你这里在kks_tx线程上下文去调用了,在tcp_v4_rcv的时候会去lock_sock获取spinlock,而该线程被硬
中断中断后,会执行软中中断,在软中断上下文最后正常执行到tcp_v4_rcv时去lock_sock获取spinlock获取不到,出现AA锁了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
13 [报告]
发表于 2013-11-02 16:01 |只看该作者
回复 12# jinsdb


netif_receive_skb是运行在软中断上下文了
这句话对么? ksoftirqd不是也会处理软中断么? ksoftirqd应该是内核线程吧? 求解

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
14 [报告]
发表于 2013-11-04 10:34 |只看该作者
FlankerSky 发表于 2013-11-01 16:09
回复 10# humjb_1983

看了一些资料,觉得在netif_receive_skb前禁止所有中断确实不太合适。但是,不直接 ...

直接调netif_rx应该也是不合适的,效果不比netif_receive_skb好,不确认你具体要实现怎样的功能~~,如果一定要直接调用netif_receive_skb,可以尝试模仿do_softirq中的处理,在调用前先调用local_bh_disable(),增加软中断计数,防止软中断重入,这样比直接关中断副作用稍小,但关闭时间也不能太长,需要保证~

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
15 [报告]
发表于 2013-11-04 10:37 |只看该作者
kmindg 发表于 2013-11-02 16:01
回复 12# jinsdb

确实不对~~,netif_receive_skb的确可以运行于ksoftirq内核线程中。
对于目前讨论的问题,ksoftirq也是调用do_softirq入口,netif_receive_skb不可重入同样是由do_softirq保证的~~

论坛徽章:
0
16 [报告]
发表于 2013-11-04 15:06 |只看该作者
回复 14# humjb_1983

目前用的netif_rx还可以,暂时没发现问题,当然还需长时间测试。然后,我再着手实现下你说的那种方法,多谢兄台指点了,帮了我很大忙!感激不尽!

   

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
17 [报告]
发表于 2013-11-04 16:46 |只看该作者
回复 16# FlankerSky
呵呵,不用客气的,多交流学习~~

   

论坛徽章:
1
丑牛
日期:2013-10-23 14:49:51
18 [报告]
发表于 2013-11-07 11:03 |只看该作者
在系统原有的do_softirq中,netif_receive_skb 不可重入,不管是在ksoftirqd中运行还是中断里,都不可重入,所以如果你的netif_receive_skb前关闭了中断,应该不是AA死锁
回复 6# humjb_1983


   

论坛徽章:
0
19 [报告]
发表于 2013-11-07 23:09 |只看该作者
to kmindg & humjb_1983

看来大家比较纠结"netif_receive_skb是运行在软中断上下文" 这句话,仔细看一下netif_receive_skb的代码注释吧,linux内核多个内核版本都是清晰了标注了
“This function may only be called from softirq context ”

/**
2270 *      netif_receive_skb - process receive buffer from network
2271 *      @skb: buffer to process
2272 *
2273 *      netif_receive_skb() is the main receive data processing function.
2274 *      It always succeeds. The buffer may be dropped during processing
2275 *      for congestion control or by the protocol layers.
2276 *
2277 *      This function may only be called from softirq context and interrupts
2278 *      should be enabled.
2279 *
2280 *      Return values (usually ignored):
2281 *      NET_RX_SUCCESS: no congestion
2282 *      NET_RX_DROP: packet was dropped
2283 */
2284int netif_receive_skb(struct sk_buff *skb)
2285{
2286        struct packet_type *ptype, *pt_prev;
2287        struct net_device *orig_dev;
2288        struct net_device *null_or_orig;
2289        int ret = NET_RX_DROP;
2290        __be16 type;
2291
2292        if (!skb->tstamp.tv64)
2293                net_timestamp(skb);
2294
2295        if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
2296                return NET_RX_SUCCESS;
2297
2298        /* if we've gotten here through NAPI, check netpoll */
2299        if (netpoll_receive_skb(skb))
2300                return NET_RX_DROP;


netif_receive_skb是在网卡驱动接收到数据包,将skb投递协议栈处理的时候调用的,所以netif_receive_skb是是在网卡软中断上下文调用的,包括后续
的投递的协议栈(如果是TCP包)的ip_rcv,tcp_v4_rcv,tcp_v4_do_rcv,协议栈的处理过程都是在软中断上下文完成,第一眼看到这个调用堆栈居然有人这么调用,
感到蛮诧异的,更没有想到还有的人会认为netif_receive_skb不应该运行在软中断上下文。

ksoftirqd是软中断的辅助处理线程,理论上所有的软中断,都有机会(可能)被ksoftirqd调用执行,是否这样就否认软中断上下文的存在?如果有人不相信netif_receive_skb
是在软中断上下文调用的,在netif_receive_skb函数中加个sleep编个内核试试看。内核提供宏in_softirq()  可以方便确认当前函数运行在哪一种上下文,为什么函数要明确调用上下文,这和资源的互斥访问相关,资源的互斥访问就得用锁,分不清调用上下文的,也必然不会用锁。

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
20 [报告]
发表于 2013-11-08 11:01 |只看该作者
jinsdb 发表于 2013-11-07 23:09
to kmindg & humjb_1983

看来大家比较纠结"netif_receive_skb是运行在软中断上下文" 这句话,仔细看一下 ...

呵呵,误会了吧,我没有否认netif_receive_skb运行在软中断上下文,之前的一处纠结在于:ksoftirq最终也可能调用netif_receive_skb,所以该函数不能完全说“只能运行在软中断上下文”。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP