著作一覧 |
さて、試してみたが、まずわかったことは、Flow Controlの設定項目それ自体は無関係だったようだ(全部を調べる気はないので、推測も多い)ということだ。
関係するのは、Large Send Offload(IPv4) で、この設定がDisableならOK、EnableならNGとなる。いじった覚えはないが、この設定も変えたり戻したりしたみたいだ。既定値がEnableだったのを、Flow Controlと一緒にDisableにして、また戻してしまったのだろう。そうでないと話が合わない。
では、この設定はいったいなんだろう? と調べるとWindows2000の資料が見つかった。Windows のネットワーク タスク オフロード
オフロードというのは、取り除くというような意味だけど、ネットワーク用語としては、「による負荷軽減」あたりで、目的指向な言葉(と思う)。したがって、上のページは、ネットワークにつきもののタスク負荷の軽減、という感じ。Large Send Offloadは、大量送信による負荷軽減というところなのかな?
この状態では、一瞬ネットワーク負荷が100%になる(タスクマネージャによる観察)。
現在は、Large Send Onloadを無効化し、逆にFlow Controlも無効化している。
では、Large Send Onloadが有効なとき、どのようなパケットがプリンタ(の手前のAirMac Expressの手前のスィッチの手前のMAC層のドライバ)に対して流されたのかを見てみる。
以下、mondeはVista SP1マシン、HP9B01E2がプリンタ(の手前のスィッチ——どのノードが問題なのかはここではわからないので置いておく。あと、実際にアダプタが投げているMAC層でのパケットと等しいかどうかは別問題なので、さらに中でまずいことが起きているかも知れない。WinPCapはNDISミニポートドライバだから、アダプタ用ドライバが受けるものと同じものを見ているけど、それはアダプタが実際に送り出すものとは異なる可能性がある)。
23:50:55.390252 IP monde.51264 > HP9B01E2.9100: S 24773620:24773620(0) win 8192どうやら、これがプリント開始の合図らしい。23:50:55.392091 IP HP9B01E2.9100 > monde.51264: S 2545482788:2545482788(0) ack 24773621 win 17520 23:50:55.392171 IP monde.51264 > HP9B01E2.9100: . ack 1 win 16425
23:50:57.478816 IP monde.51264 > HP9B01E2.9100: P 1:1201(1200) ack 1 win 16425 23:50:57.481202 IP HP9B01E2.9100 > monde.51264: . ack 1201 win 16320 23:51:07.139398 IP monde.51264 > HP9B01E2.9100: P 1201:1654(453) ack 1 win 16425 23:51:07.141130 IP HP9B01E2.9100 > monde.51264: . ack 1654 win 15867ここまでは順調に見える。
23:51:07.544423 IP monde.51264 > HP9B01E2.9100: P 1654:5750(4096) ack 1 win 16425 ※1 23:51:07.837354 IP monde.51264 > HP9B01E2.9100: . 1654:3114(1460) ack 1 win 16425 ※2 23:51:08.438426 IP monde.51264 > HP9B01E2.9100: . 1654:3114(1460) ack 1 win 16425 23:51:09.638487 IP monde.51264 > HP9B01E2.9100: . 1654:2190(536) ack 1 win 16425 23:51:10.838539 IP monde.51264 > HP9B01E2.9100: . 1654:2190(536) ack 1 win 16425 23:51:12.042610 IP monde.51264 > HP9B01E2.9100: . 1654:3114(1460) ack 1 win 16425 23:51:14.442746 IP monde.51264 > HP9B01E2.9100: . 1654:3114(1460) ack 1 win 16425
※1。これで相手は死んだらしい。
※2。以降、徐々にサイズを小さくしながらリトライ。間隔については300ms、600ms、1.2sという倍増をしている。
23:51:14.460959 IP HP9B01E2.9100 > monde.51264: . ack 3114 win 17520やっとACKが来た(1460が気に入ったようだ)。
23:51:14.461010 IP monde.51264 > HP9B01E2.9100: P 3114:5750(2636) ack 1 win 16425 23:51:14.752775 IP monde.51264 > HP9B01E2.9100: . 3114:4574(1460) ack 1 win 16425 23:51:15.352800 IP monde.51264 > HP9B01E2.9100: . 3114:4574(1460) ack 1 win 16425 23:51:16.552874 IP monde.51264 > HP9B01E2.9100: . 3114:4574(1460) ack 1 win 16425 23:51:18.953010 IP monde.51264 > HP9B01E2.9100: . 3114:4574(1460) ack 1 win 16425 23:51:23.753277 IP monde.51264 > HP9B01E2.9100: . 3114:4574(1460) ack 1 win 16425 23:51:23.943744 IP HP9B01E2.9100 > monde.51264: . ack 4574 win 17520最初の2636バイトのパケットから数えると9秒たっている。
23:51:23.943794 IP monde.51264 > HP9B01E2.9100: P 4574:5750(1176) ack 1 win 16425 23:51:23.946252 IP HP9B01E2.9100 > monde.51264: . ack 5750 win 16344あっさり、クリア。
23:51:23.946354 IP monde.51264 > HP9B01E2.9100: . 5750:8670(2920) ack 1 win 16425 (なぜ、ここでまた2920とか?) 23:51:28.943574 IP monde.51264 > HP9B01E2.9100: . 8670:9258(588) ack 1 win 16425 23:51:42.844372 IP monde.51264 > HP9B01E2.9100: . 5750:7210(1460) ack 1 win 16425 23:51:43.043423 IP HP9B01E2.9100 > monde.51264: . ack 7210 win 17520 23:51:43.043483 IP monde.51264 > HP9B01E2.9100: P 7210:9846(2636) ack 1 win 16425 (また……) 23:52:39.727630 IP monde.51264 > HP9B01E2.9100: . 7210:8670(1460) ack 1 win 16425 23:52:39.925685 IP HP9B01E2.9100 > monde.51264: . ack 8670 win 17520
最後、ここで完全にだんまりになる箇所まで飛ばす。
23:54:40.323500 IP HP9B01E2.9100 > monde.51264: . ack 12766 win 17520 23:54:40.323559 IP monde.51264 > HP9B01E2.9100: P 12766:13942(1176) ack 1 win 16425 23:54:40.325497 IP HP9B01E2.9100 > monde.51264: . ack 13942 win 16344 23:54:40.325615 IP monde.51264 > HP9B01E2.9100: . 13942:16862(2920) ack 1 win 16425 23:54:45.324828 IP monde.51264 > HP9B01E2.9100: . 16862:17450(588) ack 1 win 16425
一度減ったサイズが常に戻っている。というか、開始してから既に3分経過している。どうも、再試行の結果、プリンタからACKを受けるまでが長すぎて、(別のタイマーで見ているのではなかろうか?)送信サイズがリセットされて同じことを繰り返しているように見える。
あと、サイズを小さくしたときに、PUSHを立てていないのが気になる。これはバグではないか? というか、ずばりバグだろう。PUSHを立てていないのに、後続のパケットを出さずにACKを待っているように振舞っている。したがって、ラージサイズパケットに対してACKを返さない相手と通信するときは、かならず再試行間隔が増えていって、相手が次はまだかと督促するまで待たされているように見える。
一方、Large Send Offloadを無効化した場合は、以下となる。
23:39:35.060059 IP monde.51258 > HP9B01E2.9100: S 954832284:954832284(0) win 819223:39:35.061743 IP HP9B01E2.9100 > monde.51258: S 2372987788:2372987788(0) ack 954832285 win 17520 23:39:35.061801 IP monde.51258 > HP9B01E2.9100: . ack 1 win 16425 (プリント開始指令と思われるものの完了) 23:39:37.038068 IP monde.51258 > HP9B01E2.9100: P 1:1201(1200) ack 1 win 16425 23:39:37.039856 IP HP9B01E2.9100 > monde.51258: . ack 1201 win 16320 23:39:46.780639 IP monde.51258 > HP9B01E2.9100: P 1201:1654(453) ack 1 win 16425 23:39:46.782919 IP HP9B01E2.9100 > monde.51258: . ack 1654 win 15867 23:39:47.175701 IP monde.51258 > HP9B01E2.9100: . 1654:3114(1460) ack 1 win 16425 23:39:47.175737 IP monde.51258 > HP9B01E2.9100: . 3114:4574(1460) ack 1 win 16425 23:39:47.175751 IP monde.51258 > HP9B01E2.9100: P 4574:5750(1176) ack 1 win 16425 23:39:47.180340 IP HP9B01E2.9100 > monde.51258: . ack 5750 win 13424
という具合に、万事快調に進む。PUSHビットも適当(最適かどうかはわからないが)に立てられている。
TSOは、ソフトウェアのレイヤ(TCP/IPの部分)で、いちいちパケットの分割とかチェックサムの計算とかしないで、NICにお任せすることでギガビットイーサの処理に間に合わせるようにするということだ、ということがわかった。
VistaのTCP/IPの実装は、正しくTSOを処理していると考えてみる。そして、IntelのNDISドライバ(なのかNICのファームなのか)も正しく実装しているとする。とすると、4000バイトとかWinDumpでは出ていても、実際にはLANに対しては適切な長さで切られたパケットが送られていると推測する。
でも、それだと3分割で済み、かつ最後のパケットにPUSHが立つのでACKが返ってこないのはおかしい。
ということは、NICのファーム(またはIntelのNDISドライバ)がおかしくて、正しく分割していないのではないか、と推測できる。
まず、SP1で有効にされたというところから、実態は次のいずれかではないかと想像する。
1. x86のNICドライバで対応。x64はだめ。
2. オートネゴシエーション結果、ギガビットイーサと判定したら正しく動く。それ以外の場合は、上位層にお任せ。
1.だったら、しょうがないけど、意味的にCPU負荷を少しでも減らしたいとしたらサーバーだろうから、x64のドライバがだめということはありうるのかなぁ?
2. だったら、お金で解決だ。スィッチの買い替えということ。
でも、ギガビットな人って、他にいないしなぁ、と考えると、やはりLarge Send Offloadを無効にするのが正しいな。
でも、待てよ。まだ届いていないが、タイムリーなことに、
Apple Time Capsule 500GB MB276J/A(-)
を買ったんだった。こいつはギガビットイーサの口を持っている。
というわけで、届いたら試してみよう。(もっとも802.11gのプリンタ相手にギガビットもへったくれもないけど、NASとしての利用時には恩恵に預かれそうだし)
tcpdumpと同じはずだけど、よく忘れるのでメモ。
WinDump -D
インターフェイスをプリントする。
WinDump -XX
ヘッダ情報とデータのHEXとASCIIをプリントする。
WinDump -xx
ヘッダ情報とデータのHEXをプリントする。
WinDump -i xxxx
インターフェイスxxxxを取る。そうでないと適当なのが選ばれる。
WinDump -w xxxxx
ファイルxxxxへキャプチャを書き出す(生データなので、-XXみたいなことをするには、後でWinDump -r xxxx -XXのように読み出して行う)
例)
>windump -D
1.\Device\NPF_{73F0A8D8-4679-45FF-9748-16EF29A9B2FE} (Intel(R) PRO/1000 MT Server Connection)
2.\Device\NPF_{838F3C6C-3C64-4E55-A701-A7882BAD642F} (MS Tunnel Interface Driver)
例)
>windump -i \Device\NPF_{73F0A8D8-4679-45FF-9748-16EF29A9B2FE} -XX -s 256 tcp port 9100 >\temp\ng.dump
思い立ってクラシックのコレクションを捨てまくろうとして、とはいうものの、音楽は残しておきたいので、金曜の夜からPowerBookを使ってiTunesへばんばん取り込んだ。
でだ。夜中作業だから音は出してなかったんだよ。
最初に異変に気づいたのは土曜の夕方頃、ブーレーズのバルトーク(舞踏組曲)を聴いているときだ。
最後の、トゥッティが、突然切れた。ほえ?
あわてて、チェックしてみると、どれもこれも最後の最後で切れる。
響きが残るやつは響きが打ち切り。これは気分悪いが、でもまだ許せる。しかし、バルトークのにしろ、ブルックナーの8番にしろ、最後のトゥッティが切れるのは問題外だろう。
というわけで、すさまじく不快になる。バグでここまで不快な気分になったのは初めてかもしれない。
・デグレ未満(それまでなかったバグ)
・テストすれば明らか(聴けばわかるぞ)
・時間がかかる(というか、一部のCDはゴミ箱から拾い出す必要まであって、これはこれでうんざりだった)作業が無駄になる
・しかも、Win32版なら、いつものことだと思うだけだが、OS X版だ(というか、わざわざ大事を取って、環境を作ったのだ。これも不快100倍増の理由)
・コンシューマ用プログラム
まったく、Appleってのはハードウェア屋で、ソフトがくそだということを思い知らされた。ロジクールや、メルコのドライバみたいなものだな。
むかむかぷんぷん。
というか、音楽を不快な方法で破壊されたから、不快度100倍増なんだな。
ジェズイットを見習え |