Linuxのポーリング処理のコードを読んでみよう 〜初期化編〜
みんなの大好きなe1000のドライバから、ポーリング処理を追ってみようと思う。
カーネルのバージョンは、fxr.watson.orgに現時点で上がっている2.6.36-rc2。
但し、何故かnet/core/dev.cのページが破損してるので、その部分は配布ソースコードから。
252 module_init(e1000_init_module);
ここでe1000_init_module()がモジュールロード時に実行されるよう指定。
※資料: カーネルモジュール作成メモ
e1000_init_moduleでは
241 ret = pci_register_driver(&e1000_driver);
ここでe1000_driverを登録、e1000_driver.probeを呼ぶ。
193 static struct pci_driver e1000_driver = { 194 .name = e1000_driver_name, 195 .id_table = e1000_pci_tbl, 196 .probe = e1000_probe, 197 .remove = __devexit_p(e1000_remove), 198 #ifdef CONFIG_PM 199 /* Power Managment Hooks */ 200 .suspend = e1000_suspend, 201 .resume = e1000_resume, 202 #endif 203 .shutdown = e1000_shutdown, 204 .err_handler = &e1000_err_handler 205 };
e1000_driverはこの辺り。
e1000_driver.probeはe1000_probe()なのでこれが呼ばれる。
※資料:デバイスドライバロード時の動作 - や
e1000_probe()では各種初期化処理が行われてるけど、今回はここに注目。
888 netdev->netdev_ops = &e1000_netdev_ops; (中略) 891 netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
netdev->netdev_opsにe1000_netdev_opsを登録してから、NAPI周りの構造体初期化を行っている。
ハンドラとしてe1000_clean()を指定してる。
4つ目の引数のweight(ここでは64)は一回のポーリング数を決める為に使ってると思うんだけど、ここはちゃんと調べてない。
void netif_napi_add(struct net_device *dev, struct napi_struct *napi, int (*poll)(struct napi_struct *, int), int weight) { INIT_LIST_HEAD(&napi->poll_list); napi->gro_count = 0; napi->gro_list = NULL; napi->skb = NULL; napi->poll = poll; napi->weight = weight; list_add(&napi->dev_list, &dev->napi_list); napi->dev = dev; #ifdef CONFIG_NETPOLL spin_lock_init(&napi->poll_lock); napi->poll_owner = -1; #endif set_bit(NAPI_STATE_SCHED, &napi->state); } EXPORT_SYMBOL(netif_napi_add);
これが中身。見たところ、単にnapiの初期化かな。
772 static const struct net_device_ops e1000_netdev_ops = { 773 .ndo_open = e1000_open, 774 .ndo_stop = e1000_close, 775 .ndo_start_xmit = e1000_xmit_frame, 776 .ndo_get_stats = e1000_get_stats, 777 .ndo_set_rx_mode = e1000_set_rx_mode, 778 .ndo_set_mac_address = e1000_set_mac, 779 .ndo_tx_timeout = e1000_tx_timeout, 780 .ndo_change_mtu = e1000_change_mtu, 781 .ndo_do_ioctl = e1000_ioctl, 782 .ndo_validate_addr = eth_validate_addr, 783 784 .ndo_vlan_rx_register = e1000_vlan_rx_register, 785 .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid, 786 .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid, 787 #ifdef CONFIG_NET_POLL_CONTROLLER 788 .ndo_poll_controller = e1000_netpoll, 789 #endif 790 }; 791
e1000_netdev_opsではe1000_netdev_ops.ndo_openにe1000_open()が登録されてる。
コメントによると、これはネットワークインタフェースがアクティブになった時に呼ばれるっぽい。
e1000_open()では、割り込みの有効化が行われる。
1283 err = e1000_request_irq(adapter);
e1000_request_irq()はrequest_irq()を呼び出して、割り込みハンドラにe1000_intr()を登録。
268 static int e1000_request_irq(struct e1000_adapter *adapter) 269 { 270 struct net_device *netdev = adapter->netdev; 271 irq_handler_t handler = e1000_intr; 272 int irq_flags = IRQF_SHARED; 273 int err; 274 275 err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name, 276 netdev);
e1000_open()に戻る。
1290 napi_enable(&adapter->napi); 1291 1292 e1000_irq_enable(adapter);
NAPIと割り込みを有効化してる。
462 static inline void napi_enable(struct napi_struct *n) 463 { 464 BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state)); 465 smp_mb__before_clear_bit(); 466 clear_bit(NAPI_STATE_SCHED, &n->state); 467 }
なんかイマイチよくわからないが、napiのステートを変更してるだけだろう。
めちゃめちゃ飛ばしまくったけど初期化は大体こんなもん。