Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Coherence 問題とは何か)







# はじめに


Linux では DMA Bufferを mmap した時に、ある条件が揃うと CPU Cache が無効になり、パフォーマンスが極端に落ちる場合があります。そこで、何故そのようなことが起こるのか説明します。少し長くなるので、次のように記事を幾つかに分けて投稿します。



1. [はじめに]
2. Cache Coherence 問題   
2.1  __Cache Coherence 問題とは何か(この記事)__   
 2.2 [Cache Coherence 問題の解決方法]
3. [Cache Aliasing 問題]
4. [Linux Kernel の Cache 問題の扱い]
5. [Linux では Cache Coherence Hardware を持っていないとDMA Buffer をmmap する際に CPU Cache が無効になる]
6. [Raspberry Pi の例]
7. [RISC-V CPU の注意点]
8. [所感]



1〜3は、コンピューターアーキテクチャの基本的な事項を、簡単に説明したものです。すでにご存じの方は読み飛ばしてください。

4 はこれらの問題を Linux Kernel 内でどのように扱っているかを説明します。

5 がこれらの記事群の結論です。結論だけ知りたい方はここだけ読んでください。



この記事では「Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある」原因の一つである Cache Coherence 問題とは何かを説明します。すでにご存じの方は読み飛ばしてください。


# Cache Coherence 問題とは何か


Cache Coherence 問題は一言でいえば CACHE と MEMORY とのデータの一貫性(Coherence) の問題です。

なお、厳密に言えば、Cache Cohrence 問題と言えば、複数のCPU が各々持っている CACHE 間とのデータの Coherence問題も含まれます。しかし、ここでは DMA Bufferがおかれる MEMORY と CPUの CACHE との間の Coherence問題に絞って説明します。




## CPUが DMA Buffer に書き込んで DEVICE が読む場合


まず、CPU が DMA Buffer にデータを書き込んで、DEVICE が DMA を使って DMA Buffer を読む場合を考えます。その場合は次の図のように処理が進みます。


![Fig.1 Cache Coherence Problem 1-1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0%2F24981%2Fa62486d8-a806-5a81-a338-05dfbaf7274c.jpeg "Fig.1 Cache Coherence Problem 1-1")

Fig.1 Cache Coherence Problem 1-1

<br />



1. CPU が MEMORY 上の DMA Buffer にデータの書き込みを要求します。   
図の例ではaddr=0x0080 に data=0xABED の書き込みを要求しています。 
2. CACHE が有効な場合は、MEMORY への書き込みは保留され、まずCACHE に書き込んだアドレスとデータが記憶されます。   
図の例では D-Cache に addr=0x0080 と data=0xABED が記憶されます。    
この状態では、まだ MEMORY 上にはデータが書き込まれていません。


![Fig.2 Cache Coherence Problem 1-2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0%2F24981%2Fb2481d66-e405-af13-abd6-b2b75ec2fd33.jpeg "Fig.2 Cache Coherence Problem 1-2")

Fig.2 Cache Coherence Problem 1-2

<br />



3. 次に DEVICE が DMA を使って DMA Buffer を読みに行きます。
4. しかし、MEMORY には CPU が要求したデータ書き込みの結果がまだ反映されていません。したがって、DEVICE は CPU が書き込んだデータではない内容を読んでしまいます。



これが、CPUが DMA Buffer に書き込んで DEVICE が読む場合の Cache Coherence 問題です。


## DEVICE が DMA Buffer に書き込んで CPU が読む場合


次に、DEVICE が DMA Buffer にデータを書き込んで CPU が読む場合を考えます。その際、次の図のように CPU の Cache になんらかのデータがすでにキャッシュされているとします。


![Fig.3 Cache Coherence Problem 2-1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0%2F24981%2F49f9f517-7db8-19e3-30ff-07a700cca58a.jpeg "Fig.3 Cache Coherence Problem 2-1")

Fig.3 Cache Coherence Problem 2-1

<br />



1. CPU が DMA Buffer からのデータを読み込んでその内容が CACHE に記録されている、あるいは CPU が DMA Buffer を初期化してその内容がすでに MEMORY に反映されているとします。この図の例では addr=0x0080 の data=0x0000 が D-Cache 上にすでに記録されています。


![Fig.4 Cache Coherence Problem 2-2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0%2F24981%2Fd3e96f90-06f0-b0fa-625e-79e61b6b5d2d.jpeg "Fig.4 Cache Coherence Problem 2-2")

Fig.4 Cache Coherence Problem 2-2

<br />



2. DEVICE が DMA Buffer にデータを書き込みます。   
この図の例では addr=0x0080 に data=0xDEAD を書き込んでいます。




![Fig.5 Cache Coherence Problem 2-3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0%2F24981%2F673e4d8b-2a78-2d29-f68b-79d6dfb3fb58.jpeg "Fig.5 Cache Coherence Problem 2-3")

Fig.5 Cache Coherence Problem 2-3

<br />



3. CPU が DMA Buffer のデータを読みます。
4. しかし CACHE には DMA Buffer の前の内容が残っており、その内容が CPU に渡されます。その結果、DEVICE が DMA Buffer に書いたデータが CPU には伝わりません。



これが DEVICE が DMA Buffer に書き込んで CPU が読む場合の Cache Coherence 問題です。










# まとめ


この記事では、「Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある」のを説明する際に、知っておいてほしい Cache Cohernce 問題とは何かについて説明しました。

次の記事 [『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Coherence 問題の解決方法)』] では、このCache Coherence 問題の解決方法を説明します。



[はじめに]: https://qiita.com/ikwzm/items/aa7e2373705872ccf764 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (はじめに)』@Qiita"
[『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (はじめに)』]: https://qiita.com/ikwzm/items/aa7e2373705872ccf764 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (はじめに)』@Qiita"
[Cache Coherence 問題]: https://qiita.com/ikwzm/items/f60281491cc83f29c019 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Coherence 問題とは何か)』@Qiita"
[Cache Coherence 問題とは何か]: https://qiita.com/ikwzm/items/f60281491cc83f29c019 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Coherence 問題とは何か)』@Qiita"
[『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Coherence 問題とは何か)』]: https://qiita.com/ikwzm/items/f60281491cc83f29c019 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Coherence 問題とは何か)』@Qiita"
[Cache Coherence 問題の解決方法]: https://qiita.com/ikwzm/items/6d3225e4cbdbbabcabd5 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Coherence 問題の解決方法)』@Qiita"
[『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Coherence 問題の解決方法)』]: https://qiita.com/ikwzm/items/6d3225e4cbdbbabcabd5 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Coherence 問題の解決方法)』@Qiita"
[Cache Aliasing 問題]: https://qiita.com/ikwzm/items/1b8dc72e04d0fa031a0f "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Aliasing 問題とは何か)』@Qiita"
[Cache Aliasing 問題とは何か]: https://qiita.com/ikwzm/items/1b8dc72e04d0fa031a0f "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Aliasing 問題とは何か)』@Qiita"
[『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Aliasing 問題とは何か)』]: https://qiita.com/ikwzm/items/1b8dc72e04d0fa031a0f "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Aliasing 問題とは何か)』@Qiita"
[Cache Aliasing 問題の解決方法]: https://qiita.com/ikwzm/items/b3c24f04121a0d2deefd "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Aliasing 問題の解決方法)』@Qiita"
[『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Aliasing 問題の解決方法)』]: https://qiita.com/ikwzm/items/b3c24f04121a0d2deefd "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Cache Aliasing 問題の解決方法)』@Qiita"
[Linux Kernel の Cache 問題の扱い]: https://qiita.com/ikwzm/items/f32985890b2013ef5528 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Linux Kernel の Cache 問題の扱い)』@Qiita"
[『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Linux Kernel の Cache 問題の扱い)』]: https://qiita.com/ikwzm/items/f32985890b2013ef5528 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Linux Kernel の Cache 問題の扱い)』@Qiita"
[Linux では Cache Coherence Hardware を持っていないとDMA Buffer をmmap する際に CPU Cache が無効になる]: https://qiita.com/ikwzm/items/0f77072158ce842018fc "『Linux では Cache Coherence Hardware を持っていないとDMA Buffer をmmap する際に CPU Cache が無効になる』@Qiita"
[『Linux では Cache Coherence Hardware を持っていないとDMA Buffer をmmap する際に CPU Cache が無効になる』]: https://qiita.com/ikwzm/items/0f77072158ce842018fc "『Linux では Cache Coherence Hardware を持っていないとDMA Buffer をmmap する際に CPU Cache が無効になる』@Qiita"
[Raspberry Pi の例]: https://qiita.com/ikwzm/items/f8bcb82cfdb818bdb07d "『Raspberry Pi では DMA Buffer をmmap する際に CPU Cache が無効になる』@Qiita"
[『Raspberry Pi では DMA Buffer をmmap する際に CPU Cache が無効になる』]: https://qiita.com/ikwzm/items/f8bcb82cfdb818bdb07d "『Raspberry Pi では DMA Buffer をmmap する際に CPU Cache が無効になる』@Qiita"
[RISC-V CPU の注意点]: https://qiita.com/ikwzm/items/3c6b15029780be57f3a9 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (RISC-V CPU の注意点)』@Qiita"
[『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (RISC-V CPU の注意点)』]: https://qiita.com/ikwzm/items/3c6b15029780be57f3a9 "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (RISC-V CPU の注意点)』@Qiita"
[所感]: https://qiita.com/ikwzm/items/46f00c39b7d92c06654e "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (所感)』@Qiita"
[『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (所感)』]: https://qiita.com/ikwzm/items/46f00c39b7d92c06654e "『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (所感)』@Qiita"
[『Kernel/VM探検隊@北陸 Part 6』]: https://kernelvm.connpass.com/event/297033/ "『Kernel/VM探検隊@北陸 Part 6』"