赞
踩
非NAPI的数据包处理流程:采用的是中断方式,即网卡收到数据包就触发一个中断,然后交由中断处理程序进行处理。
优势:响应及时,如果数据量较小,则不会占用太多的CPU事件。
劣势:数据量大时,会产生过多中断,而每个中断都要消耗不少的CPU时间。
NAPI的数据包处理流程:采用的是综合中断方式和轮询方式。即,当网卡收到一个数据包时,产生一个中断,触发中断处理函数,NAPI方式中断处理函数会关闭中断,然后通过驱动
优势:数据量大或者数据量小的时候,使用中断或者轮询的方式,数据包处理效率都非常高。
劣势:数据流量不稳定时,则NAPI则会在两种方式切换上消耗不少时间,效率反而较低一些。对于上层应用来说,系统不能在接收到每个数据包时可以及时的去处理,随着传输速度的增加,累计的数据包将耗费大量内存;另外采用NAPI所造成的另一个问题就是对大的数据包处理比较困难,原因是大包处理更费时。NAPI技术适用于高速率的短数据包的处理。
网卡收包产生中断,调用驱动处理函数,驱动处理函数会根据网络设备是否支持NAPI调用不通的内核处理函数,netif_rx和napi_schedule为内核入口函数。
enqueue_to_backlog和__napi_schedule都通过____napi_schedule函数(通过调用__raise_softirq_irqoff(NET_RX_SOFTIRQ))激触发软中断,但是区别是加入poll_list的回调函数不同,enqueue_to_backlog的回调函数为process_backlog,而__napi_schedule的回调函数为napi_struct中的poll函数,该方法由驱动提供,在通过netif_napi_add加入napi_struct时制定。
netif_rx是内核接收数据包的入口。
/**
* netif_rx - post buffer to the network code
* @skb: buffer to post
*
* This function receives a packet from a device driver and queues it for
* the upper (protocol) levels to process. It always succeeds. The buffer
* may be dropped during processing for congestion control or by the
* protocol layers.
*
* return values:
* NET_RX_SUCCESS (no congestion)
* NET_RX_DROP (packet was dropped)
*
*/
int netif_rx(struct sk_buff *skb)
{
int ret;
/* if netpoll wants it, pretend we never saw it */
if (netpoll_rx(skb))
return NET_RX_DROP;
if (netdev_tstamp_prequeue)
net_timestamp_check(skb);
trace_netif_rx(skb);
#ifdef CONFIG_RPS
{
struct rps_dev_flow voidflow, *rflow = &voidflow;
int cpu;
preempt_disable();
rcu_read_lock();
cpu = get_rps_cpu(skb->dev, skb, &rflow);
if (cpu < 0)
cpu = smp_processor_id();
ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
rcu_read_unlock();
preempt_enable();
}
#else
{
unsigned int qtail;
ret = enqueue_to_backlog(skb, get_cpu(), &qtail);
put_cpu();
}
#endif
return ret;
}
EXPORT_SYMBOL(netif_rx);

在网卡驱动的中断处理函数中调用napi_schedule来使用NAPI
/**
* napi_schedule - schedule NAPI poll
* @n: napi context
*
* Schedule NAPI poll routine to be called if it is not already
* running.
*/
static inline void napi_schedule(struct napi_struct *n)
{
if (napi_schedule_prep(n))
__napi_schedule(n);
}
参考:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。