繁体   English   中英

网络驱动程序轮询中断中的致命异常

[英]Fatal exception in interrupt in network driver polling

我正在为我的项目开发一个自定义网络设备驱动程序,与以太网驱动程序不同,在该驱动程序中,我没有接收数据包的中断(设计限制)。 因此,我将轮询用于驱动程序的接收部分。 我已经在Linux中使用tasklet实现了一种轮询机制(主要从LDD3的jit.c示例中借用),该机制将轮询功能重新安排了10000次(有点随机数),以在每两次轮询之间进行延迟。 它工作正常,但我决定使其成为基于计时器的实现,以避免额外的开销。 我使用了HRtimers,工作队列和计时器来调用Tasklet,但它们都面临此错误

内核恐慌-不同步:中断中发生致命异常

eth_type_trans函数中。 以下是我得到的紧急错误详细信息:

[ 5031.345599] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[ 5031.346090] pgd = ffffffc07cf7f000
[ 5031.346471] [00000000] *pgd=0000000000000000
[ 5031.346988] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[ 5031.347383] Modules linked in: alex_mcn(O)
[ 5031.348144] CPU: 0 PID: 601 Comm: systemd-journal Tainted: G           O  3.16.0-rc6 #1
[ 5031.348744] task: ffffffc07cff5c40 ti: ffffffc07cf64000 task.ti: ffffffc07cf64000
[ 5031.349303] PC is at eth_type_trans+0x5c/0x164
[ 5031.349913] LR is at polling_tasklet_fn+0x84/0x144 [alex_mcn]

然后它给了我堆栈跟踪:

[ 5031.406316] Call trace:  
[ 5031.406798] [<ffffffc00045d604>] eth_type_trans+0x5c/0x164 
[ 5031.407482] [<ffffffbffc000310>] polling_tasklet_fn+0x80/0x144 [alex_mcn] 
[ 5031.408114] [<ffffffc000099198>] tasklet_hi_action+0xc4/0x198
[ 5031.408716] [<ffffffc0000995bc>] __do_softirq+0x10c/0x220 
[ 5031.409304] [<ffffffc00009993c>] irq_exit+0x8c/0xc0 
[ 5031.409882] [<ffffffc000084514>] handle_IRQ+0x6c/0xe0 
[ 5031.410440] [<ffffffc000081290>] gic_handle_irq+0x3c/0x80

我有效的初始代码是:

static int alex_mcn_single_rx(void){
   struct sk_buff *skb;
   ...
   skb = netdev_alloc_skb(net_dev, pktLen+5);
   ...
   skb->protocol = eth_type_trans(skb, net_dev);
   skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
   if( netif_rx(skb) == NET_RX_SUCCESS){
     net_dev->stats.rx_packets++;
   }
   else{
     printk("!!! Failure in receiving the packet\n");
     return 1;
   }

  return 0;
}

static void polling_tasklet_fn(unsigned long arg)
{
  polling_data->count++;
  if(polling_data->loops){
      if((polling_data->count)%10000==0) 
      {
          alex_mcn_single_rx();
      }
  }
  tasklet_schedule(&polling_data->tlet);
}
static void init_polling_tasklet(char * buf){

  polling_data->count = 0;
  polling_data->loops = 1;

  /* register the tasklet */
  tasklet_init(&polling_data->tlet, polling_tasklet_fn, 0);
  tasklet_hi_schedule(&polling_data->tlet);

}

该代码有效,但是当我删除if(polling_data-> loops)语句时,它将停止工作,并给我与上述相同的错误。 这对我来说没有任何意义,因为Tasklet中没有竞争条件。 另外,我知道eth_type_trans是唯一的罪魁祸首。 当我删除它时,它没有遇到任何错误(尽管然后该数据包将被丢弃)。 如果有人可以给我一些线索,我将不胜感激。

ps:我将gem5仿真器与ARMv8拱一起使用。 测试我的设计。

解决了 :我最终将eth_type_trans()函数复制到设备驱动程序,并调试了printks的问题。 用这种方法进行调试比重建内核要容易得多(模拟器要花很多时间)。 在将eth_trans_type()函数复制到代码中并开始在设备驱动程序中对其进行调试之后,该函数开始正常运行

你怎么得到net_dev 点占位符(...)看起来很模糊。 我猜想netdev_alloc_skb()不会在net_dev = NULL时崩溃,因为它没有取消引用它,但是eth_type_trans()需要正确的net_dev指针。 调用eth_type_trans()时,您是否拥有合适的net_dev

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM