Has*_*ell 4 cpu-architecture interrupt-handling
我正在阅读从NIC中断处理程序到用户空间的接收路径中的数据包流.
我想知道新分配的skbuff在下半部分中保留到哪一点.
从LDD获取snull_rx()代码:
void snull_rx(struct net_device *dev, struct snull_packet *pkt)
{
struct sk_buff *skb;
struct snull_priv *priv = netdev_priv(dev);
/*
* The packet has been retrieved from the transmission
* medium. Build an skb around it, so upper layers can handle it
*/
skb = dev_alloc_skb(pkt->datalen + 2);
if (!skb) {
if (printk_ratelimit( ))
printk(KERN_NOTICE "snull rx: low on mem - packet dropped\n");
priv->stats.rx_dropped++;
goto out;
}
memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen);
/* Write metadata, and then pass to the receive level */
skb->dev = dev;
skb->protocol = eth_type_trans(skb, dev);
skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
priv->stats.rx_packets++;
priv->stats.rx_bytes += pkt->datalen;
netif_rx(skb);
out:
return;
}
Run Code Online (Sandbox Code Playgroud)
所以在netif_rx(skb)之后直到skb保持在下半部分的哪一点?
谢谢.
编辑:我写了一篇博客文章,概述了提供大量详细信息的整个linux网络堆栈(接收路径),看一看.
答案很复杂,但是netfilter代码在softirq上下文中运行.
流程的工作方式如下:
NET_RX_SOFTIRQin /proc/softirqs)中运行的NAPI内核线程从内存中收集数据包(NIC DMA'd数据).budget数据包或数据包处理的时间限制.你可以在这里找到这个代码.__netif_receive_skb_core被调用.此函数的确切路径取决于驱动程序,但e1000e路径为:
e1000e_polle1000e_poll 电话 e1000_clean_rx_irqe1000_clean_rx_irq 电话 e1000_receive_skbe1000_receive_skb 电话 napi_gro_receivenapi_gro_receive 电话 napi_skb_finishnapi_skb_finish 电话 netif_receive_skbnetif_receive_skb 电话 netif_receive_skbnetif_receive_skb 电话 __netif_receive_skb_coreip_rcv,也会检查netfilter.sock_queue_rcv_skb.例如,UDP在这里从一个名为的函数执行此操作__udp_queue_rcv_skb.sock_queue_rcv_skb将数据排队到套接字接收缓冲区.你可以在这里找到这个代码.一些说明:
budget通过更改sysctl 来调整for NAPI net.core.netdev_budget.预算越高,将排队到进程的接收队列的数据包越多,但CPU将有更少的时间来运行用户进程.如果您对此流程有任何其他疑问,请与我联系.