重负载下的IO性能较差

时间:2012-05-21 11:28:30

标签: io filesystems linux-kernel

似乎我的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活动问题而导致操作。

无论如何,感谢您的建议。

1 个答案:

答案 0 :(得分:3)

实质上,你完全绕过内核IO调度程序。

如果你看一下ext2实现,你会发现它永远不会(好吧,一次)调用write_one_page()。对于大规模数据传输,它使用mpage_writepages()代替。

这使用Block I / O接口,而不是立即访问硬件。这意味着它通过IO调度程序。大型操作不会阻塞整个系统,因为调度程序将自动确保其他操作与大写操作交错。