网络子系统19_积压设备

来源:互联网 发布:公众号刷粉软件 编辑:程序博客网 时间:2024/05/07 18:41
//1.积压设备的目的://napi设备,非napi设备同一处理接口,linux为所有不使用napi的驱动程序,提供了一个虚拟设备,叫做积压设备。//2.与积压设备有关的数据结构://2.1 每个cpu都有一个积压设备,保存在softnet_data->backlog_dev//2.2 每个cpu都有一个积压设备的输入队列,保存在softnet_data->input_pkt_queue,所有非napi设备的入口skb,均挂载到此队列。//2.3 内核为积压设备的提供poll函数,process_backlog//积压设备的poll函数//调用路径:net_rx_action->process_backlog//参数://backlog_dev,积压设备//budget,函数此次运行可以处理的skb配额//返回值://<0 , 表明设备还有待处理的入口帧,此时设备仍然在poll_list中,且设备处于关中断状态//=0 , 表明设备已经处理完所有的入口帧,此时设备已经从poll_list中删除,可接收重新调度,设备中断已开启//函数主要任务://1.函数运行不能超过1个jiffies,处理的skb不能超过配额//2.在关中断的情况下,从softnet->input_pkt_queue取下入口skb,后开中断//2.1 如果有入口skb//2.1.1 通过netif_receive_skb向上层协议传递skb//2.1.2 递减入口设备的引用计数//2.2 如果在运行时间不足1个jiffies,并且没有超过配额的情况下,处理完了入口队列的所有skb//2.2.1 更新设备的可用配额//2.2.2 由于已经没有入口数据,因此将挤压设备从调度队列poll_list上取下来//2.2.3 清除积压设备的调度标志,表示设备可以接收下一次调度//2.2.4 如果之前入口队列满,被设置了throttle,则在入口队列为空时,清除throttle//注:在入口队列满,设置了throttle,之后的入口数据都会被丢弃,直到入口队列为空,清除throttle之后,才开始重新接收入口数据。1.1 static int process_backlog(struct net_device *backlog_dev, int *budget){int work = 0;//此次调用可以处理的skb为 设备剩余配额,传入的配置中的较小者int quota = min(backlog_dev->quota, *budget);struct softnet_data *queue = &__get_cpu_var(softnet_data);unsigned long start_time = jiffies;for (;;) {struct sk_buff *skb;struct net_device *dev;//关闭本cpu中断,因为input_pkt_queue可能会在中断中被修改local_irq_disable();//从input_pkt_queue上退出一个skbskb = __skb_dequeue(&queue->input_pkt_queue);if (!skb)goto job_done;//开中断local_irq_enable();dev = skb->dev;//将skb向上传递netif_receive_skb(skb);//递减接收此skb的dev的引用计数dev_put(dev);//消费流量个数-1work++;//此函数运行时间应该 < 1 jiffiesif (work >= quota || jiffies - start_time > 1)break;}//将设备的配额减去实际消费的流量个数backlog_dev->quota -= work;//将打算让设备消费的流量个数中减去实际消费的流量个数*budget -= work;return -1;//表示接收队列为空job_done:backlog_dev->quota -= work;*budget -= work;//将积压设备从poll_list上删除list_del(&backlog_dev->poll_list);smp_mb__before_clear_bit();//清除积压设备__LINK_STATE_RX_SCHED标识,表示积压设备重新可以接收调度netif_poll_enable(backlog_dev);//如果此cpu的输入队列已经关闭,开启输入队列if (queue->throttle)queue->throttle = 0;//开本cpu中断local_irq_enable();return 0;}//对积压设备的调度//调用路径 : 非napi设备的接收中断->netif_rx2.1 int netif_rx(struct sk_buff *skb){...netif_rx_schedule(&queue->backlog_dev);...}

原创粉丝点击