Linux では Cache Coherence Hardware を持っていないとDMA Buffer をmmap する際に CPU Cache が無効になる







# はじめに


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



1. [はじめに] 
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が無効になる場合がある (Linux Kernel の Cache 問題の扱い)』] では、Linux Kernel で Cache 問題をどのように扱っているかを説明しました。この記事では「Linux では Cache Cohrence Hardware を持っていないとDMA Buffer をmmap する際に CPU Cache が無効になる」ことを説明します。


# 何故 Cache Coherence Hardware を持っていないとキャッシュが無効になるのか？



## dev_is_dma_coherent の役割


前回の記事 [『Linux で DMA Bufferを mmap した時に CPU Cacheが無効になる場合がある (Linux Kernel の Cache 問題の扱い)』] で、Linux Kernel で Cache 問題を扱う際に重要なインライン関数 dev_is_dma_coherent() を紹介しました。

この dev_is_dma_coherent() は Cache Coherence 問題と Cache Aliasing 問題に対する対処方法を次のように選択する目的で使われています。



<table border="2">
  <tr>
    <td rowspan="2">dev_is_dma_coherent()</td>
    <td align="center" colspan="2">Linux Kernel での対応</td>
  </tr>
  <tr>
    <td align="center">Cache Coherence 問題</td>
    <td align="center">Cache Aliasing 問題</td>
  </tr>
  <tr>
    <td>true</td>
    <td>ハードウェアで解決</td>
    <td>キャッシュを有効にする</td>
  </tr>
  <tr>
    <td>false</td>
    <td>ソフトウェアで解決</td>
    <td>キャッシュを無効にする</td>
  </tr>
</table>




## dev_is_dma_coherent の問題点


dev_is_dma_coherent() の問題点は、Cache Coherence 問題と Cache Aliasing 問題の両方を一緒くたにして二択にしているところです。

そもそも、Cache Coherence 問題と Cache Aliasing 問題は、まったく独立した別々の問題です。例えばコンピューターシステムを分類する際に、次図のように

  * Cache Aliasing 問題が起きないシステムを上段
  * Cache Aliasing 問題が起きるシステムを下段
  * Cache Coherence 問題をハードウェアで解決するシステムを左列
  * Cache Coherence 問題をソフトウェアで解決するシステムを右列

とすると、この世のコンピューターシステムは４パターン(次の図の４つの赤枠)に分類されます。


![Fig.1 Computer systems are classified into 4 categories based on cache problem](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0%2F24981%2F25dec428-2e22-e4d1-7a37-0f4e697d1367.jpeg "Fig.1 Computer systems are classified into 4 categories based on cache problem")

Fig.1 Computer systems are classified into 4 categories based on cache problem

<br />



ところが、現在の Linux Kernel では、 dev_is_dma_coherent() という関数によって次の図のように二つに分類されています。






![Fig.2 Computer systems are classified into 2 categories by dev_is_dma_cohrent](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0%2F24981%2F7e38c75a-2e44-5017-a447-102df5e256ef.jpeg "Fig.2 Computer systems are classified into 2 categories by dev_is_dma_cohrent")

Fig.2 Computer systems are classified into 2 categories by dev_is_dma_cohrent

<br />



この方法では、Cache Aliasing 問題が起きないシステムであっても、Cache Cohecence 問題をソフトウェアで解決するシステムでは、mmap の際にキャッシュが無効になってしまいます。


![Fig.3 Problem in classifying with dev_is_dma_coherent](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0%2F24981%2F56ad1e2c-3a38-ad69-5b94-cc9e51537fd7.jpeg "Fig.3 Problem in classifying with dev_is_dma_coherent")

Fig.3 Problem in classifying with dev_is_dma_coherent

<br />



これが、Linux では Cache Cohrence Hardware を持っていないとDMA Buffer をmmap する際に CPU Cache が無効になる理由です。




# まとめ


この記事では「Linux では Cache Cohrence Hardware を持っていないとDMA Buffer をmmap する際に CPU Cache が無効になる」理由を説明しました。

その理由は、Linux Kernel の DMA Mapping API で使用されるインライン関数dev_is_dma_coherent() が、Cache Coherence 問題と Cache Aliasing 問題を同時に扱っているため、Cache Coherence 問題をソフトウェアで解決する場合は自動的に Cache Aliasing 問題も起きうると判断されて mmap 時にキャッシュを無効にするからです。



一般的に今どきの高性能なコンピューターシステム（パーソナルコンピューター、 高機能スマートフォン、スーパーコンピューターなど）は、Cache Coherence 問題も Cache Aliasing 問題もハードウェアで処理するため、dev_is_dma_coherent() は true となり、DMA Buffer を mmap する際にキャッシュが有効になります。



しかし、一部のコンピューターシステム（例えば組み込みなど）には、Cache Coherence Hardware を持っていないためにソフトウェアで解決しなければならないものがあります。そのようなコンピューターシステムでは、例え Cache Aliasing 問題が起きない場合でも、 dev_is_dma_coherent() は false となり、DMA Buffer を mmap する際にキャッシュが無効になります。



次回の記事 [『Raspberry Pi では DMA Buffer をmmap する際に CPU Cache が無効になる』] では、その代表例である Raspberry Pi について説明します。








# 参考


* 「Dynamic DMA mapping using the generic device」   
https://docs.kernel.org/core-api/dma-api.html
*  「Linux Kernel 6.1.97 source」   
https://elixir.bootlin.com/linux/v6.1.97/source
* 「V4L2 ストリーミングI/O(V4L2_MEMORY_MMAP) で性能が出ない問題 (2024年改訂版)」   
Qiita   
https://qiita.com/ikwzm/items/474ababbc99cb4812bc7



[はじめに]: 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』"