こんにちは、いつもお世話になっています、伊藤です。 ちょっと長文ですが、おつき合い頂ければと思います。
bgeドライバのパッチを作成して、send-prしたのですが、 私の英語が拙いせいか、あまり相手にしてもらえないので どなたか、応援をお願いしたいのですが。 http://www.freebsd.org/cgi/query-pr.cgi?pr=98738 「bgeドライバの問題について」 5.5-RELEASE(i386), 7.0-CURRENT(i386),おそらく、6.X(i386)も 同様だと思うのですが、SMPカーネル + マルチプロセッサ(HTT でも可)という環境において、 複数のプロセスが同時に、bgeドライバを通してNICのリンクステータ スを取得しようとした場合、リンク状態が正常であるにも関わらず、 ごくまれに異常を返すという現象を確認しています。 具体的には、ifconfig コマンドを同時に複数実行した場合、非常にまれ ですが、statusフィールドが "no carrier"を返して来るケースがあります。 (正常であれば、"active"となる。) カーネルオプションから、 "option SMP" を抜いたカーネルでは この現象が発生しないことから、ドライバのソースを追ったところ、 リンク状態を取得する処理にロックが掛けられていなかったため、 ロックを掛ける処理を追加したところ、現象は発生しなくなりました。 「再現させるためには」 (1)SMPカーネルを使う。 (2)マルチプロセッサもしくは、HTTで論理CPUを2つに設定する。 (3)bgeドライバを使用するNICを用意し、HUBに差しリンク状態を正常にする。 (4)以下のシェルスクリプトを2つ、同時に実行する。 タイミングさえ合えば、以下の様にぐるぐる回さなくても良いと思うんですが、 かなり微妙なタイミングなので、回しちゃってます。 #!/bin/csh while 1 set aaa=`ifconfig bge0 | grep active | wc -l` if ($aaa == 1) then echo "bge0 Link OK" else echo "bge0 Link NG" exit endif end (5)しばらく待っていると、"bge0 Link NG"のメッセージが表示される。 ちなみに、fxpや、emでは、こういった現象は発生しませんでした。 「パッチに関して」 要は、 case SIOCGIFMEDIAの処理を、BGE_LOCKと、BGE_UNLOCKで 囲んだだけです。 *** if_bge.c.orig Fri Jun 9 14:34:29 2006 --- if_bge.c Fri Jun 9 14:34:58 2006 *************** *** 3325,3330 **** --- 3325,3331 ---- break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: + BGE_LOCK(sc); if (sc->bge_tbi) { error = ifmedia_ioctl(ifp, ifr, &sc->bge_ifmedia, command); *************** *** 3333,3338 **** --- 3334,3340 ---- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); } + BGE_UNLOCK(sc); break; case SIOCSIFCAP: mask = ifr->ifr_reqcap ^ ifp->if_capenable; 「その他」 bgeと、emでリンク状態の取り出し時間を計ってみると、 emの方が10倍程速いです。 処理的には、NICからステータスを取り出すだけなので あまり差異はないと思っていたんですが。 ちょっと不思議です。(mii 側に処理があるからかなぁ。)