Я использую CentOS 7.1.1503 с ядром linux 3.10.0-229.el7.x86_64, файловую систему ext4 с режимом упорядоченного журнала и включенным delalloc.
Когда мое приложение непрерывно записывает журналы в файл(около 6 м / с), иногда я могу обнаружить, что системный вызов записи останавливается на 100-700 мс. Когда я отключаю функцию журнала ext4, или устанавливаю режим журнала на обратную запись, или отключаю выделение задержки, остановка исчезает.Когда я установил более частую обратную запись в linux, истек срок действия грязной страницы, проблема уменьшилась.
Я распечатал стек процесса при остановке случайных событий, я получил это:
[<ffffffff812e31f4>] call_rwsem_down_read_failed+0x14/0x30
[<ffffffffa0195854>] ext4_da_get_block_prep+0x1a4/0x4b0 [ext4]
[<ffffffff811fbe17>] __block_write_begin+0x1a7/0x490
[<ffffffffa019b71c>] ext4_da_write_begin+0x15c/0x340 [ext4]
[<ffffffff8115685e>] generic_file_buffered_write+0x11e/0x290
[<ffffffff811589c5>] __generic_file_aio_write+0x1d5/0x3e0
[<ffffffff81158c2d>] generic_file_aio_write+0x5d/0xc0
[<ffffffffa0190b75>] ext4_file_write+0xb5/0x460 [ext4]
[<ffffffff811c64cd>] do_sync_write+0x8d/0xd0
[<ffffffff811c6c6d>] vfs_write+0xbd/0x1e0
[<ffffffff811c76b8>] SyS_write+0x58/0xb0
[<ffffffff81614a29>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
Я прочитал исходный код ядра Linux и обнаружил, что call_rwsem_down_read_failed будет вызывать rwsem_down_read_failed, который будет продолжать ждать rw_semaphore.
Я думаю, что причина в том, что очистка журнала метаданных должна ждать очистки связанных грязных страниц, когда очистка грязных страниц заняла много времени, журнал заблокирован, и при фиксации журнала есть rw_semaphore этого индекса, запишите системный вызов этого индексазастопорился.
Я очень надеюсь, что смогу найти доказательства, чтобы доказать это.