Chinaunix首页 | 论坛 | 博客
  • 博客访问: 434458
  • 博文数量: 99
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 1012
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-20 16:30
个人简介

linux kernel 工程师

文章分类

全部博文(99)

文章存档

2018年(5)

2017年(12)

2016年(27)

2015年(10)

2014年(43)

2012年(2)

我的朋友

分类: LINUX

2014-02-11 12:09:44

process_backlog是softnet_data->backlog的poll函数, 作为非NAPI接口的处理函数
net_rx_action调用poll函数时会使用它。

static int process_backlog(struct napi_struct *napi, int quota)
{
 int work = 0;
 struct softnet_data *sd = container_of(napi, struct softnet_data, backlog);

#ifdef CONFIG_RPS
 /* Check if we have pending ipi, its better to send them now,
  * not waiting net_rx_action() end.
  */
 if (sd->rps_ipi_list) {
  local_irq_disable();
  net_rps_action_and_irq_enable(sd);
 }
#endif
 napi->weight = weight_p;
 local_irq_disable();
 while (work < quota) {
  struct sk_buff *skb;
  unsigned int qlen;

  while ((skb = __skb_dequeue(&sd->process_queue))) {  //skb实际上从process_queue取下,而不是直接从input_pkt_queue取下
   local_irq_enable();
   __netif_receive_skb(skb);  //交给ip层处理
   local_irq_disable();
   input_queue_head_incr(sd);
   if (++work >= quota) {// 不能超过配额
    local_irq_enable();
    return work;
   }
  }

  rps_lock(sd);
  qlen = skb_queue_len(&sd->input_pkt_queue);
  //将input_pkt_queue并入process_queue
  if (qlen)
   skb_queue_splice_tail_init(&sd->input_pkt_queue,
         &sd->process_queue);

  //如果总的工作量不超过配额,说明本次就可以处理完毕,将backlog从softnet的poll_list上拿下
  if (qlen < quota - work) {
   /*
    * Inline a custom version of __napi_complete().
    * only current cpu owns and manipulates this napi,
    * and NAPI_STATE_SCHED is the only possible flag set on backlog.
    * we can use a plain write instead of clear_bit(),
    * and we dont need an smp_mb() memory barrier.
    */
   list_del(&napi->poll_list);
   napi->state = 0;

   quota = work + qlen; //调整quota至work + qlen,而不必等到原先分配的weight
   }
  rps_unlock(sd);
 }
 local_irq_enable();

 return work;
}

阅读(1494) | 评论(0) | 转发(0) |
0

上一篇:netif_rx

下一篇:struct softnet_data 简单分析

给主人留下些什么吧!~~