igb(4)を理解する為にデータシートを読む(RSSハッシュテーブルの初期化と書き換え)
前の記事と同じくigb_initialize_receive_unitsをみると、RETAというところへ書き込んでいる:
union igb_reta { u32 dword; u8 bytes[4]; } reta; /* Warning FM follows */ for (int i = 0; i < 128; i++) { reta.bytes[i & 3] = (i % adapter->num_queues) << shift; if ((i & 3) == 3) E1000_WRITE_REG(hw, E1000_RETA(i >> 2), reta.dword); }
データシートをみると、8.10.22にRedirection Table - RETAに関する説明がある。
1エントリ1byteな128エントリのテーブルがあって、テーブルのインデックス値はハッシュ値の1-4bit(1オリジンで言ってる?0-3bitの事?)だけを使う。
エントリ内のキュー番号は0-3bitだけを使う。
FreeBSDのコードでigb_retaがu8 bytes[4]としているのは、レジスタの書き換え単位が1byteではなくて4byteだからだと思われる。
なのでちょっとコードがややこしいが、要するに初期値の値を0からキュー数-1でシーケンシャルに散らしてあげる事で、複数のキューへパケットがバラけるようになるという事のようだ。
ここで各エントリの値を全て同じにすると、一つのキューに集中してパケットが届くようになり、一つのCPUにだけ割り込みが入るようになるはずだ。