/*
net_rx_action()会从两个地方取帧数据:
(1)非NAPI设备的中断处理流程把帧放入本地cpu私有数softnet_data 的接收队列中
(2)调用NAPI设备驱动的poll方法会直接从设备内存(或设备驱动程序接收环)中取出帧
*/
static void net_rx_action(struct softirq_action *h)
{
/*取得本地cpu 的softnet_data 的poll_list 链表
在里面放着所有需要轮询接收数据包的设备
*/
struct list_head *list = &__get_cpu_var(softnet_data).poll_list;
/*设置软中断处理程序一次允许的最大执行时间为2个jiffies*/
unsigned long time_limit = jiffies + 2;
int budget = netdev_budget;//轮询配额 当数据包数超过此值 进行轮询接收 此值初始为300
void *have;
//禁止本地cpu中断
local_irq_disable();
/*
list的更新:
(1)在执行具体的poll函数中若此时的设备已经没有数据则poll中会调用__napi_complete()从链表删除此设备list得到更新
(2)在执行具体的poll函数中若处理的数据超过了设备的权重weight 则在while的后面在此设备没有被禁止的情下将此设备放到链表的尾部list得到更新
*/
while (!list_empty(list))
{
struct napi_struct *n;
int work, weight;
//限制轮询处理包个数以及处理的时间
if