微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

网络设备 无缓冲空间

如何解决网络设备 无缓冲空间

您好,我创建了使用 uart 端口发送和接收的网络驱动程序。 我的驱动程序遇到了一些问题。我能够 ping 但总是在我得到几个 ping 之后

ping: sendmsg: 没有可用的缓冲区空间驱动

我检查了内核日志,但我什么也没看到。

这是我接收数据的方式:

struct stm32_port *stm32_port = netdev_priv(my_net);
struct sk_buff *skb;
unsigned char *dma_start;

dma_start = stm32_port->rx_buf + (RX_BUF_L - stm32_port->last_res);
print_hex_dump(KERN_DEBUG,"data: ",DUMP_PREFIX_OFFSET,16,1,dma_start,true);

skb = dev_alloc_skb(dma_size + 2);
if (!skb) {
    if (printk_ratelimit(  ))
        printk(KERN_NOTICE "snull rx: low on mem - packet dropped\n");
    my_net->stats.rx_dropped++;
    //goto error;
}

memcpy(skb_put(skb,dma_size),dma_size);

/* Write Metadata,and then pass to the receive level */
skb->dev = my_net;
skb->protocol = eth_type_trans(skb,my_net);
skb->ip_summed = CHECKSUM_NONE; // let the OS check the checksum
my_net->stats.rx_packets++;
my_net->stats.rx_bytes += dma_size;
netif_rx(skb);

port->icount.rx += dma_size;
stm32_port->last_res -= dma_size;
if (stm32_port->last_res == 0)
    stm32_port->last_res = RX_BUF_L; //dma_count

这是我发送数据的方式:

struct stm32_port *lp = netdev_priv(ndev);
struct uart_port *port = &lp->port;
struct sk_buff *sk_buff;
struct dma_async_tx_descriptor *desc = NULL;
struct stm32_usart_offsets *ofs = &lp->info->ofs;
unsigned pktlen = skb->len;
dma_cookie_t cookie;
int ret = 0;

//print_hex_dump(KERN_DEBUG,skb->data,true);

netif_stop_queue(ndev);

sk_buff = skb_get(skb);

if (ofs->icr == UNDEF_REG){
    stm32_usart_clr_bits(port,ofs->isr,USART_SR_TC);
}else{
    writel_relaxed(USART_ICR_TCCF,port->membase + ofs->icr);
}

    memcpy(&lp->tx_buf[0],sk_buff->data,pktlen);
    desc = dmaengine_prep_slave_single(lp->tx_ch,lp->tx_dma_buf,pktlen,DMA_MEM_TO_DEV,DMA_PREP_INTERRUPT);

    if (!desc){
        goto fallback_err;            
    }
    
    cookie = dmaengine_submit(desc);
    ret = dma_submit_error(cookie);
    if (ret) {
        /* dma no yet started,safe to free resources */
        dmaengine_terminate_async(lp->tx_ch);
        goto fallback_err;
    }

    /* Issue pending DMA TX requests */
    dma_async_issue_pending(lp->tx_ch);

    stm32_usart_set_bits(port,ofs->cr3,USART_CR3_DMAT);

/* rely on TXE irq (mask or unmask) for sending remaining data */
stm32_usart_tx_interrupt_disable(port);

ndev->stats.tx_packets++;
ndev->stats.tx_bytes += pktlen;

fallback_err:
skb_tx_timestamp(skb);
dev_kfree_skb (skb);
netif_start_queue(ndev);
return NETDEV_TX_OK;

解决方法

感谢@stark,我找到了一个解决方案,我现在使用 __kfree_skb() 方法释放缓冲区,因为这样不会检查引用计数。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。