[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: fxp at pci on arm32 and bus_dmamap_sync()
筒井です。
In <200005311310.e4VDAmc03705@mirage.ceres.dti.ne.jp>
I wrote:
> NetBSD/arm32 (20000520 あたりの current) の CATS で
> Intel Etherexpress PRO/100+ を使おうとしているんですが、
> しばらく負荷をかけていると下記のように panic してしまいます。
> panic: pool_get(mclpl): free list modified: magic=a020beef; \
> page 0xf37ec000; item addr 0xf37ec000
この件ですが、色々調べていたら port-arm32 で過去に話が出ていました。
http://mail-index.netbsd.org/port-arm32/1999/11/08/0000.html
これによると _bus_dmamap_sync() で POSTREAD/POSTWRITE 時にも
cache flush をしてやると動くようになるということでした。
また、 write buffer は cache と memory の間にあるので
write buffer drain は cache flush 後に行うのが正しい、
という結論でした。
DMA 終了後にも cache flush するというのはやはり変な気がするので
さらにいろいろ調べてみたんですが、どうも fxp_intr() の中で
受信ステータスの RFA を複数回参照しているのが原因のようです。
fxp_intr() の受信割り込み処理ではパケット受信完了の判定のために
rfa->rfa_status の FXP_CB_STATUS_C をチェックしているんですが、
この時点で RFA のメモリの内容が CPU の cache に乗ってしまいます。
ここでフラグが立っていなかった場合は、 fxp が受信完了した時点で
rfa_status を DMA で書き換えることになりますが、古い RFA の内容が
cache に残っていると次回 rfa->rfa_status がチェックされる時に
更新された新しい値が読めない場合がある、ということのようです。
受信未完了だった場合に FXP_RFASYNC() を呼ぶようにしてやると
今のところ panic することなくまともに動いているようです。
(patch 添付)
DMA でパラメータ転送する場合のメモリは通常 bus_dmamem_alloc() で
メモリ確保して、 BUS_DMA_COHERENT を指定して bus_dmamem_map()
するのでたいてい cache 無効になっているんですが、 fxp の RFA の場合は
fxp の仕様の都合上通常の mbuf 中のメモリをパラメータ転送に使っており、
その場合は cache が有効なので bus_dmamap_sync がシビアに要求される
ということのようです。
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp
--- i82557.c.orig Sun Jun 4 10:46:10 2000
+++ i82557.c Sun Jun 4 10:46:14 2000
@@ -916,6 +916,11 @@
if ((rxstat & FXP_RFA_STATUS_C) == 0) {
/*
+ * RFA will be updated later by fxp
+ * so we need to sync it.
+ */
+ FXP_RFASYNC(sc, m, BUS_DMASYNC_PREREAD);
+ /*
* We have processed all of the
* receive buffers.
*/