Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1792419
  • 博文数量: 306
  • 博客积分: 3133
  • 博客等级: 中校
  • 技术积分: 3932
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-19 16:50
文章分类

全部博文(306)

文章存档

2018年(7)

2017年(18)

2016年(39)

2015年(35)

2014年(52)

2013年(39)

2012年(22)

2011年(29)

2010年(53)

2009年(12)

分类: LINUX

2011-11-24 20:34:27

net_rx() --> netif_rx()

    netif_rx() -- 将sk_buff插入到softnet_data->input_pkt_queue链表中

    netif_rx() completes the interrupt handling. First, the current time is set in skb->time, and the socket buffer is placed in the input queue. As compared with earlier versions of the Linux kernel, there is now not only one single queue having the name "backlog"; instead, each CPU stores "its" incoming packets in the structure softnet_data[cpu].input_pkt_queue. This means that the processor that handles the interrupt always stores the packet in its queue. This mechanism was introduced to avoid kernel-wide locks of a single input queue.

    Once the packet was placed in the queue, the interrupt handling is complete. The handling routine of a hardware interrupt should run only the operations absolutely required to ensure that other activities of the computer (software interrupts, tasklets, processes) won't be unnecessarily interrupted.


/usr/src/linux-2.6.19/net/core/dev.c

int netif_rx(struct sk_buff *skb)
{
    struct softnet_data *queue;
    unsigned long flags;
    if (netpoll_rx(skb))
        return NET_RX_DROP;
    if (!skb->tstamp.off_sec)
        net_timestamp(skb);
    local_irq_save(flags);
    queue = &__get_cpu_var(softnet_data);
    __get_cpu_var(netdev_rx_stat).total++;

    if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
        if (queue->input_pkt_queue.qlen) {
enqueue:
            dev_hold(skb->dev);
            __skb_queue_tail(&queue->input_pkt_queue, skb);
            local_irq_restore(flags);
            return NET_RX_SUCCESS;
        }
        netif_rx_schedule(&queue->backlog_dev);
        goto enqueue;
    }

    __get_cpu_var(netdev_rx_stat).dropped++;
    local_irq_restore(flags);
    kfree_skb(skb);
    return NET_RX_DROP;
}

 

 

netif_rx_schedule()触发网络软中断
--------------------------------------
netif_rx_schedule()-->
__netif_rx_schedule()-->
__raise_softirq_irqoff(NET_RX_SOFTIRQ)

 


/usr/src/linux-2.6.19/net/core/dev.c
int netdev_max_backlog = 1000;
阅读(1592) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~