我读到了从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;
}那么,在netif_rx( skb )之后,skb将保持在下半部分的哪一点?
谢谢。
发布于 2016-04-06 08:29:17
编辑:我写了一篇博客文章,概述了整个linux网络栈(接收路径),其中提供了大量详细信息,瞧一瞧。
答案是复杂的,但是是的,netfilter代码运行在softirq上下文中。
流程的工作方式如下:
NET_RX_SOFTIRQ in /proc/softirqs)中运行的NAPI内核线程从内存( NIC获取数据)中获取数据包。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_core
ip_rcv,后者也将检查网络过滤器。sock_queue_rcv_skb将其排队到套接字的接收缓冲区。例如,UDP从一个名为这里的函数执行此__udp_queue_rcv_skb。sock_queue_rcv_skb将数据排队到套接字接收缓冲区。您可以找到这段代码这里。一些注意事项:
budget来调整NAPI的net.core.netdev_budget。预算越高,到进程的接收队列排队的数据包就越多,但是CPU运行用户进程的时间就越少。如果你对这个过程有什么其他问题我可以回答,请告诉我。
发布于 2016-03-22 13:50:43
上面的代码运行在硬件中断上下文、netif_rx队列、数据包和信号内核继续SOFTIRQ上下文(NET_RX)上。
https://stackoverflow.com/questions/35959155
复制相似问题