Йенс Екслбо (Jens Axboe), създателят на io_uring и планировците на вход/изход CFQ, Deadline и Noop, предложи за включване в кодовата база на QEMU емулационен патч, който редуцира закъсненията при работа с fdmon (monitoring на файлови дескриптори) в режим "aio=io_uring" и когато системата е в бездействие (idle), с 50-80 пъти.
Проблемът се проявяваше поради превключването на операцията ppoll() в състояние на сън с таймаут от 499 мс, въпреки наличието на вход/изход. За възобновяване на основния цикъл на обработка на събитията, блокиран от ppoll(), беше предложен патч, който добавя обаждане на функцията aio_notify() в функцията за създаване на запис SQE (Submission Queue Entry), за да извади ppoll() от режима на сън.
Проблемът възникна по време на регресионно тестване на io_uring в виртуални машини с различни блочни устройства. Йенс отбеляза случайното появяване на таймаути при използване на AHCI/SATA устройства в режим "aio=io_uring", докато в конфигурации с virtio-blk или nvme тестовете винаги успешно завършваха за около секунда. Отбелязва се, че проблемът засяга всички типове блочни устройства, но при AHCI/SATA устройствата закъсненията са най-изразени поради използването на MMIO.
Йенс също така описа своя опит с отстраняване на проблеми, използвайки AI асистента Claude. След като определи сценария, който възпроизвежда условията за появата на таймаут, той предаде наличните отладъчни данни на Claude, предостави достъп до виртуалната машина и предложи да се установят вероятните причини за открития проблем.
Claude реши да провери дали работата ще се забави при използване на virtio-blk устройство и стартира предложен от разработчика деструктивен сценарий, който възпроизвежда проблема. По време на проверката бяха изтрити първите 128 МБ съдържание от блочното устройство /dev/vda във виртуалната машина. След това, Claude заключи, че проблемът не е в virtio-blk. Когато Йенс насочи AI асистента към изтриването на част от съдържанието на /dev/vda, той отговори "Да, направих го", а след искане за поправка — възстанови работоспособността на виртуалния диск /dev/vda. Отбелязва се, че използването на AI асистента помогна да се разберат по-добре особеностите на изпълнението на различни цикли на обработка на събития в QEMU.
Забележително е, че проблемът беше достатъчно труден за откриване, тъй като в синтетичните тестове забавянето не се регистрира поради факта, че появата на неуспеха се влияе от буденето на цикъла за обработка на събития с ppoll заради друга активност, а синтетичните тестове за вход/изход не изпълняват обработка на получените данни. Забавянето стана по-очевидно при добавянето на няколко извиквания на usleep() за симулиране на обработка на данни.
Преди поправката на системата в режим на изчакване (idle): time sudo ./iotest /dev/sda Изпълнено за 25.76 секунди fish външно usr time 6.19 millis 783.00 micros 5.41 millis sys time 12.43 millis 642.00 micros 11.79 millis
След поправката на системата в режим на изчакване: time sudo ./iotest /dev/sda Изпълнено за 1.30 секунди fish външно usr time 2.14 millis 0.14 millis 2.00 millis sys time 16.93 millis 1.16 millis 15.76 millis
Източник: opennet.ru
