[ - ]
CODE:二、netif_rx
netif_rx有两个很重要的工作:
1、把backlog_dev加入进设备列表;
2、把从网卡驱动接收来的数据添加进接收包队列中; [Copy to clipboard]
[ - ]
CODE:int netif_rx(struct sk_buff *skb)
{
int this_cpu;
struct softnet_data *queue;
unsigned long flags;
/* if netpoll wants it, pretend we never saw it */
if (netpoll_rx(skb))
return NET_RX_DROP;
/*如果没有设置接收的时间,更新之*/
if (!skb->stamp.tv_sec)
net_timestamp(&skb->stamp);
/*
* The code is rearranged so that the path is the most
* short when CPU is congested, but is still operating.
*/
local_irq_save(flags);
this_cpu = smp_processor_id();
/*取得当前CPU的队列*/
queue = &__get_cpu_var(softnet_data);
/*接收计数器累加*/
__get_cpu_var(netdev_rx_stat).total++;
/*队列总数没有超过定义的最大值*/
if (queue->input_pkt_queue.qlen input_pkt_queue.qlen) {
if (queue->throttle)
goto drop;
enqueue:
dev_hold(skb->dev);
/*将数据包入队,并累加队列计算器*/
__skb_queue_tail(&queue->input_pkt_queue, skb);
#ifndef OFFLINE_SAMPLE
get_sample_stats(this_cpu);
#endif
local_irq_restore(flags);
return queue->cng_level;
}
if (queue->throttle)
queue->throttle = 0;
/*将backlog_dev设备添加进设备列表,并进一步入理*/
netif_rx_schedule(&queue->backlog_dev);
goto enqueue;
}
if (!queue->throttle) {
queue->throttle = 1;
__get_cpu_var(netdev_rx_stat).throttled++;
}
drop:
/*丢弃数据包,先累加计数器,再释放skb*/
__get_cpu_var(netdev_rx_stat).dropped++;
local_irq_restore(flags);
kfree_skb(skb);
return NET_RX_DROP;
}
[color="Red"]三、netif_rx_schedule [Copy to clipboard]
[ - ]
CODE:static inline void netif_rx_schedule(struct net_device *dev)
{
if (netif_rx_schedule_prep(dev))
__netif_rx_schedule(dev);
}
netif_rx_schedule函数只是一个包裹函数,它将主动权交到了__netif_rx_schedule手中: [Copy to clipboard]