C 网络设备没有缓冲区空间
您好,我创建了网络驱动程序,它使用uart端口发送和接收数据。 我的驱动程序处理一些问题。我能打乒乓球,但每次打几下后,我都会得到 ping:sendmsg:没有可用的缓冲区空间 我检查了内核日志,但什么也看不到 这就是我接收数据的方式:C 网络设备没有缓冲区空间,c,linux,driver,device,uart,C,Linux,Driver,Device,Uart,您好,我创建了网络驱动程序,它使用uart端口发送和接收数据。 我的驱动程序处理一些问题。我能打乒乓球,但每次打几下后,我都会得到 ping:sendmsg:没有可用的缓冲区空间 我检查了内核日志,但什么也看不到 这就是我接收数据的方式: struct stm32_port *stm32_port = netdev_priv(my_net); struct sk_buff *skb; unsigned char *dma_start; dma_start = stm32_port->rx
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,我找到了一个解决方案,我现在用uu kfree_skb()方法释放缓冲区,因为这样就不会检查refcount。skb不会被释放,如果refcount不是0。也许试着加一张支票。对不起,我的问题可能很傻。你到底是什么意思。我想当我发送时,netif_rx会释放缓冲区。发送时,我用dev_kfree_skb清除缓冲区。