数据链路层二

 

3 网络接收软件中断

网络系统的软中断接收处理程序是net_rx_action()。net_rx_action()的任务是将数据帧推送到上层TCP/Ip协议进行处理。要推送给上层协议的数据可以从两个地方获取。

²  多个设备共享的CPU输入队列。不支持NAPI的网络设备的中断处理程序掉netif_rx函数,把数据帧放在当前执行中断处理程序的CPU的输入队列中。net_rx_action()从输入队列中获取数据帧传给上层协议,CPU的输入队列由所有不支持NAPi的网络设备共享。

²  设备硬件缓冲区。支持NAPi的网络设备驱动程序用poll函数直接从设备硬件缓冲区中读出数据帧推送给上层协议。

软件流程

数据链路层二_第1张图片

4 从输入队列中读取数据

         CPU对立softnet_data的poll虚函数,初始化为默认的process_backlog,为不支持NAPI的设备来处理队列中的数据帧。分析netif_rx的执行流程,发现netif_rx函数在接收到第一个网络数据帧时,会将处理CPU输入队列数据帧的上传函数process_backlog放到当前CPU的poll_list队列,在net_rx_action()函数中调用执行。

if (test_bit(NAPI_STATE_SCHED,&n->state)

work = n->poll(n,weight);

static int process_backlog(struct napi_struct *napi, int quota)

{

         int work = 0;

         struct softnet_data *queue = &__get_cpu_var(softnet_data);

         unsigned long start_time = jiffies;

 

         napi->weight = weight_p;

         do {

                   struct sk_buff *skb;

                   struct net_device *dev;

 

                   local_irq_disable();

//从CPU输入队列中获取数据帧skb

                   skb = __skb_dequeue(&queue->input_pkt_queue);

//如果队列空,则将设备移出poll_list队列

                   if (!skb) {

                            __napi_complete(napi);

                            local_irq_enable();

                            break;

                   }

 

                   local_irq_enable();

 

                   dev = skb->dev;

//调用netif_receive_skb将skb传送给上层协议

                   netif_receive_skb(skb);

 

                   dev_put(dev);

         } while (++work < quota && jiffies == start_time);

 

         return work;

}

数据链路层二_第2张图片

此处有个问题需要解决?

怎么知道放入输入队列的数据是哪个设备的?

现在分析下执行到process_backlog时,一些数据结构的问题。

这主要是通过skb中的dev数据域,将数据和设备联系起来了。而napi_struct中又有dev指针域,和设备联系起来,通过各个结构体中的指针,从而将数据与设备联系起来。

 数据链路层二_第3张图片

 

你可能感兴趣的:(数据链路层二)