2.6.28内核以太网帧接收时的流量控制

2.6.28内核的接收拥塞控制比Understanding Linux Network Internals中所描述的已经简化了很多
这里给出一个简单描述

首先是内核结构成员的变化
1.每cpu变量struct softnet_data中去掉了以下三个成员。
    int            throttle;
    int            cng_level;
    int            avg_blog;
   
2.net_device中去掉了以下两个变量
    int            quota;
    int            weight;
取而代之的是新增的napi_struct中的int weight变量
这个weight表示一个设备的权重,设备权重越大,在一次中断中它所能完成的工作越多
这个权重完全是由驱动程序设计者自己指定的,通过函数
netif_napi_add(struct net_device *dev,
                  struct napi_struct *napi,
                  int (*poll)(struct napi_struct *, int),
                  int weight)
将dev,napi,poll函数和权重联系在一起
虽然可以随意指定,但是为了让系统正常工作,还是不要指定太大,否则可能会造成系统响应变慢
看了几个网卡驱动,e100指定16,e1000,tg3等指定为64.一般来说,网卡速度越快,这个值可以指定的越大
对于非NAPI驱动来说,所有驱动共享一个64的weight


下面我们来看一下这个值是如何起作用的
非NAPI驱动:
    首先对于非NAPI驱动还有一个参数在起作用:netdev_max_backlog。这是一个全局变量,代表非NAPI驱动接收队列的最大长度,默认值为1000,可以通过/proc/sys/net/core/netdev_max_backlog修改。
    每当中断发生时,非NAPI的中断处理函数会调用netif_rx来将接收到的以太网帧传递给内核,所有非NAPI驱动的skb都会被挂到同一个队列上softnet_data.input_pkt_queue,这个队列会随时记录着队列长度。一旦发现队列长度超过了netdev_max_backlog就会丢弃该帧,同时返回一个NET_RX_DROP。从代码来看,似乎很多驱动都不对NET_RX_DROP做出什么反映,想想也对,丢弃就丢弃吧,这是上层的决定,我驱动的工作已经完成了。
   
NAPI驱动:
    全局变量netdev_max_backlog对NAPI驱动不起作用。因为NAPI驱动并不需要在中断中分配skb并挂入某个接收队列,它所做的仅仅是将自己的napi结构挂入softnet_data的poll_list中,然后开启软中断,而分配skb、读入数据并将skb提交给上层是在poll函数中一次完成的。
   

    在软中断中还要用到一个全局变量netdev_budget,这个变量表示一次软中断所能接收的最大报文数,默认值为300,可以通过/proc/sys/net/core/netdev_budget来改变。这个变量跟weight值有点像,只不过这个变量代表的相当于一个总weight,就是一次软中断最多处理的weight之和为300,而每个设备最多处理数为它们自己的weight,假如第一个设备weight为300且一次就处理了300个skb,那么本次软中断就轮不到其它设备了。对于NAPI驱动来说,每一个设备有自己的weight,而非NAPI驱动就不那么幸运了,所有设备要共享64的weight,也就是softnet_data的struct napi_struct backlog中的weight。
   
   
从以上分析可以看出,目前对NAPI驱动接收以太网帧的拥塞控制起作用的仅仅是napi_struct.weight和全局变量netdev_budget,确实比2.6.11内核简单了很多

你可能感兴趣的:(工作,.net,linux,struct,Blog,NetWork)