Chinaunix首页 | 论坛 | 博客
  • 博客访问: 328020
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: LINUX

2013-07-18 15:15:30

内核版本:kernel-2.6.18

网卡驱动通过调用netif_rx函数,把数据送入到协议栈中。

代码中用到一个数据结构 softnet_data ,在网卡收发数据的时候,需要维护一个缓冲区队列,来缓存数据,在协议栈中用一个队列层来表示该缓冲区,队列层位于数据链路层和网络层之间。softnet_data 就是数据链路层中的数据结构,它是一个Per-CPU变量,每个CPU都有一个.


 

点击(此处)折叠或打开

  1. int netif_rx(struct sk_buff *skb)
  2. {
  3.        ………………………………
  4.        local_irq_save(flags);
  5.        /* 获取当前CPU的 softnet_data 数据 */
  6.        queue = &__get_cpu_var(softnet_data);
  7.        __get_cpu_var(netdev_rx_stat).total++;
  8.        /* netdev_max_backlog 允许送到队列的数据包的最大数目。
  9.           监测是否还有空间来存储帧,若大于netdev_max_backlog
  10.           表示空间已满,网络阻塞严重,cpu将丢弃。
  11.        */
  12.        if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
  13.               /* 空间已有存储的数据帧 */
  14.               if (queue->input_pkt_queue.qlen) {
  15. enqueue:
  16.                      dev_hold(skb->dev);
  17.                      /* 挂softnet_data输入队列 */
  18.                      __skb_queue_tail(&queue->input_pkt_queue, skb);
  19.                      local_irq_restore(flags);
  20.                      return NET_RX_SUCCESS;
  21.               }
  22.               /* queue->input_pkt_queue.qlen 为0表示队列是空,
  23.                  表明此队列并没有被软中断所处理,
  24.                  因此我们需要将此队列加入到软中断的处理链表中。
  25.               */
  26.               netif_rx_schedule(&queue->backlog_dev);
  27.               goto enqueue;
  28.        }
  29.        __get_cpu_var(netdev_rx_stat).dropped++;
  30.        local_irq_restore(flags);
  31.        kfree_skb(skb);
  32.        return NET_RX_DROP;
  33. }


阅读(9289) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~