[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: fxp at pci on arm32 and bus_dmamap_sync()



<200007191055.e6JAtYd02329@mirage.ceres.dti.ne.jp>の記事において
私は書きました。

> で、これとは別に、いろいろとマニュアルその他を調べたところ
> なんとなく問題の本質がわかってきたような気がしてます。

ということで続きです。

いろいろ探したところいくつかのマニュアルは
http://developer.intel.com/design/network/datashts/index.htm
にありました。i82557 の RFA 等の構成は 82596 と互換ということで
探すと i82596 のマニュアルには一応それらしい内容が載っていました。
ftp://download.intel.co.jp/design/network/datashts/29021906.pdf

通常 network driver の受信バッファは受信のステータスや
バッファアドレスを格納する descriptor 部分と実際に
データを受信するバッファ部分の 2つからなりますが、
fxp ではこの 2つを連続した一つの領域にとる必要があります。
(ex や tlp ではこれらは別々のメモリに取られる)

で、fxp では先頭のバッファアドレスについては scb レジスタ内の
値を FXP_SCB_COMMAND_RU_START を使って設定し、続くバッファは
バッファ内の RFA の link_addr で指定します。
最後のバッファの link_addr には何を指定すべきなのかは
マニュアルに書いてないんですが i82557.c では 0xffffffff を
指定してます。

これらの受信バッファの割り当てが固定であればこれで
問題ないんですが、 BSD だと受信バッファは mbuf に
割り当てられるのでバッファは受信が終わったそばから
更新されていきます。 fxp だと descriptor の RFA も
mbuf 内にあるので FXP_SCB_COMMAND_RU_START で指定した
descriptor のアドレスはすぐに無効なものになってしまいます。

i82557.c では、受信処理が終わって次のバッファを確保したら
最後のバッファの後ろに新しいバッファを足すということを
していますが、バッファの確保がパケットの受信に追い付かず
最後のバッファまで使ってしまった場合は次のバッファの
link_addr として 0xffffffff が読まれることになります。
このときにどういう動作になるのかはマニュアルを見ても
よくわからないんですが、ここでもし FXP_SCB_COMMAND_RU_START で
指定したアドレス(つまりバッファ先頭)にアクセスに行っていると
したら、そこはすでに m_freem() されているでしょうから
のちのち free list modified の panic を引き起こすことになります。

#no resources の時に ABORT すると panic が起こらなくなると
#いうのはこの推定の裏付けになるんじゃないかと思ってるんですが……

ようするに i82557 の構成が固定受信バッファを前提としているのに
fxp driver ではむりやり mbuf を使った構成としているので、
受信バッファ確保が追い付かないと変なことが起こるのではないかという
気がしてます。

少なくとも FXP_SCB_COMMAND_RU_START で指定したアドレスが
いつまでも古い無効になったバッファを指したままというのは変なので、
fxp_intr() の rcvloop 中の IF_DEQUEUE() で受信済みのバッファを
キューから取り出したら毎回受信バッファの先頭アドレスを
キューの新しい先頭バッファのアドレスに指定し直す必要があると
思うんですが、どうも先頭アドレスは受信バッファの初期化時にしか
設定できないような感じなのでなんともしようがありません。

というわけで、まだマニュアルをじっくり読んだわけではないんですが、
(世間の評判に反して)fxp は BSD には向かないんじゃないかという
後ろ向きな考えになりつつあります。現在使われてない
Flexible memory structure とか使うとうまいこと書けるのかも
しれませんが……

#と、こんなややこしいこととても英語では説明できない……
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp