hugepages に裏打ちされたバッファーを使用するドライバーで作業していますが、hugepages の連続性に問題があることがわかりました。
mmap
ユーザー空間では、プログラムはsyscallを使用して hugepages に裏打ちされた大きなバッファーを割り当てます。バッファーは、呼び出しを介してドライバーに伝達されioctl
ます。ドライバーはget_user_pages
関数を使用して、そのバッファーのメモリ アドレスを取得します。
これは、1 GB (1 hugepage) のバッファー サイズで完全に機能します。get_user_pages
多くのページ ( HUGE_PAGE_SIZE / PAGE_SIZE
) が返されますが、それらはすべて連続しているため、問題はありません。最初のページのアドレスを取得して、それを操作page_address
します。remap_pfn_range
ドライバーは、別のプログラムがmmap
char デバイスで呼び出しを行うときに、そのバッファーをユーザー空間にマップすることもできます。
ただし、バッファが複数の hugepage に支えられている場合、事態は複雑になります。カーネルは、非シーケンシャルな hugepage に裏打ちされたバッファーを返すことができるようです。つまり、hugepage プールのレイアウトがこのようなものである場合
+------+------+------+------+
| HP 1 | HP 2 | HP 3 | HP 4 |
+------+------+------+------+
HP1 と HP4、または HP3 と HP2 を予約することで、hugepage でバックアップされたバッファーの要求を満たすことができます。つまりget_user_pages
、最後のケースでページを取得すると、ページ 0 のアドレスは実際にはページ 262.144 (次の hugepage の先頭) のアドレスの 1 GB 後になります。
これらのページへのアクセスを順次処理する方法はありますか? バッファ全体を使用できるように、アドレスを並べ替えて下位のアドレスを見つけようとしました(たとえば、カーネルが HP3、HP2 に基づくバッファを提供する場合、HP2 のアドレスをベース アドレスとして使用します)が、データがスクランブルされるようです。ユーザー空間(その並べ替えられたバッファーのオフセット0は、ユーザー空間バッファーのオフセット1GBの可能性があります)。
TL;DR: 順序付けられていないヒュージページが 1 つ以上ある場合、Linux カーネル ドライバーで順番にアクセスする方法はありますか?
ところで、私は 3.8.0-29-generic カーネルを搭載した Linux マシンで作業しています。