ΠžΡ‚ висока латСнтност Π½Π° Ceph Π΄ΠΎ Kernel Patch с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° eBPF/BCC

ΠžΡ‚ висока латСнтност Π½Π° Ceph Π΄ΠΎ Kernel Patch с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° eBPF/BCC

Π’ Linux ΠΈΠΌΠ° ΠΌΠ½ΠΎΠ³ΠΎ инструмСнти Π·Π° отстраняванС Π½Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ с ядрото ΠΈ прилоТСнията. ΠŸΠΎΠ²Π΅Ρ‡Π΅Ρ‚ΠΎ ΠΎΡ‚ тях ΠΎΠΊΠ°Π·Π²Π°Ρ‚ Π½Π΅Π³Π°Ρ‚ΠΈΠ²Π½ΠΎ влияниС Π²ΡŠΡ€Ρ…Ρƒ производитСлността Π½Π° прилоТСнията ΠΈ Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π² продукция.

ΠŸΡ€Π΅Π΄ΠΈ няколко Π³ΠΎΠ΄ΠΈΠ½ΠΈ бСшС Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π΅Π½ ΠΎΡ‰Π΅ Π΅Π΄ΠΈΠ½ инструмСнт β€” eBPF. Π’ΠΎΠΉ Π΄Π°Π²Π° Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° прослСдяванС Π½Π° ядрото ΠΈ потрСбитСлскитС прилоТСния с ниски Ρ€Π°Π·Ρ…ΠΎΠ΄ΠΈ ΠΈ Π±Π΅Π· нСобходимост ΠΎΡ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΠΈ Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° външни ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Π² ядрото.

Π’Π΅Ρ‡Π΅ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‚ мноТСство ΠΏΠΎΠ»Π΅Π·Π½ΠΈ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ eBPF, ΠΈ Π² Ρ‚Π°Π·ΠΈ статия Ρ‰Π΅ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΊΠ°ΠΊ Π΄Π° напишСм собствСна ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π° Π·Π° ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€Π°Π½Π΅, Π±Π°Π·ΠΈΡ€Π°Π½Π° Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° PythonBCC. Бтатията Π΅ основана Π½Π° Ρ€Π΅Π°Π»Π½ΠΈ ΡΡŠΠ±ΠΈΡ‚ΠΈΡ. Π©Π΅ ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ΠΌ ΠΏΡ€Π΅Π· процСса ΠΎΡ‚ появата Π½Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π΄ΠΎ Π½Π΅Π³ΠΎΠ²ΠΎΡ‚ΠΎ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π²Π°Π½Π΅, Π·Π° Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‰ΠΈΡ‚Π΅ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚ΠΈ Π² ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΈ ситуации.

Ceph Π΅ Π±Π°Π²Π΅Π½

Π’ кластСра Ceph Π΄ΠΎΠ±Π°Π²ΠΈΡ…Π° Π½ΠΎΠ² хост. Π‘Π»Π΅Π΄ миграцията Π½Π° част ΠΎΡ‚ Π΄Π°Π½Π½ΠΈΡ‚Π΅ Π½Π° Π½Π΅Π³ΠΎ забСлязахмС, Ρ‡Π΅ скоростта Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° записнитС заявки Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-ниска, ΠΎΡ‚ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ ΡΡŠΡ€Π²ΡŠΡ€ΠΈ.

ΠžΡ‚ висока латСнтност Π½Π° Ceph Π΄ΠΎ Kernel Patch с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° eBPF/BCC
Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠΈ, Π½Π° Ρ‚ΠΎΠ·ΠΈ хост сС използвашС bcache ΠΈ Π½ΠΎΠ²ΠΎ ядро linux 4.15. Π₯ост с Ρ‚Π°ΠΊΠ°Π²Π° конфигурация сС използвашС Ρ‚ΡƒΠΊ Π·Π° ΠΏΡŠΡ€Π²ΠΈ ΠΏΡŠΡ‚. И Π² Ρ‚ΠΎΠ·ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ‚ бСшС ясно, Ρ‡Π΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Ρ‚Π΅ΠΎΡ€Π΅Ρ‚ΠΈΡ‡Π½ΠΎ моТСшС Π΄Π° бъдС всичко.

ИзслСдванС Π½Π° хоста

НСка Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌ с Ρ‚ΠΎΠ²Π°, Π΄Π° Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΊΠ²ΠΎ сС случва Π²ΡŠΡ‚Ρ€Π΅ Π² процСса ceph-osd. Π—Π° Ρ†Π΅Π»Ρ‚Π° Ρ‰Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ perf ΠΈ flamescope (ΠΏΠΎΠ²Π΅Ρ‡Π΅ информация ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅ Ρ‚ΡƒΠΊ):

ΠžΡ‚ висока латСнтност Π½Π° Ceph Π΄ΠΎ Kernel Patch с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° eBPF/BCC
Π’Π°Π·ΠΈ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½Π° ΠΏΠΎΠΊΠ°Π·Π²Π°, Ρ‡Π΅ функцията fdatasync() Π΅ ΠΏΡ€Π΅ΠΊΠ°Ρ€Π°Π»Π° ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅ ΠΏΡ€ΠΈ ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ Π² функцията generic_make_request(). Π§Ρ‚ΠΎ Π·Π½Π°Ρ‡ΠΈ, Ρ‡Π΅ Π½Π°ΠΉ-вСроятно, ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈΡ‚Π΅ Π΅ някъдС извън самия Π΄Π΅ΠΌΠΎΠ½ osd. Π’ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΈΠ»ΠΈ ядрото, ΠΈΠ»ΠΈ дисковСтС. Π˜Π·Ρ…ΠΎΠ΄Π½ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ iostat ΠΏΠΎΠΊΠ°Π·Π²Π°Ρ…Π° висока латСнтност Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° запитванията ΠΎΡ‚ bcache-дисковСтС.

ΠŸΡ€ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° хоста ΠΎΡ‚ΠΊΡ€ΠΈΡ…ΠΌΠ΅, Ρ‡Π΅ Π΄Π΅ΠΌΠΎΠ½ΡŠΡ‚ systemd-udevd ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° голямо количСство CPU β€” ΠΎΠΊΠΎΠ»ΠΎ 20% Π½Π° няколко ядра. Π’ΠΎΠ²Π° Π΅ странно ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ трябва Π΄Π° изясним ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°Ρ‚Π° Π·Π° Π½Π΅Π³ΠΎ. Въй ΠΊΠ°Ρ‚ΠΎ Systemd-udevd Ρ€Π°Π±ΠΎΡ‚ΠΈ с uevent-ΠΈ, Ρ€Π΅ΡˆΠΈΡ…ΠΌΠ΅ Π΄Π° Π³ΠΈ наблюдавамС Ρ‡Ρ€Π΅Π· udevadm monitor. Оказва сС, Ρ‡Π΅ сС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° голямо количСство ΡΡŠΠ±ΠΈΡ‚ΠΈΡ Π·Π° промяна Π·Π° всяко Π±Π»ΠΎΡ‡Π½ΠΎ устройство Π² систСмата. Π’ΠΎΠ²Π° Π΅ доста Π½Π΅ΠΎΠ±ΠΈΡ‡Π°ΠΉΠ½ΠΎ, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ‰Π΅ трябва Π΄Π° сС ΠΏΡ€ΠΎΡƒΡ‡ΠΈ ΠΊΠ°ΠΊΠ²ΠΎ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° всички Ρ‚Π΅Π·ΠΈ ΡΡŠΠ±ΠΈΡ‚ΠΈΡ.

ИзползванС на BCC Toolkit

ΠšΠ°ΠΊΡ‚ΠΎ Π²Π΅Ρ‡Π΅ установихмС, ядрото (ΠΈ Π΄Π΅ΠΌΠΎΠ½ΡŠΡ‚ ceph Π² систСмния ΠΏΠΎΠ²ΠΈΠΊ) ΠΏΡ€Π΅ΠΊΠ°Ρ€Π²Π° ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π² generic_make_request(). НСка ΠΈΠ·ΠΌΠ΅Ρ€ΠΈΠΌ скоростта Π½Π° изпълнСниС Π½Π° Ρ‚Π°Π·ΠΈ функция. Π’ BCC ΡƒΠΆΠ΅ ΠΈΠΌΠ° чудСсСн инструмСнт β€” funclatency. Π©Π΅ слСдим Π΄Π΅ΠΌΠΎΠ½ ΠΏΠΎ нСговия PID с ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π» ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΈΡ‚Π΅ ΠΎΡ‚ 1 сСкунда ΠΈ Ρ‰Π΅ ΠΈΠ·Π²Π΅ΠΆΠ΄Π°ΠΌΠ΅ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π° Π² милисСкунди.

ΠžΡ‚ висока латСнтност Π½Π° Ceph Π΄ΠΎ Kernel Patch с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° eBPF/BCC
ОбикновСно Ρ‚Π°Π·ΠΈ функция Ρ€Π°Π±ΠΎΡ‚ΠΈ Π±ΡŠΡ€Π·ΠΎ. Всичко, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈ β€” Π΅ Π΄Π° ΠΏΡ€Π΅Π΄Π°Π΄Π΅ заявката Π² ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° Π½Π° устройството.

Bcache Π΅ слоТСн ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ, ΠΊΠΎΠΉΡ‚ΠΎ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ° сС ΡΡŠΡΡ‚ΠΎΠΈ ΠΎΡ‚ Ρ‚Ρ€ΠΈ диска:

  • backing device (ΠΊΠ΅ΡˆΠΈΡ€Π°Ρ‰ диск), Π² Ρ‚ΠΎΠ·ΠΈ случай Ρ‚ΠΎΠ²Π° Π΅ Π±Π°Π²Π΅Π½ HDD;
  • caching device (ΠΊΠ΅ΡˆΠΈΡ€Π°Ρ‰ диск), Ρ‚ΡƒΠΊ Ρ‚ΠΎΠ²Π° Π΅ Π΅Π΄ΠΈΠ½ дял ΠΎΡ‚ NVMe устройството;
  • Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½ΠΎΡ‚ΠΎ устройство bcache, с ΠΊΠΎΠ΅Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ.

Π—Π½Π°Π΅ΠΌ, Ρ‡Π΅ ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° заявката забавя, Π½ΠΎ Π·Π° ΠΊΠΎΠ΅ ΠΎΡ‚ Ρ‚Π΅Π·ΠΈ устройства? Π©Π΅ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Ρ‚ΠΎΠ²Π° ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-късно.

Π‘Π΅Π³Π° Π·Π½Π°Π΅ΠΌ, Ρ‡Π΅ uevent-ΠΈΡ‚Π΅ вСроятно ΡΡŠΠ·Π΄Π°Π²Π°Ρ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ. Π”Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΊΠ°ΠΊΠ²ΠΎ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ²Π° тяхната гСнСрация Π½Π΅ Π΅ Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° лСсно. НСка ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Π΅ Π΅ софтуСр, ΠΊΠΎΠΉΡ‚ΠΎ сС стартира ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ΠΈΡ‡Π½ΠΎ. НСка Π²ΠΈΠ΄ΠΈΠΌ какъв софтуСр сС изпълнява Π² систСмата, с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° скрипта execsnoop ΠΎΡ‚ ΡΡŠΡ‰ΠΈΡ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚ΠΈ BCC. Π©Π΅ Π³ΠΎ стартирамС ΠΈ Ρ‰Π΅ насочим ΠΈΠ·Π²ΠΎΠ΄Π° към Ρ„Π°ΠΉΠ».

НапримСр Ρ‚Π°ΠΊΠ°:

/usr/share/bcc/tools/execsnoop  | tee ./execdump

Няма Π΄Π° прСдставямС пълния Π˜Π·Ρ…ΠΎΠ΄ Π½Π° execsnoop, Π½ΠΎ Π΅Π΄Π½Π° интСрСсуваща Π½ΠΈ Ρ€Π΅Π΄ΠΈΡ†Π° изглСТдашС Ρ‚Π°ΠΊΠ°:

sh 1764905 5802 0 sudo arcconf getconfig 1 AD | grep Temperature | awk -F '[:\/]' '{print $2}' | sed 's\/^ ([0-9]*) C.*\/1\/'

Π’Ρ€Π΅Ρ‚Π°Ρ‚Π° ΠΊΠΎΠ»ΠΎΠ½Π° Π΅ PPID (родитСлски PID) Π½Π° процСса. ΠŸΡ€ΠΎΡ†Π΅ΡΡŠΡ‚ с PID 5802 сС ΠΎΠΊΠ°Π·Π° Π΅Π΄ΠΈΠ½ ΠΎΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Π΅Ρ‚Π΅ Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° систСма Π·Π° ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³. ΠŸΡ€ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° конфигурацията Π½Π° систСмата Π·Π° ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ бяха ΠΎΡ‚ΠΊΡ€ΠΈΡ‚ΠΈ Π³Ρ€Π΅ΡˆΠ½ΠΎ Π·Π°Π΄Π°Π΄Π΅Π½ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ. Π’Π΅ΠΌΠΏΠ΅Ρ€Π°Ρ‚ΡƒΡ€Π°Ρ‚Π° Π½Π° HBA Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π° сС ΠΎΡ‚Ρ‡ΠΈΡ‚Π° Π½Π° всСки 30 сСкунди, ΠΊΠΎΠ΅Ρ‚ΠΎ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-чСсто, ΠΎΡ‚ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ. Π‘Π»Π΅Π΄ промяна Π½Π° ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»Π° Π½Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°Ρ‚Π° Π½Π° ΠΏΠΎ-дълъг, ΠΎΡ‚ΠΊΡ€ΠΈΡ…ΠΌΠ΅, Ρ‡Π΅ забавянСто Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° заявкитС Π½Π° Ρ‚ΠΎΠ·ΠΈ хост Π²Π΅Ρ‡Π΅ Π½Π΅ Π»ΠΈΡ‡ΠΈ Π½Π° Ρ„ΠΎΠ½Π° Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ хостовС.

Но всС ΠΎΡ‰Π΅ Π½Π΅ Π΅ ясно Π·Π°Ρ‰ΠΎ bcache устройството сС забавяшС Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° ΠΌΠ½ΠΎΠ³ΠΎ. ΠŸΠΎΠ΄Π³ΠΎΡ‚Π²ΠΈΡ…ΠΌΠ΅ тСстова ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ° с ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Π° конфигурация ΠΈ ΠΎΠΏΠΈΡ‚Π°Ρ…ΠΌΠ΅ Π΄Π° Π²ΡŠΠ·ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅ΠΌ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, стартирайки fio Π½Π° bcache, ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ΠΈΡ‡Π½ΠΎ изпълнявайки udevadm trigger Π·Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° uevents.

ПисанС Π½Π° инструмСнти, основани Π½Π° BCC

НСка сС ΠΎΠΏΠΈΡ‚Π°ΠΌΠ΅ Π΄Π° напишСм прост инструмСнт Π·Π° прослСдяванС ΠΈ ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° Π΅ΠΊΡ€Π°Π½Π° Π½Π° Π½Π°ΠΉ-Π±Π°Π²Π½ΠΈΡ‚Π΅ заявки generic_make_request(). Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΡƒΠ²Π° Π½ΠΈ ΠΈ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° диска, Π·Π° ΠΊΠΎΠΉΡ‚ΠΎ Π΅ ΠΈΠ·Π²ΠΈΠΊΠ°Π½Π° Ρ‚Π°Π·ΠΈ функция.

ΠŸΠ»Π°Π½ΡŠΡ‚ Π΅ прост:

  • РСгистрирамС kprobe Π½Π° generic_make_request():
    • Π‘ΡŠΡ…Ρ€Π°Π½ΡΠ²Π°ΠΌΠ΅ Π² ΠΏΠ°ΠΌΠ΅Ρ‚Ρ‚Π° ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° диска, Π΄ΠΎΡΡ‚ΡŠΠΏΠ½ΠΎ Ρ‡Ρ€Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π½Π° функцията;
    • Π‘ΡŠΡ…Ρ€Π°Π½ΡΠ²Π°ΠΌΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π²Π°Ρ‚Π° ΠΌΠ°Ρ€ΠΊΠ°.

  • РСгистрирамС kretprobe ΠΏΡ€ΠΈ Π²Ρ€ΡŠΡ‰Π°Π½Π΅ ΠΎΡ‚ generic_make_request():
    • ΠŸΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° Π²Ρ€Π΅ΠΌΠ΅Π²Π° ΠΌΠ°Ρ€ΠΊΠ°;
    • Π’ΡŠΡ€ΡΠΈΠΌ Π·Π°ΠΏΠ°Π·Π΅Π½Π°Ρ‚Π° Π²Ρ€Π΅ΠΌΠ΅Π²Π° ΠΌΠ°Ρ€ΠΊΠ° ΠΈ я сравнявамС с Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π°;
    • Ако Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ Π΅ ΠΏΠΎ-голям ΠΎΡ‚ зададСния, Π½Π°ΠΌΠΈΡ€Π°ΠΌΠ΅ Π·Π°ΠΏΠ°Π·Π΅Π½ΠΎΡ‚ΠΎ ΠΈΠΌΠ΅ Π½Π° диска ΠΈ Π³ΠΎ ΠΈΠ·Π²Π΅ΠΆΠ΄Π°ΠΌΠ΅ Π½Π° Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°.

Kprobes ΠΈ kretprobes ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° Π½Π° Ρ‚ΠΎΡ‡ΠΊΠΈΡ‚Π΅ Π·Π° спиранС, Π·Π° Π΄Π° промСнят ΠΊΠΎΠ΄Π° Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅ Π² Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅Ρ‚Π΅ докумСнтацията ΠΈ Π΄ΠΎΠ±Ρ€Π° статия ΠΏΠΎ Ρ‚Π°Π·ΠΈ Ρ‚Π΅ΠΌΠ°. Ако ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌ ΠΊΠΎΠ΄Π° Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈΡ‚Π΅ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚ΠΈ Π² BCC, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠΈΠΌ, Ρ‡Π΅ Ρ‚Π΅ ΠΈΠΌΠ°Ρ‚ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Π° структура. Π’Π°ΠΊΠ° Ρ‡Π΅ Π² Ρ‚Π°Π·ΠΈ статия Ρ‰Π΅ пропуснСм парсинга Π½Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π½Π° скрипта ΠΈ Ρ‰Π΅ ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ΠΌ Π½Π°ΠΏΡ€Π°Π²ΠΎ към самата BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°.

Π’Π΅ΠΊΡΡ‚ΡŠΡ‚ Π½Π° eBPF Π² python-скрипта ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠΎ слСдния Π½Π°Ρ‡ΠΈΠ½:

bpf_text = β€œβ€β€ # Π’ΡƒΠΊ Ρ‰Π΅ бъдС ΠΊΠΎΠ΄ΡŠΡ‚ Π½Π° bpf ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° β€œβ€β€

Π—Π° ΠΎΠ±ΠΌΠ΅Π½ Π½Π° Π΄Π°Π½Π½ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅, eBPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°. Π’Π°ΠΊΠ° Ρ‰Π΅ ΠΏΠΎΡΡ‚ΡŠΠΏΠΈΠΌ ΠΈ Π½ΠΈΠ΅. ΠšΠ°Ρ‚ΠΎ ΠΊΠ»ΡŽΡ‡ Ρ‰Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ PID Π½Π° процСса, Π° ΠΊΠ°Ρ‚ΠΎ стойност Ρ‰Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ структурата:

struct data_t {
	u64 pid;
	u64 ts;
	char comm[TASK_COMM_LEN];
	u64 lat;
	char disk[DISK_NAME_LEN];
};

BPF_HASH(p, u64, struct data_t);
BPF_PERF_OUTPUT(events);

Π’ΡƒΠΊ рСгистрирамС Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°, Π½Π°Ρ€Π΅Ρ‡Π΅Π½Π° p, с ΠΊΠ»ΡŽΡ‡ ΠΎΡ‚ Ρ‚ΠΈΠΏ u64 ΠΈ стойност ΠΎΡ‚ Ρ‚ΠΈΠΏ struct data_t. Π’Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Ρ‰Π΅ бъдС Π΄ΠΎΡΡ‚ΡŠΠΏΠ½Π° Π² контСкста Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°. ΠœΠ°ΠΊΡ€ΠΎΡΡŠΡ‚ BPF_PERF_OUTPUT рСгистрира Π΄Ρ€ΡƒΠ³Π° Ρ‚Π°Π±Π»ΠΈΡ†Π°, Π½Π°Ρ€Π΅Ρ‡Π΅Π½Π° events, която сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Π½Π° Π΄Π°Π½Π½ΠΈ Π² потрСбитСлското пространство.

ΠŸΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Ρ€Π²Π°Π½Π΅ Π½Π° Π·Π°ΠΊΡŠΡΠ½Π΅Π½ΠΈΡΡ‚Π° ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° функция ΠΈ Π²Ρ€ΡŠΡ‰Π°Π½Π΅ ΠΎΡ‚ нСя, ΠΈΠ»ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ извиквания Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π΅ Π½ΡƒΠΆΠ½ΠΎ Π΄Π° сС ΠΈΠΌΠ° ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄, Ρ‡Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ трябва Π΄Π° ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ Π½Π° Π΅Π΄ΠΈΠ½ ΠΈ ΡΡŠΡ‰ΠΈ контСкст. Π‘ Π΄Ρ€ΡƒΠ³ΠΈ Π΄ΡƒΠΌΠΈ, трябва Π΄Π° ΠΏΠΎΠΌΠ½ΠΈΠΌ Π·Π° Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡ‚ΠΎ ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎ изпълнСниС Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅. ИмамС Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π΄Π° ΠΈΠ·ΠΌΠ΅Ρ€ΠΈΠΌ Π·Π°ΠΊΡŠΡΠ½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° функция Π² контСкста Π½Π° Π΅Π΄ΠΈΠ½ процСс ΠΈ Π²Ρ€ΡŠΡ‰Π°Π½Π΅Ρ‚ΠΎ ΠΎΡ‚ Ρ‚Π°Π·ΠΈ функция Π² контСкста Π½Π° Π΄Ρ€ΡƒΠ³ процСс, Π½ΠΎ Ρ‚ΠΎΠ²Π° вСроятно Ρ‰Π΅ Π΅ Π±Π΅Π·ΠΏΠΎΠ»Π΅Π·Π½ΠΎ. Π”ΠΎΠ±ΡŠΡ€ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚ΡƒΠΊ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π°Ρ‚Π° biolatency, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΊΠ°Ρ‚ΠΎ ΠΊΠ»ΡŽΡ‡ Π½Π° Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° сС Π·Π°Π΄Π°Π²Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π» Π½Π° struct request, която отразява Π΅Π΄Π½Π° заявка към диска.

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° трябва Π΄Π° напишСм ΠΊΠΎΠ΄, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ сС изпълнява ΠΏΡ€ΠΈ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° изслСдваната функция:

void start(struct pt_regs *ctx, struct bio *bio) {
	u64 pid = bpf_get_current_pid_tgid();
	struct data_t data = {};
	u64 ts = bpf_ktime_get_ns();
	data.pid = pid;
	data.ts = ts;
	bpf_probe_read_str(&data.disk, sizeof(data.disk), (void*)bio->bi_disk->disk_name);
	p.update(&pid, &data);
}

Π’ΡƒΠΊ вторият Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ‰Π΅ бъдС Π·Π°ΠΌΠ΅Π½Π΅Π½ с ΠΏΡŠΡ€Π²ΠΈΡ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Π½Π° ΠΈΠ·Π²ΠΈΠΊΠ°Π½Π°Ρ‚Π° функция. generic_make_request(). Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ PID Π½Π° процСса, Π² контСкста Π½Π° ΠΊΠΎΠΉΡ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌ, ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π° Π²Ρ€Π΅ΠΌΠ΅Π²Π° ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠ° Π² наносСкунди. ЗаписвамС всичко Ρ‚ΠΎΠ²Π° Π² Π½ΠΎΠ²ΠΎΡΡŠΠ·Π΄Π°Π΄Π΅Π½ΠΎΡ‚ΠΎ struct data_t data. Π˜ΠΌΠ΅Ρ‚ΠΎ Π½Π° диска ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ ΠΎΡ‚ структурата bio, която сС ΠΏΡ€Π΅Π΄Π°Π²Π° ΠΏΡ€ΠΈ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° generic_make_request(), ΠΈ Π³ΠΎ Π·Π°ΠΏΠ°Π·Π²Π°ΠΌΠ΅ Π² ΡΡŠΡ‰Π°Ρ‚Π° структура data. ΠŸΠΎΡΠ»Π΅Π΄Π½Π°Ρ‚Π° ΡΡ‚ΡŠΠΏΠΊΠ° Π΅ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ запис Π² Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π°, Π·Π° която стана Π΄ΡƒΠΌΠ° ΠΏΠΎ-Ρ€Π°Π½ΠΎ.

Π‘Π»Π΅Π΄Π²Π°Ρ‰Π°Ρ‚Π° функция Ρ‰Π΅ бъдС ΠΈΠ·Π²ΠΈΠΊΠ°Π½Π° ΠΏΡ€ΠΈ Π²Ρ€ΡŠΡ‰Π°Π½Π΅Ρ‚ΠΎ ΠΎΡ‚ generic_make_request():

void stop(struct pt_regs *ctx) {
    u64 pid = bpf_get_current_pid_tgid();
    u64 ts = bpf_ktime_get_ns();
    struct data_t* data = p.lookup(&pid);
    if (data != 0 && data->ts > 0) {
        bpf_get_current_comm(&data->comm, sizeof(data->comm));
        data->lat = (ts - data->ts) / 1000;
        if (data->lat > MIN_US) {
            FACTOR
            data->pid >>= 32;
            events.perf_submit(ctx, data, sizeof(struct data_t));
        }
        p.delete(&pid);
    }
}

Π’Π°Π·ΠΈ функция Π΅ ΠΏΠΎΠ΄ΠΎΠ±Π½Π° Π½Π° ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½Π°Ρ‚Π°: установявамС PID Π½Π° процСса ΠΈ Π²Ρ€Π΅ΠΌΠ΅Π²Π°Ρ‚Π° ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠ°, Π½ΠΎ Π½Π΅ задСлямС ΠΏΠ°ΠΌΠ΅Ρ‚ Π·Π° Π½ΠΎΠ²Π° структура Π΄Π°Π½Π½ΠΈ. ВмСсто Ρ‚ΠΎΠ²Π° Ρ‚ΡŠΡ€ΡΠΈΠΌ Π² Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Π²Π΅Ρ‡Π΅ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‰Π°Ρ‚Π° структура спорСд ΠΊΠ»ΡŽΡ‡Π° == тСкущия PID. Ако структурата бъдС Π½Π°ΠΌΠ΅Ρ€Π΅Π½Π°, установявамС ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° стартирания процСс ΠΈ Π³ΠΎ добавямС Π² нСя.

Бидарният сдвиг, ΠΊΠΎΠΉΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Ρ‚ΡƒΠΊ, Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ, Π·Π° Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ GID Π½Π° Π½ΠΈΡˆΠΊΠ°Ρ‚Π°, Ρ‚.Π΅. PID Π½Π° основния процСс, ΠΊΠΎΠΉΡ‚ΠΎ Π΅ стартирал Π½ΠΈΡˆΠΊΠ°Ρ‚Π°, Π² контСкста Π½Π° ΠΊΠΎΠΉΡ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌ. Π˜Π·Π²ΠΈΠΊΠ²Π°Π½Π°Ρ‚Π° ΠΎΡ‚ нас функция bpf_get_current_pid_tgid() Π²Ρ€ΡŠΡ‰Π° ΠΊΠ°ΠΊΡ‚ΠΎ GID Π½Π° Π½ΠΈΡˆΠΊΠ°Ρ‚Π°, Ρ‚Π°ΠΊΠ° ΠΈ нСйния PID Π² Π΅Π΄Π½ΠΎ 64-Π±ΠΈΡ‚ΠΎΠ²ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

ΠŸΡ€ΠΈ ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π° Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π½Π΅ Π½ΠΈ интСрСсува Π½ΠΈΡˆΠΊΠ°Ρ‚Π°, Π° основният процСс. Π‘Π»Π΅Π΄ сравнСниСто Π½Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π°Ρ‚Π° Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° с зададСния ΠΏΡ€Π°Π³, ΠΏΡ€Π΅Π΄Π°Π²Π°ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° структура data Π² пространството Π½Π° потрСбитСля Ρ‡Ρ€Π΅Π· Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° events, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΈΠ·Ρ‚Ρ€ΠΈΠ²Π°ΠΌΠ΅ записа ΠΎΡ‚ p.

Π’ python-скрипта, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ Π·Π°Ρ€Π΅ΠΆΠ΄Π° Ρ‚ΠΎΠ·ΠΈ ΠΊΠΎΠ΄, трябва Π΄Π° Π·Π°ΠΌΠ΅Π½ΠΈΠΌ MIN_US ΠΈ FACTOR с ΠΏΡ€Π°Π³ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° забавянС ΠΈ Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈΡ‚Π΅ Π²Ρ€Π΅ΠΌΠ΅, ΠΊΠΎΠΈΡ‚ΠΎ Ρ‰Π΅ ΠΏΡ€Π΅Π΄Π°Π΄Π΅ΠΌ Ρ‡Ρ€Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅:

bpf_text = bpf_text.replace('MIN_US',str(min_usec))
if args.milliseconds:
	bpf_text = bpf_text.replace('FACTOR','data->lat /= 1000;')
	label = "msec"
else:
	bpf_text = bpf_text.replace('FACTOR','')
	label = "usec"

Π‘Π΅Π³Π° трябва Π΄Π° ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²ΠΈΠΌ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Ρ‡Ρ€Π΅Π· макрос BPF ΠΈ Π΄Π° рСгистрирамС ΠΏΡ€ΠΎΠ±ΠΈΡ‚Π΅:

b = BPF(text=bpf_text)
b.attach_kprobe(event="generic_make_request",fn_name="start")
b.attach_kretprobe(event="generic_make_request",fn_name="stop")

Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° Ρ‰Π΅ трябва Π΄Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ struct data_t Π² нашия скрипт, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π΅Π½ случай Π½ΠΈΡ‰ΠΎ няма Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅:

TASK_COMM_LEN = 16	# linux/sched.h
DISK_NAME_LEN = 32	# linux/genhd.h
class Data(ct.Structure):
	_fields_ = [("pid", ct.c_ulonglong),
            	("ts", ct.c_ulonglong),
            	("comm", ct.c_char * TASK_COMM_LEN),
            	("lat", ct.c_ulonglong),
            	("disk",ct.c_char * DISK_NAME_LEN)]

ΠŸΠΎΡΠ»Π΅Π΄Π½Π°Ρ‚Π° ΡΡ‚ΡŠΠΏΠΊΠ° β€” ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈΡ‚Π΅ Π½Π° Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°:

def print_event(cpu, data, size):
    global start
    event = ct.cast(data, ct.POINTER(Data)).contents
    if start == 0:
        start = event.ts
    time_s = (float(event.ts - start)) / 1000000000
    print("%-18.9f %-16s %-6d   %-1s %s   %s" % (time_s, event.comm, event.pid, event.lat, label, event.disk))

b["events"].open_perf_buffer(print_event)
# Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΈΠ·Ρ…ΠΎΠ΄Π°
start = 0
while 1:
    try:
        b.perf_buffer_poll()
    except KeyboardInterrupt:
        exit()

Бамият скрипт Π΅ Π΄ΠΎΡΡ‚ΡŠΠΏΠ΅Π½ Π½Π° GItHub. НСка ΠΎΠΏΠΈΡ‚Π°ΠΌΠ΅ Π΄Π° Π³ΠΎ стартирамС Π½Π° тСстова ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚ΠΈ fio, записваща Π½Π° bcache, ΠΈ Π΄Π° ΠΈΠ·Π²ΠΈΠΊΠ°ΠΌΠ΅ udevadm monitor:

ΠžΡ‚ висока латСнтност Π½Π° Ceph Π΄ΠΎ Kernel Patch с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° eBPF/BCC
Най-накрая! Π‘Π΅Π³Π° Π²ΠΈΠΆΠ΄Π°ΠΌΠ΅, Ρ‡Π΅ Ρ‚ΠΎΠ²Π°, ΠΊΠΎΠ΅Ρ‚ΠΎ изглСТдашС ΠΊΠ°Ρ‚ΠΎ забавящо bcache устройство, Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚ Π΅ забавяща функция generic_make_request() Π·Π° ΠΊΠ΅ΡˆΠΈΡ€Π°Π½ΠΈΡ диск.

Π Π°Π·Π³Π»Π΅Π΄Π°ΠΉΡ‚Π΅ ядро

Какво Ρ‚ΠΎΡ‡Π½ΠΎ забавя ΠΏΡ€ΠΈ ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° заявката? Π’ΠΈΠΆΠ΄Π°ΠΌΠ΅, Ρ‡Π΅ Π·Π°ΠΊΡŠΡΠ½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ сС появява Π΄ΠΎΡ€ΠΈ ΠΏΡ€Π΅Π΄ΠΈ Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° ΠΎΡ‚Ρ‡ΠΈΡ‚Π°Π½Π΅Ρ‚ΠΎ Π½Π° заявката, Ρ‚.Π΅. ΠΎΡ‚Ρ‡Π΅Ρ‚ΡŠΡ‚ Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Π°Ρ‚Π° заявка Π·Π° ΠΏΠΎ-Π½Π°Ρ‚Π°Ρ‚ΡŠΡˆΠ½ΠΎ ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° статистиката ΠΏΠΎ нСя (/ proc/diskstats ΠΈΠ»ΠΈ iostat) всС ΠΎΡ‰Π΅ Π½Π΅ Π΅ Π·Π°ΠΏΠΎΡ‡Π½Π°Π». Π’ΠΎΠ²Π° лСсно ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈ, ΠΊΠ°Ρ‚ΠΎ пуснСтС iostat ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° Π²ΡŠΠ·ΠΏΡ€ΠΎΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, ΠΈΠ»ΠΈ BCC скрипт biolatency, ΠΊΠΎΠΉΡ‚ΠΎ сС основава Π½Π° Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ ΠΈ края Π½Π° ΠΎΡ‚Ρ‡ΠΈΡ‚Π°Π½Π΅Ρ‚ΠΎ Π½Π° заявкитС. Нито Π΅Π΄Π½Π° ΠΎΡ‚ Ρ‚Π΅Π·ΠΈ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚ΠΈ няма Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ Π·Π° заявкитС към ΠΊΠ΅ΡˆΠΈΡ€Π°Π½ΠΈΡ диск.

Ако ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅ generic_make_request(), Ρ‰Π΅ Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Π΅ ΠΏΡ€Π΅Π΄ΠΈ Π·Π°ΠΏΠΎΡ‡Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΎΡ‚Ρ‡ΠΈΡ‚Π°Π½Π΅Ρ‚ΠΎ Π½Π° заявката сС ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‚ ΠΎΡ‰Π΅ Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. ΠŸΡŠΡ€Π²Π°Ρ‚Π° β€” generic_make_request_checks(), ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π° лСгитимността Π½Π° заявката относно настройкитС Π½Π° диска. Π’Ρ‚ΠΎΡ€Π°Ρ‚Π° β€” blk_queue_enter(), Π² която ΠΈΠΌΠ° интСрСсСн ΠΏΠΎΠ²ΠΈΠΊ wait_event_interruptible():

ret = wait_event_interruptible(q->mq_freeze_wq,
	(atomic_read(&q->mq_freeze_depth) == 0 &&
	(preempt || !blk_queue_preempt_only(q))) ||
	blk_queue_dying(q));

Π’ Π½Π΅Π³ΠΎ ядрото Ρ‡Π°ΠΊΠ° размразяванСто Π½Π° ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π°. Π˜Π·ΠΌΠ΅Ρ€Π²Π°ΠΌΠ΅ Π·Π°ΠΊΡŠΡΠ½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ blk_queue_enter():

~# /usr/share/bcc/tools/funclatency blk_queue_enter -i 1 -m               	 
Tracing 1 functions for "blk_queue_enter"... Hit Ctrl-C to end.

 	msecs           	: count 	distribution
     	0 -> 1      	: 341  	|****************************************|

 	msecs           	: count 	distribution
     	0 -> 1      	: 316  	|****************************************|

 	msecs           	: count 	distribution
     	0 -> 1      	: 255  	|****************************************|
     	2 -> 3      	: 0    	|                                    	|
     	4 -> 7      	: 0    	|                                    	|
     	8 -> 15     	: 1    	|                                    	|

ИзглСТда, Ρ‡Π΅ смС Π±Π»ΠΈΠ·ΠΎ Π΄ΠΎ Ρ€Π°Π·Π³Π°Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈ Π·Π° "замразяванС/размразяванС" Π½Π° ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° β€” Ρ‚ΠΎΠ²Π° са blk_mq_freeze_queue ΠΈ blk_mq_unfreeze_queue. Π’Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° сС промСнят настройкитС Π½Π° ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° Π½Π° заявкитС, ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»Π½ΠΎ опасни Π·Π° заявкитС, ΠΊΠΎΠΈΡ‚ΠΎ сС Π½Π°ΠΌΠΈΡ€Π°Ρ‚ Π² Ρ‚Π°Π·ΠΈ опашка. ΠŸΡ€ΠΈ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° blk_mq_freeze_queue() ΠΎΡ‚ функцията blk_freeze_queue_start() сС ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π° Π±Ρ€ΠΎΡΡ‡ΡŠΡ‚ q->mq_freeze_depth. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° ядрото ΠΈΠ·Ρ‡Π°ΠΊΠ²Π° ΠΈΠ·ΠΏΡ€Π°Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° Π² blk_mq_freeze_queue_wait().

Π’Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π½Π° Ρ‡Π°ΠΊΠ°Π½Π΅ Π·Π° почистванС Π½Π° Ρ‚Π°Π·ΠΈ опашка Π΅ Ρ€Π°Π²Π½ΠΎ Π½Π° забавянСто Π½Π° диска, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ядрото ΠΈΠ·Ρ‡Π°ΠΊΠ²Π° Π·Π°Π²ΡŠΡ€ΡˆΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° всички поставСни Π² ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. ΠŸΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π°, ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ Π² настройкитС Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈ. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Ρ‰Π΅ бъдС ΠΈΠ·Π²ΠΈΠΊΠ°Π½ blk_mq_unfreeze_queue(), намаляваща брояча freeze_depth.

Π‘Π΅Π³Π° Π·Π½Π°Π΅ΠΌ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ, Π·Π° Π΄Π° ΠΏΠΎΠΏΡ€Π°Π²ΠΈΠΌ ситуацията. ΠšΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° udevadm trigger Π²ΠΎΠ΄ΠΈ Π΄ΠΎ ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅ Π½Π° настройкитС Π·Π° Π±Π»ΠΎΡ‡Π½ΠΎ устройство. Π’Π΅Π·ΠΈ настройки са описани Π² ΠΏΡ€Π°Π²ΠΈΠ»Π°Ρ‚Π° Π½Π° udev. МоТСм Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ, ΠΊΠΎΠΈ Ρ‚ΠΎΡ‡Π½ΠΎ настройки β€žΠ·Π°ΠΌΡ€Π°Π·ΡΠ²Π°Ρ‚β€œ ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π°, ΠΎΠΏΠΈΡ‚Π²Π°ΠΉΠΊΠΈ сС Π΄Π° Π³ΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΠΌ Ρ‡Ρ€Π΅Π· sysfs ΠΈΠ»ΠΈ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π΅Π³Π»Π΅Π΄Π°ΠΌΠ΅ изходния ΠΊΠΎΠ΄ Π½Π° ядрото. ОсвСн Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΡ€ΠΎΠ±Π²Π°ΠΌΠ΅ инструмСнта BCC trace, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ ΠΈΠ·Π²Π΅Π΄Π΅ Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π° трасСта Π½Π° стСка Π½Π° ядрото ΠΈ потрСбитСлското пространство Π·Π° всСки ΠΏΠΎΠ²ΠΈΠΊ blk_freeze_queue, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

~# /usr/share/bcc/tools/trace blk_freeze_queue -K -U
PID 	TID 	COMM        	FUNC        	 
3809642 3809642 systemd-udevd   blk_freeze_queue
    	blk_freeze_queue+0x1 [kernel]
    	elevator_switch+0x29 [kernel]
    	elv_iosched_store+0x197 [kernel]
    	queue_attr_store+0x5c [kernel]
    	sysfs_kf_write+0x3c [kernel]
    	kernfs_fop_write+0x125 [kernel]
    	__vfs_write+0x1b [kernel]
    	vfs_write+0xb8 [kernel]
    	sys_write+0x55 [kernel]
    	do_syscall_64+0x73 [kernel]
    	entry_SYSCALL_64_after_hwframe+0x3d [kernel]
    	__write_nocancel+0x7 [libc-2.23.so]
    	[unknown]

3809631 3809631 systemd-udevd   blk_freeze_queue
    	blk_freeze_queue+0x1 [kernel]
    	queue_requests_store+0xb6 [kernel]
    	queue_attr_store+0x5c [kernel]
    	sysfs_kf_write+0x3c [kernel]
    	kernfs_fop_write+0x125 [kernel]
    	__vfs_write+0x1b [kernel]
    	vfs_write+0xb8 [kernel]
    	sys_write+0x55 [kernel]
    	do_syscall_64+0x73 [kernel]
    	entry_SYSCALL_64_after_hwframe+0x3d [kernel]
    	__write_nocancel+0x7 [libc-2.23.so]
    	[unknown]

ΠŸΡ€Π°Π²ΠΈΠ»Π°Ρ‚Π° Π½Π° Udev промСнят доста рядко ΠΈ ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΎ сС случват ΠΏΠΎΠ΄ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ». Π’Π°ΠΊΠ° Π²ΠΈΠΆΠ΄Π°ΠΌΠ΅, Ρ‡Π΅ Π΄ΠΎΡ€ΠΈ ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π²Π΅Ρ‡Π΅ Π·Π°Π΄Π°Π΄Π΅Π½ΠΈ стойности ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ²Π° ΠΏΡ€ΠΈΠ»ΠΈΠ² Π½Π° забавянС Π½Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° заявката ΠΎΡ‚ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ към диска. Π Π°Π·Π±ΠΈΡ€Π° сС, Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ udev, ΠΊΠΎΠ³Π°Ρ‚ΠΎ няма Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² конфигурацията Π½Π° дисковСтС (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, устройството Π½Π΅ сС ΡΠ²ΡŠΡ€Π·Π²Π°/ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π²Π°), Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Π΄ΠΎΠ±Ρ€Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΠΎΠΌΠΎΠ³Π½Π΅ΠΌ Π½Π° ядрото Π΄Π° Π½Π΅ ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° Π½Π΅Π½ΡƒΠΆΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π° ΠΈ Π΄Π° Π½Π΅ β€žΠ·Π°ΠΌΡ€Π°Π·ΡΠ²Π°β€œ ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° Π½Π° заявкитС, Π°ΠΊΠΎ Π² Ρ‚ΠΎΠ²Π° няма Π½ΠΈΠΊΠ°ΠΊΠ²Π° нСобходимост. Π’Ρ€ΠΈ ΠΌΠ°Π»ΠΊΠΈ ΠΊΠΎΠΌΠΈΡ‚Π° поправят ситуацията.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

eBPF Π΅ ΠΈΠ·ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ гъвкав ΠΈ ΠΌΠΎΡ‰Π΅Π½ инструмСнт. Π’ статията Ρ€Π°Π·Π³Π»Π΅Π΄Π°Ρ…ΠΌΠ΅ Π΅Π΄ΠΈΠ½ практичСски случай ΠΈ дСмонстрирахмС ΠΌΠ°Π»ΠΊΠ° част ΠΎΡ‚ Ρ‚ΠΎΠ²Π°, ΠΊΠΎΠ΅Ρ‚ΠΎ Π΅ възмоТно Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ. Ако сС интСрСсуватС ΠΎΡ‚ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° BCC инструмСнти, си струва Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅Ρ‚Π΅ официалния Ρ‚ΡƒΡ‚ΠΎΡ€ΠΈΠ°Π», ΠΊΠΎΠΉΡ‚ΠΎ Π΄ΠΎΠ±Ρ€Π΅ описва основитС Π½Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π°.

Има ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ интСрСсни инструмСнти Π·Π° отстраняванС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ ΠΈ ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€Π°Π½Π΅, Π±Π°Π·ΠΈΡ€Π°Π½ΠΈ Π½Π° eBPF. Π•Π΄ΠΈΠ½ ΠΎΡ‚ тях Π΅ bpftrace, ΠΊΠΎΠΉΡ‚ΠΎ позволява написванСто Π½Π° ΠΌΠΎΡ‰Π½ΠΈ Π΅Π΄Π½ΠΎΡ€Π΅Π΄ΠΎΠ²ΠΈ скриптовС ΠΈ ΠΌΠ°Π»ΠΊΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π½Π° awk-ΠΏΠΎΠ΄ΠΎΠ±Π΅Π½ Π΅Π·ΠΈΠΊ. Другият Π΅ ebpf_exporter, ΠΊΠΎΠΉΡ‚ΠΎ позволява ΡΡŠΠ±ΠΈΡ€Π°Π½Π΅ Π½Π° нискоуровнСви ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ с висока Ρ€Π΅Π·ΠΎΠ»ΡŽΡ†ΠΈΡ Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ във вашия prometheus ΡΡŠΡ€Π²ΡŠΡ€, с Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ ΠΏΠΎ-късно Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ красива визуализация ΠΈ Π΄ΠΎΡ€ΠΈ Π°Π»Π°Ρ€ΠΌΠΈ.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster