How to 'receive' SKB how to organize the received SKBs ???
1.
The function : netif_rx(struct sk_buff *skb) do this work, so every network driver needs this function !!!
2.
In the beginning of this function is the checking of
netpoll mechanism, while we'll not discuss netpoll in this paper, so
we'll ignore it. Just go on!
3.
Now, this function will set the timestamp for this
SKB buffer, it calls function : net_timestamp(skb) to set
the skb->tstamp's value !!!
4.
Now the wonderful things is coming here : the receive queue and the softIRQ.
4.1 the receive queue definition
the definition : struct softnet_data *queue;
/*
* Incoming packets are placed on per-cpu queues so that
* no locking is needed.
*/
struct softnet_data
{
struct net_device *output_queue;
struct sk_buff_head input_pkt_queue;
struct list_head poll_list;
struct sk_buff *completion_queue;
struct net_device backlog_dev; /* Sorry. 8) */
};
So what can we concluded from its definition ???
SKBs are queued into the list input_pkt_queue.
Notice : Each CPU has its own queue so no locking mechanism is needed.
4.2 push SKB into receive queue
This function first check the receive queue's
length, if the qlen is bigger than or equal to netdev_max_backlog, then
updating the dropped statistics and free the SKB, return the
NET_RX_DROP; else if the qlen equal 0, this function will call
netif_rx_schedule() function first and then put the SKB into the
receive queue; else if the qlen is bigger than 0 then this function
will call function __skb_queue_tail() directly to put the SKB into the
queue tail, then return NET_RX_SUCCESS.
Notice : the SKB can not be freed when this function return NET_RX_SUCCESS.
4.3 the soft IRQ
The soft IRQ is drived by netif_rx_schedule(struct net_device *dev);
If the dev is running and its is not scheduled, then
the netif_rx_schedule() calls __netif_rx_schedule(dev) function. And
then the function __netif_rx_schedule() set the dev->quota value to
64 and insert the dev->poll_list to receive queue's poll_list, then
it raise the soft IRQ : NET_RX_SOFTIRQ.
This soft IRQ(NET_RX_SOFTIRQ) is handled by function : net_rx_action().
The net_rx_action() then calls process_backlog() to handle the SKB in the receive queue.
4.4 The process_backlog() function
This function is simple, it main framework is a
forever loop. It fetches each SKB from the receive queue and calls
function : netif_receive_skb() to handle it!
The function netif_receive_skb() do the real work of putting the SKB to IP layer and we'll discuss it next.
阅读(1197) | 评论(1) | 转发(0) |