Linux IO のパフォーマンスに問題があるようです。プロジェクトをclear
使用して、カーネル空間からファイル全体を作成する必要があります。次のコード パターンを使用します。
for_each_mapping_page(mapping, index) {
page = read_mapping_page(mapping, index);
lock_page(page);
{ kmap // memset // kunmap }
set_page_dirty(page);
write_one_page(page, 1);
page_cache_release(page);
cond_resched();
}
すべて正常に動作しますが、大きなファイル (私にとっては ~3Gb+) の場合、システムが奇妙な方法で停止していることがわかります。この操作が完了していない間は、何も実行できません。つまり、この操作の前に存在するすべてのプロセスは正常に実行されますが、この操作中に何かを実行しようとすると、完了するまで何も表示されません。
それはカーネルの IO スケジューリングの問題ですか、それとも私が何かを見逃したのでしょうか? そして、どうすればこの問題を解決できますか?
ありがとう。
更新:
クリストフの提案によると、コードを作り直したところ、次のようになりました。
headIndex = soff >> PAGE_CACHE_SHIFT;
tailIndex = eoff >> PAGE_CACHE_SHIFT;
/**
* doing the exact @headIndex .. @tailIndex range
*/
for (index = headIndex; index < tailIndex; index += nr_pages) {
nr_pages = min_t(int, ARRAY_SIZE(pages), tailIndex - index);
for (i = 0; i < nr_pages; i++) {
pages[i] = read_mapping_page(mapping, index + i, NULL);
if (IS_ERR(pages[i])) {
while (i--)
page_cache_release(pages[i]);
goto return_result;
}
}
for (i = 0; i < nr_pages; i++)
zero_page_atomic(pages[i]);
result = filemap_write_and_wait_range(mapping, index << PAGE_CACHE_SHIFT,
((index + nr_pages) << PAGE_CACHE_SHIFT) - 1);
for (i = 0; i < nr_pages; i++)
page_cache_release(pages[i]);
if (result)
goto return_result;
if (fatal_signal_pending(current))
goto return_result;
cond_resched();
}
その結果、IO パフォーマンスは向上しましたが、操作の原因となった同じユーザー内で同時ディスク アクセスを実行している間、依然として巨大な IO アクティビティに問題があります。
とにかく、提案をありがとう。