[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.
 				 */