struct softnet_data
{
struct Qdisc *output_queue; //qdisc是queueing discipline的简写,也就是排队规则,即qos.这里也就是输出帧的控制。
struct sk_buff_head input_pkt_queue; //当输入帧被驱动取得之前,就保存在这个队列里,(不适用与napi驱动,napi有自己的私有队列)
struct list_head poll_list; //表示有输入帧待处理的设备链表。
struct sk_buff *completion_queue; //表示已经成功被传递出的帧的链表。
struct napi_struct backlog; //用来兼容非napi的驱动。
};
struct napi_struct {
/* The poll_list must only be managed by the entity which
* changes the state of the NAPI_STATE_SCHED bit. This means
* whoever atomically sets that bit can add this napi_struct
* to the per-cpu poll_list, and whoever clears that bit
* can remove from the list right before clearing the bit.
*/
struct list_head poll_list; //设备列表(在入口队列有新帧等待处理的设备)
unsigned long state;
int weight;
int (*poll)(struct napi_struct *, int); //把缓冲区从设备的入口队列(NAPI私有队列,softnet_data->input_pkt_queue不同)退出
#ifdef CONFIG_NETPOLL
spinlock_t poll_lock;
int poll_owner;
#endif
unsigned int gro_count;
struct net_device *dev;
struct list_head dev_list;
struct sk_buff *gro_list;
struct sk_buff *skb;
}; 我们需要注意poll_list成员,它表示在输入队列中有帧需要处理的设备链表,这是用来支持轮询的。这个链表中的设备都处于关中断的状态。内核在适当时间进行轮询处理这些设备接收到的帧。原文地址:http://blog.csdn.net/windeal3203/article/details/44829161