似乎我的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调度问题还是我错过了什么?我该如何解决这个问题?
感谢。
UPD:
根据Kristof的建议,我已经重写了我的代码,现在它看起来像这样:
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活动问题而导致操作。
无论如何,感谢您的建议。
答案 0 :(得分:3)
实质上,你完全绕过内核IO调度程序。
如果你看一下ext2实现,你会发现它永远不会(好吧,一次)调用write_one_page()
。对于大规模数据传输,它使用mpage_writepages()
代替。
这使用Block I / O接口,而不是立即访问硬件。这意味着它通过IO调度程序。大型操作不会阻塞整个系统,因为调度程序将自动确保其他操作与大写操作交错。