Üretim Linux sistemlerinde gecikme ani artışları ortaya çıktığında, hangi çekirdek fonksiyonunun sorumlu olduğunu tahmin etmek zaman kaybına yol açar. Ben, ekiplerin top çıktısına veya genel perf raporlarına bakıp, kesme işleme veya zamanlayıcı gecikmelerinde gizli kalan gerçek suçlayıcıyı kaçırmasını gördüm. Perfetto, çekirdek fonksiyonlarını mikrosaniye çözünürlüğe kadar izleyerek, sched/switch veya irq/handler gibi tracepoint'lerle ilişkilendirerek bu durumu değiştirir. Bu yazıda, yüksek seviyeli gecikme belirtilerinden başlayarak, gecikmeye neden olan kesin fonksiyona kadar inmeyi nasıl yaptığını anlatacağım.
Perfetto'yu çekirdek fonksiyon izleme için kurma
İlk olarak, fonksiyon izleme etkinleştirilmiş (CONFIG_FUNCTION_TRACER=y) ve Perfetto kurulu olan güncel bir çekirdeğin olduğundan emin olun. Dağıtım paketleri genellikle güncel olmadığı için, perfetto.dev'den resmi ikili dosyayı kullanmayı tercih ederim. En son sürümü indirin, çıkarın ve perfetto ikili dosyasını PATH'inize ekleyin.
Zamanlayıcı ve IRQ olaylarıyla birlikte fonksiyon çağrılarını izlemek için aşağıdaki yapılandırmayı kullanıyorum:
# perfetto_config.pbtxt
buffers: {
size_kb: 10240
fill_policy: RING_BUFFER
}
data_sources: {
config {
name: "linux.ftrace"
linux_ftrace_config {
ftrace_events: "sched/switch"
ftrace_events: "irq/handler*
enable_function_tracing: true
function_filter: "schedule\|do_softirq\|handle_irq"
}
}
}
Bu yapılandırma, her sched/switch ve irq/handler olayını yakalarken, odaklanmış bir fonksiyon seti için fonksiyon izlemeyi etkinleştirir. Daha sonra filtreyi genişletebilirsiniz, ancak başlangıçta dar tutmak, buffer'ın aşırı yüklenmesini önler.
Gecikme artışı sırasında izi yakalama
Yüksek gecikme gözlemlediğimde—örneğin, 99. yüzdelik yanıt süresi üzerinden bir izleme uyarısıyla—izzi manuel olarak tetiklerim. Bir terminalde, Perfetto'yu şu şekilde başlatırım:
perfetto -c perfetto_config.pbtxt -o latency_trace.pb
Artış sırasında 10–30 saniye çalıştırır, ardından Ctrl+C ile durdurur. Çıktı, Perfetto UI'sine (ui.perfetto.dev) yüklenebilecek bir protobuf dosyasıdır.
Kullanıcı Arayüzü'nde Fonksiyon Seviyesinde Gecikme Analizi
Perfetto web UI'sindeki izlemeyi aç. İlk olarak, görevlerin geciktiği zamanları görmek için sched/switch izlemesine bak. Beklenen süreden daha uzun bir süre RUNNING durumunda olmayan bir görev olduğu boşluğa yakınlaştır. Ardından, fonksiyon izleme yoluna geç.
İşte aradığım şeyler:
- İki sched/switch eventi arasında uzun bir süre çekirdek fonksiyonu yürütme
- Belirli bir fonksiyonun tekrarlı çağrıları (örneğin, do_softirq her seferinde 200µs)
- Bir görev sonunda çalışmadan önce irq/handler etkinliklerinin birikmesi
Bir durumda, ağ tıkanıklıklarında __do_softirq her çağrısında 800µs tükettiğini gördüm. Fonksiyon filtresi onu yakalamıştı ve UI, onu ixgbe_poll tarafından çağrıldığını gösteriyordu. Bu, ağır yük altında NIC sürücüsünün NAPI döngüsüne doğrudan işaret ediyordu.
Özel Fonksiyon Filtreleriyle Daha Derinlemesine İnceleme
Bazen varsayılan filtre yeterli olmaz. Bir alt sistemi şüphe ediyorsanız ancak kesin fonksiyonu bilmiyorsanız, kısa süreli olarak daha geniş izlemeyi etkinleştirin:
# Geçici olarak tüm fonksiyon izlemeyi etkinleştir (dikkatli kullanın)
echo function > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/tracing_on
# ... sorunu yeniden üretin ...
echo 0 > /sys/kernel/debug/tracing/tracing_on
Ardından izi, perfetto’nun ftrace ayrıştırıcıyla çıkarın veya bir temel çizelgeyle karşılaştırın. Boşta dönen dönemlerden elde ettiğim temel izi saklarım ve Perfetto’nun diff görünümünü kullanarak neyin değiştiğini görürüm.
Kullanıcı-alan etkisiyle ilişkilendirme
Çekirdek fonksiyon gecikmeleri, kullanıcı görevlerini etkilediğinde sadece önem kazanır. Perfetto UI'da, görev durumlarını görmek için "sched" izini etkinleştirin. Uzun bir irq/handler veya fonksiyon izi, INTERRUPTIBLE_SLEEP veya UNINTERRUPTIBLE_SLEEP durumunda takılan bir görevle eşleştiğinde, engelleme yolunu bulmuş olursunuz.
İpucu: İşlem adınızı comm kullanarak fonksiyon filtresine ekleyin:
enable_function_tracing: true
function_filter: "schedule\|do_softirq\|handle_irq\|mysqld"
Bu, belirli bir görev adına yapılan çekirdek işleminde gecikmenin olup olmadığını izole etmenize yardımcı olur.
Sınırlamalar ve dikkat edilmesi gerekenler
Fonksiyon izleme ekstra yük getirir—modern çekirdeklerde genellikle %2–5 CPU, ancak çok fazla fonksiyon izlenirse bu oran artabilir. Test etmeden yoğun üretim makinelerinde genel olarak etkinleştirmekten kaçınıyorum. Ayrıca, derleyici optimizasyonları veya dinamik izleme sınırları nedeniyle tüm fonksiyonlar izlenemez; bir fonksiyon izleme çıktısında görünmüyorsa, notrace veya static olarak işaretlenip işaretlenmediğini kontrol edin.
Başka bir dikkat edilmesi gereken durum: buffer aşımı. İzleme istatistiklerinde "düşürülen olaylar" görüyorsanız, buffer boyutunu artırın veya yakalama penceresini kısaltın. Çoğu sistemde 30 saniyelik ani yük artışları için 10MB buffer yeterli olduğunu buldum.
Perfetto yerine perf veya eBPF kullanmak için ne zaman başvurmalıyım?
Kullanıcı-çekirdek karışık yığınlar için CPU flamegraph'ları yapmam gerektiğinde hâlâ perf record -g kullanıyorum. Ancak zamanlama ve tracepoint korelasyonu önemli olan gecikme avcılığı için—özellikle planlama ve kesintiler etrafında—Perfetto, daha net ve senkronize bir görünüm sunar. Ayrıca, perf.data dosyalarıyla kıyaslandığında, takımlarımla izleri paylaşmak da daha kolay.
Auditd ve SIEM entegrasyonu hakkında yazdığım yazımda da belirttiğim gibi, izlenebilir ve sorgulanabilir veri, tahmin etmekten çok daha iyidir. Perfetto, çekirdek gecikmesini siyah bir kutudan izlenebilir bir sinyale dönüştürür.
Ağ, depolama veya gerçek zamanlı iş yüklerinde gizli titremeyle uğraşıyorsanız, sched/switch ve irq/handler izleriyle başlayın, fonksiyon filtreleme ekleyin ve verinin zamanın gerçekte nerede harcadığını göstermesine izin verin.
Kapak görseli: USDAgov · PDM (Openverse / kamu malı) · https://www.flickr.com/photos/41284017@N08/7644752188
