Driver/snull/snull_poll()

Last-modified: 2007-09-11 (火) 13:52:17

284 :/*
285 : * The poll implementation.
286 : */

p536 割り込み受信の軽減を参照
基本の処理をパケットを保持するためのskbの作成
snull_rxと似ている

287 :static int snull_poll(struct net_device *dev, int *budget)
288 :{
289 : int npackets = 0, quota = min(dev->quota, *budget);
290 : struct sk_buff *skb;
291 : struct snull_priv *priv = netdev_priv(dev);
292 : struct snull_packet *pkt;
293 :
294 : while (npackets < quota && priv->rx_queue) {
295 : pkt = snull_dequeue_buf(dev);

パケットを待ち列から取得する

296 : skb = dev_alloc_skb(pkt->datalen + 2);

パケットを保持するためのバッファをアロケートする

297 : if (! skb) {

バッファのアロケートができなければ

298 : if (printk_ratelimit())

メッセージを少なくする

299 : printk(KERN_NOTICE "snull: packet dropped\n");

300 : priv->stats.rx_dropped++;

とりこぼされた数を統計システムで更新

301 : snull_release_buffer(pkt);

パケットのリリース

302 : continue;
303 : }
304 : skb_reserve(skb, 2); /* align IP on 16B boundary */

skbのアラインメントをあわせる、dev_alloc_skbではあわせてくれないらしい。

305 : memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen);

パケット内容をskbにコピーする

306 : skb->dev = dev;
307 : skb->protocol = eth_type_trans(skb, dev);
308 : skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */

306~308はskbの内容を設定する

309 : netif_receive_skb(skb);

パケットをskb経由でカーネルに引き渡す

310 :
311 : /* Maintain stats */

統計処理

312 : npackets++;
313 : priv->stats.rx_packets++;
314 : priv->stats.rx_bytes += pkt->datalen;
315 : snull_release_buffer(pkt);
316 : }
317 : /* If we processed all packets, we're done; tell the kernel and reenable ints */
318 : *budget -= npackets;

受け取ったパケットの分だけbudgetを減らす。CPUに割り当てられている許可受けとりパケット数

319 : dev->quota -= npackets;

受け取ったパケットの分だけquotaを減らす。インタフェースに割り当てられている許可受け取りパケット数。

320 : if (! priv->rx_queue) {

rx_queueがなければ

321 : netif_rx_complete(dev);

ポーリングをオフにする

322 : snull_rx_ints(dev, 1);
323 : return 0;
324 : }
325 : /* We couldn't process everything. */
326 : return 1;
327 :}