2012-05-21 2 views
0

Кажется, что у меня проблема с производительностью 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:

По предложению I Krištof в уже переработан мой код, и теперь он выглядит следующим образом:

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(); 
} 

В результате я получил более высокую производительность ввода-вывода, но по-прежнему есть проблемы с огромная активность ввода-вывода при одновременном доступе к диску у одного и того же пользователя, вызвавшего операцию.

В любом случае, спасибо за предложения.

+0

Вы действительно хотите иметь файловый ввод-вывод в вашем модуле ядра? Он считается [нестандартным] (http://lkml.indiana.edu/hypermail/linux/kernel/0005.3/0061.html) и [bad] (http://www.linuxjournal.com/article/8110) , Я не могу ответить на ваш вопрос, но могу сказать, что вы пытаетесь переместить это в процесс пользовательской правки. – Shahbaz

+0

@Shahbaz: Ну, у меня есть некоторые причины, чтобы получить это в ядре. Кроме того, я не вижу ничего, что могло бы показать мне, почему IO-образный режим плохой. –

+0

Эта операция, очевидно, займет некоторое время. Вы запускаете его из кодового пути, который должен быть быстрым? Или вы сделали блокировку перед входом в этот цикл, который предотвращает успешное выполнение других задач? – Peter

ответ

3

В сущности, вы полностью обходите планировщик ввода-вывода ядер.

Если вы посмотрите на реализацию ext2, вы увидите ее никогда (хорошо нормально, один раз) вызывает write_one_page(). Для крупномасштабных передач данных вместо этого используется mpage_writepages().

Это использует интерфейс ввода-вывода блока, а не сразу получает доступ к аппаратным средствам. Это означает, что он проходит через планировщик ввода-вывода. Большие операции не будут блокировать все системы, так как планировщик автоматически обеспечит чередование других операций с большими записями.

+0

Спасибо за комментарий. Я полагаю, что что-то не так с планированием ввода-вывода. Я займу некоторое время, чтобы переработать код. –

Смежные вопросы