2012-03-02 6 views
1

は、ユーザプログラムでこの同時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が同じページの部分を共有しないように、ユーザプログラムのバッファをページアラインすることでした。

これには別の解決方法があるのだろうか? 私はまた、なぜこれが大きな問題であったのだろうかと思います。

+1

これはおそらくプラットフォーム固有のものです。キャッシュを無効にする必要があると、組み込みシステムで実行されていることが示唆されます。 2つのバッファがキャッシュラインを共有するのに十分近いか、またはプラットフォームの正誤表に他の制限がありますか? –

+0

はい、それはppc440epなので、バッファはおそらく十分に近いでしょう。キャッシュラインは32バイトで、4〜12バイトが壊れている/変更されていないことがわかりました。同じ物理メモリの2つの異なるバージョンがキャッシュに存在することはできますか?そして、私が1つのスレッドで折り返しをすると、他のスレッドのデータを破棄できますか?私が知る限りでは考えられないerratasはありません。しかし、get_user_pagesはどうですか?同じページの2つの異なるバージョンを返すとどうなりますか?異なるスレッドからのget_user_pagesとpage_cache_releaseがインターリーブされる場合。 – Ronnie

+0

私はページに物理的なアドレスを与える以外は、get_user_pages/page_cache_releaseの機能を完全には明らかにしていません。このシステムにはディスクキャッシュなど何もありません。メモリとCPUキャッシュのみがあります。 – Ronnie

答えて

1

これは、埋め込みプロセッサとキャッシュの一貫性のないDMAの制限です。ハイエンドのPowerPCチップでは、この問題は解消されます。

あなたの2つのバッファは、満たすポイントでキャッシュラインを共有します。 1つのスレッドがドライバにキャッシュにRAMを書き込むと同時に、2番目のスレッドはmemsetにあり、キャッシュラインに0xeeを埋め込みます。

DMA 1はデータをRAMに書き込みますが、プロセッサはそのデータに対して0xeeを含むダーティキャッシュラインを保持しています。 2番目のスレッドがキャッシュを書き出すと、DMA1からのデータに0xeeが書き込まれます。

解決策は以下のとおりです。

  1. あなたのバッファ(最高のパフォーマンスを)キャッシュ-揃えます。
  2. カーネルドライバでバウンスバッファを使用します(ほとんどの場合、既存のユーザースペースコードと互換性があります)。

get_user_pages()は、ハードウェアとタイミングに関する問題の一部ではありません。

+0

私はあなたがキャッシュの問題をbeeingそれについて右だと思うが、私はmemsetを使用せずにエラーを見たと思うが、この問題をデバッグする前にmemsetがなかったので...しかし、DMA 1が完了した後、キャッシュはDMA 2が完了する前にキャッシュに0xeeを読み戻しますか? – Ronnie

+0

'malloc'は、ヒープメンテナンスのためにバッファの両端のデータにも触れます。それで十分かもしれません。 –

+0

はい、これは説明のようです。 – Ronnie