忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT HPC论坛 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 1301 | 回复: 0

LINUX网卡驱动,使用iperf测试丢包, packet receive errors [复制链接]

论坛徽章:
0
发表于 2017-02-16 17:07 |显示全部楼层
大神们好,小弟最近做了一个LINUX网卡驱动,用iperf来测试时候,发现UDP有丢包。
用iperf测试UDP,一共测试两次,一次一个小时,速率为1000M,丢包率大概在0.0001%左右
再继续测试时,发现会大量丢包,已经惨不忍睹了,不知道什么问题,现在把收发代码贴出来,请大家指正一下:

/*发送回调函数*/


```
netdev_tx_t net_tx (struct sk_buff *skb, struct net_device *dev)
{
        NET_PRIV *net_priv = netdev_priv(dev);
        unsigned long flags;
        PNET_SKB_DATA  pskb ;

       
        spin_lock_irqsave(&net_priv->send_lock, flags);


        /*list_skbPool pool中取一个pskb*/
        pskb = (PNET_SKB_DATA)listGetFirstNodeFromList(&net_priv->dev->list_skbPool);
        /*如果没取到,则返回*/
        if(pskb == NULL)
        {
                spin_unlock_irqrestore(&net_priv->send_lock, flags);
                return NETDEV_TX_BUSY;

        }
       
        /*取到一个pskb后,把这个pskb从队列list_skbPool移除*/
        pskb = listRemoveNodeFromListHead(&net_priv->dev->list_skbPool);
       
        /*把skb挂在pskb中*/
        pskb->skb = skb;

        /*把pskb插入队列list_skbSend尾部,等待另外一个线程来取数据,继而发送出去*/
        listAddNodeToListTail(pskb, &net_priv->dev->list_skbSend);
       

        dev->trans_start = jiffies;
        up(net_priv->dev->semElsSend);
       
        spin_unlock_irqrestore(&net_priv->send_lock, flags);
       
       
        return NETDEV_TX_OK;
}
```



此时另外有一个线程,在不断取数据,取到后就发送出去。



接收时,是一个线程一直从链路上收数据,收到数据就调用下面这个接收函数
/*接收函数*/


```
int net_rx(unsigned char *data, unsigned int len, struct net_device *dev)
{
        struct sk_buff *skb = NULL;

       
        NET_PRIV *net_priv = netdev_priv(dev);
        unsigned long flags;
       

        /*分配套接字缓冲区*/
        skb = dev_alloc_skb(len + 2);
        if(skb == NULL)
        {
                printk("%s:memory is not sufficient, rcvd packet dropped.\n", dev->name);
                dev->stats.rx_dropped++;
               
                return -1;
        }
        skb_reserve(skb, 2);

        skb->dev = dev;


        memcpy(skb_put(skb, len), data, len);
       
        skb->protocol = eth_type_trans(skb, dev);


        if(NET_RX_SUCCESS != netif_receive_skb(skb))
        {
                dev->stats.tx_errors ++;
                dev->stats.tx_dropped ++;
               
                return -2;
        }


        /*接收包统计*/
        dev->stats.rx_packets ++;
        dev->stats.rx_bytes += len;

        return 0;
}
```




之前加了一些统计打印,发现从链路及驱动里面没有丢包。
丢包发生在送给协议栈后,在协议栈丢掉了
通过命令netstat -su发现打印如下:
Udp:
    30681696 packets received
    71 packets to unknown port received.
    436 packet receive errors
    266 packets sent
    436 receive buffer errors
    0 send buffer errors
    IgnoredMulti: 393

其中436 packet receive errors 这个统计值436,正好就是iperf统计的丢包数量。
在网上搜了很多,说是当出现packet receive errors 的时候,说明是应用层来不及接收导致的。但是我用两台PC机(linux系统)进行测试,没有丢包。

这个问题困惑了很久,希望得到大神指点,谢谢!

打赏鼓励一下!

1人打赏

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP