web-dev-qa-db-ja.com

Linux DAX(ダイレクトアクセス)の詳細

DAX(Direct Access)を探していたところ、XIP(Execute In Place)の代わりとして導入されていることがわかりました。ただし、RAMにコピーせずにアプリケーションを実行できるかどうかは疑問です。 「ファイルへの直接アクセス」と書いてありますが、実行可能ファイルはカーネルへのファイルでもありますね。では、RAMにファイルをコピーせずにカーネルにファイルを実行させるのでしょうか?はいの場合、それはどのように機能しますか? .text領域を所定の位置に保持しますが、.data領域のコピーを作成しますか?

実験のセットアップがあります。DAXをサポートするLinuxカーネル4.6.2を構成しました。ラムバックアップブロックデバイスを作成しました。 daxオプションでRAMディスクをマウントしました:

# mount -t ramfs -o dax,size=8m ext2 /ramdisk
# mount
rootfs on / type rootfs (rw,size=59124k,nr_inodes=14781)
proc on /proc type proc (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
ext2 on /ramdisk type ramfs (rw,relatime,dax,size=8m)
#

これで、ramfsが/ ramdiskにマウントされ、ext2でフォーマットされ、daxがサポートされました。アプリケーションを/ ramdiskにコピーして、実行すると、 RAMの他の場所にコピーされて、そこから実行されないようにするにはどうすればよいですか?

残念ながら、daxにはドキュメントがほとんどありません。それは カーネルの説明 は次のように述べています:

メモリのようなブロックデバイスの場合、ページキャッシュページは元のストレージの不要なコピーになります。 DAXコードは、ストレージデバイスに直接読み取りと書き込みを実行することにより、余分なコピーを削除します。ファイルマッピングの場合、ストレージデバイスはユーザースペースに直接マッピングされます。

これは、実行可能ファイルをRAMの2番目の場所にコピーせずに実行できるように見えます。ただし、次のようにも言われています。

カーネルまたはそのモジュールが、DAXをサポートするブロックデバイス上のDAXをサポートするファイルシステムに格納されている場合でも、それらはRAMにコピーされます。

要約すると、私はDAX機能と混同しており、アプリケーションをRAMの別の場所にコピーせずに、アプリケーションを実行する方法を提供できるかどうか知りたいです(キャッシュへのコピーは私にとってトピック外です) )。それがどのように機能するかについての説明を聞いてうれしいです。

2
baof

あなたの例を議論する前に、少し免責事項:これは現実のやや単純化されたバージョンです、私が説明しない多くのコーナーケースと例外がありますが、何が起こっているのかを理解させるのに十分なはずです...


ブロックデバイス

あなたを混乱させているのは、「ブロックデバイス」という用語の無差別な使用です。ブロックデバイスは通常、HDD、CD、SSDなどです...名前自体が示すように、これらのデバイスに個々のバイトを読み書きすることはできません。ブロック(通常は512バイトのサイズ)で書き込む必要があります。

ブロックデバイスには、デバイスステータスの読み取り、コマンドの送信などに使用できるプロセッサアドレス空間にマップされたいくつかのレジスタと小さなメモリ領域があります。ただし、(通常)それらは、保持しているデータに直接アクセスする手段を提供しません。これは通常、デバイスにコマンドを送信し、DMA操作(読み取りまたは書き込み)が完了したことを通知するハードウェア割り込みを待つことによって行われます。

ご覧のとおり、これらの種類のデバイスでは、操作にDMA操作などが含まれるため、メインメモリ(DRAM)を使用しないことは(不可能ではないにしても)やや困難です。DAXの機能このような場合、データへのアクセスに伴うオーバーヘッドの一部を取り除くことですが、それ以上のことはしません。

DIMM形式* NVM

ただし、最近、一部のDIMM形式*の不揮発性メモリ(NVM)が市場に導入されました。これらのデバイスは、コンテンツ全体をプロセッサのアドレス空間にマップするため、ストアおよびロード命令を介してプロセッサから直接アクセスできます。カーネルは、これらのデバイスがアクセスされていることを知る必要さえありません。すべての意図と目的によって、プロセスが通常のDRAMでバックアップされたメモリページにアクセスしているかのようです。

* DIMMフォーマットはほんの一例です。 PCIのような他のいくつかの既存のインターフェースもあります...

紛らわしい部分

ここに混乱があります...最近まで、「ストレージデバイス」は実質的に「ブロックデバイス」の同義語でした。 Linuxカーネルは、これらの新しいNVMをストレージデバイス/ブロックデバイスとして認識し、たとえばSSDの場合と同じように/ devにエントリを作成することにより、それに応じて処理します。 (これらのNVMでバックアップされたデバイスのいずれかがない場合は、通常のDRAMの特定のメモリ範囲をNVMのように扱うように指定することで、それをシミュレートできます。 ここを参照 実行方法の詳細それ。)

このようなデバイスでファイルシステムを作成すると、通常のHDDを使用しているかのように機能します。コンテンツをDRAMにキャッシュすることにより、パフォーマンスの向上を試みます。 DAX対応のファイルシステムが行うことは、アクセスを高速化することを目的としたキャッシュの作成を回避することですが、これらの場合、パフォーマンスが低下する可能性があります。


カーネルまたはそのモジュールが、DAXをサポートするブロックデバイス上のDAXをサポートするファイルシステムに格納されている場合でも、それらはRAMにコピーされます。

この動作の確かな理由を実際に見つけることはできませんでしたが、カーネルとカーネルモジュールが遅い(DRAMより遅い)デバイスから実行されないことを保証するために、セキュリティとパフォーマンスの理由で行われていると思います。それらの内容がカーネルの実行中に混乱しないこと。

ただし、実行可能ファイルがユーザースペースに残っている限り、NVMでバックアップされたメモリのみを使用してNVMから直接実行可能ファイルを実行しても問題はありません。

Intelのプロジェクト Pmem.io およびHPの Atlas を見てください。これらは、この種のもののために特別に作成されたプログラミングインターフェイスです。


今あなたの例について:

# mount -t ramfs -o dax,size=8m ext2 /ramdisk
# mount
rootfs on / type rootfs (rw,size=59124k,nr_inodes=14781)
proc on /proc type proc (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
ext2 on /ramdisk type ramfs (rw,relatime,dax,size=8m)
#

RAMでバックアップされたEXT2ファイルシステムを作成していません。ダミー名ext2のramfsを使用してRAMベースのファイルシステムを作成しています。次のようにマウントしても違いはありません。

# mount -t ramfs -o dax,size=8m winter_is_coming /ramdisk
1
Francesquini

.text領域を所定の位置に保持しますが、.data領域のコピーを作成しますか?

いずれの場合も、exec()mmap()と同じようにMAP_PRIVATEで機能します。ページは、読み取り専用としてプロセスの仮想アドレス空間にマップされます。したがって、書き込みはページフォールト割り込みを引き起こします。これらのページフォールトの処理方法は、 コピーオンライト として記述されます。

DAXの場合、仮想ページはデバイス上の物理ページにマップされた状態で開始されます。ただし、MAP_PRIVATEでページフォールトを書き込むと、ページデータがRAM内の新しいページにコピーされます。 (その後、プロセスのマッピングがそれに応じて更新され、中断されたプログラム命令が再開されます)。

DAXはXIPを一般化したものであり、書き込みと読み取り、つまりMAP_SHAREDとMAP_PRIVATEを許可することに注意してください。 MAP_SHAREDは、たとえばデータベースファイルに使用できます。


実際、共有ライブラリの場合は.textも記述できます。位置独立実行可能ファイルではなく、それ自体への参照を含むライブラリでは、関連するライブラリがロードされているアドレスに応じて、これらの参照を更新する必要があります。このプロセスは「再配置」と呼ばれます。ライブラリは他のライブラリも参照します。 libc;これらの参照の更新は、「シンボル解決」と呼ばれます。

カーネルまたはそのモジュールが、DAXをサポートするブロックデバイス上のDAXをサポートするファイルシステムに格納されている場合でも、それらはRAMにコピーされます。

カーネルモジュールは特別です。シンボルの解決も必要です。ただし、カーネルはCOWを使用しません。 (より一般的には、コードとデータセグメントにデマンドページングを使用しません)。カーネル内のページフォールトは、それらを処理すると無限の再帰が発生する可能性があるため、致命的です。したがって、DAX以前では、カーネルモジュールを全体としてRAMにコピーする必要があることは明らかでした。カーネルコードとデータセグメントは小さいです。DAXを実装した場合、メリットはありませんでした。バイトアドレス可能なストレージを備えたサーバーでこれをいじくり回します。

カーネル自体は歴史的に圧縮されており、明らかにRAMに解凍されています。

そうは言っても、XIPサポートされています 非圧縮カーネルの場合 。これは通常、「組み込み」システム、つまり非常に限られたハードウェアで使用されます。その時点で、ロード可能なモジュールを使用するのではなく、必要なコードのほとんどを組み込みにすることはおそらく問題ではありません。

1
sourcejedi