网络设备无缓冲区Space

network device No buffer Space

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

ping: sendmsg: No buffer space available driver

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

这是我接收数据的方式:

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, 16, 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_start, 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, "data: ", DUMP_PREFIX_OFFSET, 16, 1, skb->data, 16, 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() 方法释放缓冲区,因为那样不会检查引用计数。