は、ユーザプログラムでこの同時DMAユーザメモリに
スレッド1を考えてみましょう:
buf = malloc(9000);
memset(buf, 0xee, 9000);
read(buf, 9000); //for example gives pages [part of 7, 8, 9, part of 10]
スレッド2をユーザプログラムで:
buf = malloc(9000); //for example gives pages [part of 4, 6, 5, part of 7]
memset(buf, 0xee, 9000);
read(buf, 9000);
ドライバーが読み込ま:
get_user_pages();
//build dma sg list from pages
//...
//the platform demands a cachesync
for(all pages) {
dma_cache_wback_inv();
}
//start dma and wait for it to be done
//...
wait_event_interruptible_timeout(); //blocks calling thread until dma done
for(all pages) {
if(read) SetPageDirty();
page_cache_release();
}
ページ7は両方ともそれは時々悪いデータ(0xeeは1つのbufの最後にあります)をもたらす大きな問題でした。ちょうどそれを明確にするために、2つの読み取りは異なるDMAチャンネル上で実行されるので、同時に実行することができます。
私の解決策は、2つのドライバDMAが同じページの部分を共有しないように、ユーザプログラムのバッファをページアラインすることでした。
これには別の解決方法があるのだろうか? 私はまた、なぜこれが大きな問題であったのだろうかと思います。
これはおそらくプラットフォーム固有のものです。キャッシュを無効にする必要があると、組み込みシステムで実行されていることが示唆されます。 2つのバッファがキャッシュラインを共有するのに十分近いか、またはプラットフォームの正誤表に他の制限がありますか? –
はい、それはppc440epなので、バッファはおそらく十分に近いでしょう。キャッシュラインは32バイトで、4〜12バイトが壊れている/変更されていないことがわかりました。同じ物理メモリの2つの異なるバージョンがキャッシュに存在することはできますか?そして、私が1つのスレッドで折り返しをすると、他のスレッドのデータを破棄できますか?私が知る限りでは考えられないerratasはありません。しかし、get_user_pagesはどうですか?同じページの2つの異なるバージョンを返すとどうなりますか?異なるスレッドからのget_user_pagesとpage_cache_releaseがインターリーブされる場合。 – Ronnie
私はページに物理的なアドレスを与える以外は、get_user_pages/page_cache_releaseの機能を完全には明らかにしていません。このシステムにはディスクキャッシュなど何もありません。メモリとCPUキャッシュのみがあります。 – Ronnie