- 论坛徽章:
- 0
|
to kmindg & humjb_1983
看来大家比较纠结"netif_receive_skb是运行在软中断上下文" 这句话,仔细看一下netif_receive_skb的代码注释吧,linux内核多个内核版本都是清晰了标注了
“This function may only be called from softirq context ”
/**
2270 * netif_receive_skb - process receive buffer from network
2271 * @skb: buffer to process
2272 *
2273 * netif_receive_skb() is the main receive data processing function.
2274 * It always succeeds. The buffer may be dropped during processing
2275 * for congestion control or by the protocol layers.
2276 *
2277 * This function may only be called from softirq context and interrupts
2278 * should be enabled.
2279 *
2280 * Return values (usually ignored):
2281 * NET_RX_SUCCESS: no congestion
2282 * NET_RX_DROP: packet was dropped
2283 */
2284int netif_receive_skb(struct sk_buff *skb)
2285{
2286 struct packet_type *ptype, *pt_prev;
2287 struct net_device *orig_dev;
2288 struct net_device *null_or_orig;
2289 int ret = NET_RX_DROP;
2290 __be16 type;
2291
2292 if (!skb->tstamp.tv64)
2293 net_timestamp(skb);
2294
2295 if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
2296 return NET_RX_SUCCESS;
2297
2298 /* if we've gotten here through NAPI, check netpoll */
2299 if (netpoll_receive_skb(skb))
2300 return NET_RX_DROP;
netif_receive_skb是在网卡驱动接收到数据包,将skb投递协议栈处理的时候调用的,所以netif_receive_skb是是在网卡软中断上下文调用的,包括后续
的投递的协议栈(如果是TCP包)的ip_rcv,tcp_v4_rcv,tcp_v4_do_rcv,协议栈的处理过程都是在软中断上下文完成,第一眼看到这个调用堆栈居然有人这么调用,
感到蛮诧异的,更没有想到还有的人会认为netif_receive_skb不应该运行在软中断上下文。
ksoftirqd是软中断的辅助处理线程,理论上所有的软中断,都有机会(可能)被ksoftirqd调用执行,是否这样就否认软中断上下文的存在?如果有人不相信netif_receive_skb
是在软中断上下文调用的,在netif_receive_skb函数中加个sleep编个内核试试看。内核提供宏in_softirq() 可以方便确认当前函数运行在哪一种上下文,为什么函数要明确调用上下文,这和资源的互斥访问相关,资源的互斥访问就得用锁,分不清调用上下文的,也必然不会用锁。
|
|