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内核简单了很多


【add by yiyeguzhou100】

netdev_budget: Maximum number of packets taken from all interfaces in one polling cycle (NAPI poll). In one polling cycle interfaces which are registered to polling are probed in a round-robin manner. The limit of packets in one such probe can be set per-device via sysfs class/net/<device>/weight .    

static void net_rx_action(struct softirq_action *h) //net_rx_action details explain: http://blog.chinaunix.net/uid-27018250-id-3835884.html
{
	struct softnet_data *sd = &__get_cpu_var(softnet_data); //net_rx_action负责从当前CPU中获取softnet_data,处理poll_list上的dev,调用dev->poll()对网络数据进行真正处理。
              //this is current CPU's softnet_data(sd)
	unsigned long time_limit = jiffies + 2;
	int budget = netdev_budget; //default value is 300
	struct sk_buff *skb;
	void *have;

	local_irq_disable();

	while ((skb = __skb_dequeue(&sd->tofree_queue))) {
		local_irq_enable();
		kfree_skb(skb);
		local_irq_disable();
	}
	
	/**
	 * 遍历等待轮询的设备链表。
	 */
	while (!list_empty(&sd->poll_list)) {</span>


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值