免费注册 查看新帖 |

Chinaunix

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

skb_queue_tail()出现panic,内核锁的疑惑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-07-13 13:15 |只看该作者 |倒序浏览
本帖最后由 leonwang202 于 2011-07-13 19:49 编辑

小弟最近写了个测试程序
1.通过dev_add_pack() 加入了自己的钩子函数,
2.软中断里调用钩子函数,把从eth1网卡上来的skb放入到一个接收队列中,
3.当用户调read的时候,从队列上取出skb,将skb->data传给用户空间。

模块程序跑在 linux-2.6.18 smp 上,总是panic 死在skb_queue_tail() 这个函数上。。。
各位大牛看一下,哪里出的问题,下面是主要代码
  1. #define IF_NAME "eth1"
  2. struct net_device *netdev;     //eth1所对应的网卡
  3. int hack_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
  4. {
  5.     if(netdev != dev){      //只接受eth1网卡上的skb
  6.         kfree_skb(skb);
  7.         return 0;
  8.     }
  9.     nskb = skb_clone(skb, GFP_ATOMIC);
  10.     kfree_skb(skb);
  11.     skb_queue_tail(&rcv_queue, nskb);               //将skb加入到接收队列
  12.     if( waitqueue_active(&rcv_waitqueue) )         //唤醒阻塞的进程
  13.         wake_up_interruptible(&rcv_waitqueue);
  14.     return 0;
  15. }

  16. static struct packet_type net_hack_type =
  17. {
  18.     .type = __constant_htons(ETH_P_IP),            //只把IP包传给用户空间
  19.     .func = hack_recv,                                           //钩子函数
  20. };

  21. int my_open(struct inode *inode, struct file *filp)   //字符设备对应的open操作
  22. {
  23.     netdev = dev_get_by_name(IF_NAME);          //找到eth1对应的netdev
  24.     skb_queue_head_init(&rcv_queue);                //初始化接收队列
  25.     dev_add_pack(&net_hack_type);                   //添加自己的钩子函数
  26.         return 0;
  27. }

  28. int my_release(struct inode  * inode, struct file * filp)  //字符设备对应的release操作
  29. {
  30.     dev_remove_pack(&net_hack_type);
  31.     skb_queue_purge(&rcv_queue);
  32.     return 0;
  33. }

  34. ssize_t my_read(struct file *filp, char __user *buf, size_t len, loff_t *f_pos)//字符设备对应的read操作
  35. {
  36.     ssize_t copied = 0;
  37.     ssize_t to_copy = 0;
  38.     struct sk_buff *skb = NULL;
  39.     char *tmp = buf;
  40.     do{
  41.         wait_event_interruptible(rcv_waitqueue,!skb_queue_empty(&rcv_queue)); //接收队列没包的话,阻塞在这里
  42.         skb = skb_dequeue(&rcv_queue);     //取包
  43.         if(!skb)
  44.             goto out;
  45.         to_copy = skb->len;
  46.         if( to_copy > (len - copied)) {              //用户空间buf不足
  47.             skb_queue_head(&rcv_queue, skb);
  48.             goto out;
  49.         }
  50.         copy_to_user(tmp, skb->data, skb->len);
  51.         kfree_skb(skb);
  52.         copied += to_copy;
  53.         tmp = buf + copied;
  54.     } while(copied < len);
  55. out:
  56.     return copied;
  57. }
复制代码
模块程序运行后,总是随机panic在 skb_queue_tail()
BUG: unable to handle kernel NULL pointer dereference at virtual address 00000000
EIP is at skb_queue_tail+0x17/0x2d

初步怀疑是同步没做好,
接收队列rcv_queue 只在软中断和用户进程上下文中共享
我看了下skb_queue_tail() 和skb_dequeue()的实现,操作接收队列时,用spin_lock_irqsave()和spin_unlock_irqrestore()保护了啊,为什么还会出现上面的panic 呢?

论坛徽章:
0
2 [报告]
发表于 2011-07-13 20:13 |只看该作者
回复 1# leonwang202


    完整的panic信息如下:
  1. BUG: unable to handle kernel NULL pointer dereference at virtual address 00000000
  2. printing eip:
  3. c05b57db
  4. *pde = 1b3db001
  5. Oops: 0002 [#1]
  6. SMP
  7. last sysfs file: /devices/pci0000:00/0000:00:1c.2/0000:04:00.1/irq
  8. Modules linked in: net(U) autofs4 hidp rfcomm l2cap bluetooth lockd sunrpc dm_mu                                                                                        ltipath scsi_dh video hwmon backlight sbs i2c_ec i2c_core button battery asus_ac                                                                                        pi ac ipv6 xfrm_nalgo crypto_api parport_pc lp parport joydev sr_mod cdrom sg hp                                                                                        ilo pcspkr serio_raw bnx2 dm_raid45 dm_message dm_region_hash dm_mem_cache dm_sn                                                                                        apshot dm_zero dm_mirror dm_log dm_mod ata_piix libata cciss sd_mod scsi_mod ext                                                                                        3 jbd uhci_hcd ohci_hcd ehci_hcd
  9. CPU:    3
  10. EIP:    0060:[<c05b57db>]    Tainted: G      VLI
  11. EFLAGS: 00010006   (2.6.18-164.el5PAE #1)
  12. EIP is at [color=Red]skb_queue_tail+0x17/0x2d[/color]
  13. eax: 00000246   ebx: f8a7ba70   ecx: 00000007   edx: c08850c0
  14. esi: 00000000   edi: f8a7ba7c   ebp: f3926000   esp: c0740eb0
  15. ds: 007b   es: 007b   ss: 0068
  16. Process net_main (pid: 8001, ti=c0740000 task=f1174000 task.ti=daa39000)
  17. Stack: 00000000 f0dd0e00 00000008 f8a79337 c06b4b60 f8a7a760 c05ba65f f3926000
  18.        c07e1720 00000000 f0dd0e00 00000000 00000000 f3926400 f0dd0e00 f8986b56
  19.        c0740f8c 00000000 f392656c f3926400 f2a3c550 c041df20 006b26ab 0000a307
  20. Call Trace:
  21. [<f8a79337>] hack_recv+0xc1/0xe9 [net]
  22. [<c05ba65f>] netif_receive_skb+0x323/0x370
  23. [<f8986b56>] bnx2_poll_work+0xc22/0xd2c [bnx2]
  24. [<c041df20>] enqueue_task+0x29/0x39
  25. [<c0405946>] common_interrupt+0x1a/0x20
  26. [<c041df20>] enqueue_task+0x29/0x39
  27. [<c041df7a>] __activate_task+0x4a/0x59
  28. [<c041e83d>] try_to_wake_up+0x3e8/0x3f2
  29. [<c04074ba>] do_IRQ+0xb5/0xc3
  30. [<f898a08a>] bnx2_poll_msix+0x29/0xbf [bnx2]
  31. [<c05bc4c4>] net_rx_action+0x9c/0x1a7
  32. [<c04292fb>] __do_softirq+0x87/0x114
  33. [<c04073bb>] do_softirq+0x52/0x9c
  34. [<c044b5b0>] __do_IRQ+0x0/0xd6
  35. [<c04074ba>] do_IRQ+0xb5/0xc3
  36. [<c0405946>] common_interrupt+0x1a/0x20
  37. [<c0617378>] _spin_unlock_irqrestore+0x8/0x9
  38. [<c05b589f>] skb_dequeue+0x39/0x3f
  39. [<f8a79409>] get_one_skb+0x15/0x31 [net]
  40. [<f8a7943c>] net_hack_read+0x17/0x103 [net]
  41. [<c044840a>] audit_syscall_entry+0x15a/0x18c
  42. [<f8a79425>] net_hack_read+0x0/0x103 [net]
  43. [<c047331c>] vfs_read+0x9f/0x141
  44. [<c047376a>] sys_read+0x3c/0x63
  45. [<c0404f17>] syscall_call+0x7/0xb
  46. =======================
  47. Code: 00 00 00 89 51 04 89 0a 89 c2 89 f8 5b 5e 5f e9 ac 1b 06 00 57 56 89 d6 8d                                                                                         78 0c 53 89 c3 89 f8 e8 3b 1b 06 00 8b 53 04 ff 43 08 <89> 1e 89 56 04 89 32 89                                                                                         73 04 89 c2 89 f8 5b 5e 5f e9 7f 1b 06
  48. EIP: [<c05b57db>] [color=Red]skb_queue_tail+0x17/0x2d[/color] SS:ESP 0068:c0740eb0
  49. <0>Kernel panic - not syncing: Fatal exception in interrupt
  50. BUG: warning at arch/i386/kernel/smp.c:550/smp_call_function() (Tainted: G                                                                                             )
  51. [<c0415ae0>] stop_this_cpu+0x0/0x33
  52. [<c04158cf>] smp_call_function+0x57/0xc3
  53. [<c0424f2b>] printk+0x18/0x8e
  54. [<c041594e>] smp_send_stop+0x13/0x1c
  55. [<c04244c3>] panic+0x4c/0x16d
  56. [<c04064ce>] die+0x240/0x274
  57. [<c0618716>] do_page_fault+0x52a/0x607
  58. [<c04596c4>] __alloc_pages+0xd8/0x297
  59. [<c06181ec>] do_page_fault+0x0/0x607
  60. [<c0405a89>] error_code+0x39/0x40
  61. [<c05b57db>] skb_queue_tail+0x17/0x2d
  62. [<f8a79337>] hack_recv+0xc1/0xe9 [net]
  63. [<c05ba65f>] netif_receive_skb+0x323/0x370
  64. [<f8986b56>] bnx2_poll_work+0xc22/0xd2c [bnx2]
  65. [<c041df20>] enqueue_task+0x29/0x39
  66. [<c0405946>] common_interrupt+0x1a/0x20
  67. [<c041df20>] enqueue_task+0x29/0x39
  68. [<c041df7a>] __activate_task+0x4a/0x59
  69. [<c041e83d>] try_to_wake_up+0x3e8/0x3f2
  70. [<c04074ba>] do_IRQ+0xb5/0xc3
  71. [<f898a08a>] bnx2_poll_msix+0x29/0xbf [bnx2]
  72. [<c05bc4c4>] net_rx_action+0x9c/0x1a7
  73. [<c04292fb>] __do_softirq+0x87/0x114
  74. [<c04073bb>] do_softirq+0x52/0x9c
  75. [<c044b5b0>] __do_IRQ+0x0/0xd6
  76. [<c04074ba>] do_IRQ+0xb5/0xc3
  77. [<c0405946>] common_interrupt+0x1a/0x20
  78. [<c0617378>] _spin_unlock_irqrestore+0x8/0x9
  79. [<c05b589f>] skb_dequeue+0x39/0x3f
  80. [<f8a79409>] get_one_skb+0x15/0x31 [net]
  81. [<f8a7943c>] net_hack_read+0x17/0x103 [net]
  82. [<c044840a>] audit_syscall_entry+0x15a/0x18c
  83. [<f8a79425>] net_hack_read+0x0/0x103 [net]
  84. [<c047331c>] vfs_read+0x9f/0x141
  85. [<c047376a>] sys_read+0x3c/0x63
  86. [<c0404f17>] syscall_call+0x7/0xb
  87. ======================
复制代码

论坛徽章:
0
3 [报告]
发表于 2011-07-16 11:30 |只看该作者
回复 1# leonwang202

经过牛人指点,问题解决

    nskb = skb_clone(skb, GFP_ATOMIC);

   nskb可能为NULL.....⊙﹏⊙b汗

论坛徽章:
0
4 [报告]
发表于 2012-08-04 19:03 |只看该作者
学习了,给力

论坛徽章:
0
5 [报告]
发表于 2015-07-22 14:22 |只看该作者
学习
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP