top %90 CPU kullanımı gösteriyor ama hiçbir kullanıcı süreci buna sebep değilse, kernel-space CPU tüketimiyle karşı karşıyasınız demektir. Benim ortamımda bu, sanılandan daha sık yaşanır — softirq fırtınaları, lock çakışmaları, I/O bekleme süresi veya bir sürücü hatası sessizce CPU döngülerini yakar. Linux yüksek CPU kullanımı kernel sorun giderme işi, süreç listesinin ötesine bakıp kernel'in zamanını nerede harcadığını profilleme meselesidir. İşte olağan şüpheliler temiz çıktığında buna nasıl yaklaştığım.
top ve htop Sizi Nasıl Yanıltabilir
Klasik hata: top'u açarsınız, CPU'ya göre sıralarsınız ve bir sürü süreci %1-2'de görürsünüz. Ama sistem %95 yükte ve SSH dial-up gibi hissettirir. Sorun şu ki, top varsayılan olarak user-space CPU'yu gösterir. Kernel zamanı — syscall'lerde, interrupt işlemlerinde, softirq işlemlerinde ve scheduler yükünde harcanan zaman — genellikle tek bir sürece temiz şekilde atfedilmez.
top'taki %Cpu(s) satırına bakın. sy (system) değerini %60 ve us (user) değerini %5 görüyorsanız, o sizin kırmızı bayrağınızdır. Ağır işi kernel yapıyor, uygulamanız değil.
%Cpu(s): 3.2 us, 71.5 sy, 0.0 ni, 12.1 id, 13.2 wa, 0.0 hi, 0.0 si, 0.0 st
Bu çıktıda %71.5 olan sy bana kernel'in CPU'yu yaktığını söylüyor. %13.2 olan wa ise I/O bekleme süresinin de katkıda bulunduğu anlamına geliyor. Hiçbir tek süreç bunu açıklamayacak.
Önce softirq ve Donanım Interrupt'larını Kontrol Edin
Softirq'lar ertelenmiş interrupt işleyicileridir. Ağ paket işleme (NET_RX), timer tick'leri ve block I/O tamamlama işlemlerinin hepsi burada çalışır. Yüksek ağ veri hacmine sahip yoğun e-ticaret sunucularında, NIC interrupt'ları CPU'lar arasında dağıtmadığı için ksoftirqd'in bütün bir çekirdeği tükettiğini gördüm.
Şununla başlayın:
cat /proc/interrupts
watch -n1 "cat /proc/softirqs"
NET_RX tek bir CPU'da hızla artarken diğerleri boştaysa, bir interrupt affinity sorununuz var demektir. NIC'nizde RSS (Receive Side Scaling) etkin mi kontrol edin:
ethtool -l eth0
ethtool -L eth0 combined 4
Bu, receive interrupt'larını birden çok kuyruğa yayar. Fiziksel sunucularda ayrıca irqbalance veya manuel /proc/irq/*/smp_affinity maskelerini kullanarak IRQ'ları sabitlerim. Daha önce ağ sorun giderme yazımda (https://furkanikkan.com/urun/ag-yavasliginin-gercek-nedenini-bulmanin-7-yolu-50) belirttiğim gibi, kök neden genellikle beklediğiniz yerde olmaz — ve interrupt dağılımı o sessiz katillerden biridir.
Başka Hiçbir Şey Konuşmadığında Kernel'i perf ile Profilleyin
Softirq ve interrupt kontrolleri normal döndüğünde, direkt perf'e geçerim. Size tam olarak hangi kernel fonksiyonunun CPU'yu yaktığını söyleyen araç budur. Tahmin yok.
perf record -a -g -- sleep 30
perf report
-g bayrağı, en üst düzey kernel fonksiyonundan en uçtaki fonksiyona kadar izleyebilmeniz için çağrı grafiklerini yakalar. Aradığınız şeyler:
__do_softirq,net_rx_actionveyatcp_v4_rcvgibi fonksiyonlar → ağ yığını baskısı__blk_run_queue,blk_update_request→ block I/O katmanı__schedule,try_to_wake_up→ scheduler çakışması veya aşırı context switchingfutex_wait_queue_me,rwsem_down_read_slowpath→ lock çakışması
Tam raporu istemediğimde kullandığım pratik bir komut:
perf top
Bu, kernel fonksiyonlarının CPU kullanımına göre canlı ve güncellenen bir görünümünü verir — kernel iç yapıları için top gibi.
İpucu: perf yüklü değilse, kernel sürümünüz için linux-tools paketini kurun. Debian/Ubuntu'da: apt install linux-tools-$(uname -r).
I/O Bekleme Süresinin Kernel CPU Olarak Gizlenmesi
Geçen yıl beni ısıran bir durum. Bir Proxmox sunucusunda top %40 sy ve %30 wa gösteriyordu. Her süreç normal görünüyordu. Meğer ZFS ARC, bir yedekleme işi dönen disklerden soğuk veri okuduğu için çalkalanıyormuş ve kernel bütün zamanını I/O tamamlanmasını bekleyerek block katmanında harcıyormuş.
Kilit tanılama:
iostat -xz 1
Belirli bir cihazda %util değerinin 100'e yakın olmasına ve yüksek await değerlerine bakın. await SSD'lerde 20-30ms'nin üzerindeyse veya HDD'lerde 100ms'nin üzerindeyse, kernel I/O'da bloke oluyor ve o bekleme kuyruğunu yönetirken CPU döngülerini yakıyor demektir.
Kontrol ettiğim diğer araçlar:
vmstat 1—rsütunu (çalışabilir süreçler) yüksek ama CPU %100 user değilse, kernel ağır bir şekilde context-switch yapıyordursar -w 1— context switch oranı; tek bir CPU'da saniyede 50.000'in üzerindeki her şey araştırılmalıdırpidstat -w 1— süreç başına context switch'leri gösterir, suçluyu belirlemeye yardımcı olur
Lock Çakışması ve Scheduler Yükü
Bazen kernel sadece kendini yöneterek CPU yakar. Lock çakışması, birden fazla CPU aynı spinlock veya rwsem için savaştığında olur. Bunu, yüksek syscall oranına sahip yoğun veritabanı sunucularında ve bilinen scheduler hataları olan eski kernel'leri çalıştıran sistemlerde gördüm.
perf, en üstte _raw_spin_lock, queued_spin_lock_slowpath veya rwsem_down_write_slowpath gibi fonksiyonları gösterecektir. Bu olduğunda:
- Kernel sürümünüzü kontrol edin — eski 4.x kernel'lerde yüksek ağ yükü altında bilinen spinlock sorunları vardı
sysctl kernel.sched_migration_cost_nsdeğerine bakın — bunu düşürmek NUMA sistemlerinde scheduler yükünü azaltabilir- Scheduler davranışını özel olarak profilleme için
perf schedkullanın:
perf sched record -- sleep 10
perf sched latency --max
Bu, hangi görevlerin en yüksek zamanlama gecikmesine sahip olduğunu ve hangi CPU'ların bir scheduler perspektifinden aşırı yüklü olduğunu gösterir.
Hedeflenmiş Kernel İzleme için Ftrace
perf size fonksiyon adını verdiğinde ama ne zaman ve ne sıklıkta çağrıldığını görmeniz gerektiğinde, ftrace bir sonraki adımdır. Kernel'in içine yerleşiktir — paket gerekmez.
echo 1 > /sys/kernel/debug/tracing/events/sched/sched_switch/enable
cat /sys/kernel/debug/tracing/trace_pipe | head -50
Bu, context switch olaylarını gerçek zamanlı olarak akar. İki belirli süreç arasında saniyede binlerce switch görüyorsanız, bir zamanlama fırtınası yakalamışsınız demektir.
Fonksiyon seviyesinde izleme için:
echo function > /sys/kernel/debug/tracing/current_tracer
echo tcp_v4_rcv > /sys/kernel/debug/tracing/set_ftrace_filter
echo 1 > /sys/kernel/debug/tracing/tracing_on
Artık tcp_v4_rcv'ye yapılan her çağrı zaman damgasıyla günlüğe kaydedilir. Bunu bir keresinde, hiçbir user-space süreci dahil olmadan kernel CPU sıçramalarına neden olan bir SYN flood'u takip etmek için kullanmıştım.
Hızlı Tanılama Kontrol Listesi
Yüksek CPU için sayfa aldığımda ve süreç listesi temiz göründüğünde, sıram şöyledir:
top%Cpu(s)satırını kontrol edin —syveyawayüksek mi?cat /proc/softirqsvecat /proc/interruptsçalıştırın — tek bir CPU aşırı yüklü mü?- 30 saniye boyunca
perf top— hangi kernel fonksiyonu baskın? iostat -xz 1— bir disk %100 util'de mi?vmstat 1— yüksek context switch'ler mi veya çalışabilir süreçler mi?dmesg | tail— son saatte herhangi bir kernel uyarısı veya hatası var mı?
En sonuncusu bariz görünebilir, ama arızalı bir NIC'ı tekrar tekrar sıfırlayan bir sürücüyü gösteren tek bir dmesg çıktısıyla gizemleri çözdüm. Kernel, süreç listesinde hiçbir zaman görünmeyen hata işleme ve kurtarma döngülerinde CPU harcıyordu.
Kernel-space CPU sorunları, standart araçlar süreçler etrafında inşa edildiği için zor olur. perf, ftrace ve interrupt analiziyle kernel'in kendisini profilleme noktasına geçtiğinizde, kök neden genellikle birkaç dakika içinde ortaya çıkar. Zor olan kısım, oraya bakmayı ilk başta hatırlamaktır.
Kapak görseli: Operate, Defend, Attack, Influence! · PDM (Openverse / kamu malı) · https://www.flickr.com/photos/131622585@N06/48986472741
