stap監控cpu指令碼小結

myownstars發表於2013-06-02

cpu相關probe

cpu()--返回當前CPU number

scheduler.cpu_off--程式在cpu上停止執行時呼叫;task_prev即將離開的程式;task_next即將執行的程式;name--probe point;idle--當前程式是否idle

scheduler.cpu_on--程式在cpu上開始執行時呼叫;task_prev上一個執行的程式;name--probe point;idle當前程式是否idle

scheduler.balance--CPU嘗試尋找更多的任務;name--probe point名字

scheduler.ctxswitch--程式切換時呼叫;prev_id被切換出去的pid;next_id被切換進的pid;prev_task_name/next_task_name;

scheduler.migrate--在cpu間遷移的task;cpu_from源cpu;cpu_to目標cpu;task程式名;pid程式id;priority程式優先順序;

scheduler.process_fork--衍生程式;parent_pid/child_pid

scheduler.wakeup--被喚醒的程式;task_cpu/task_pid/task_priority/task_state

irq_handler.entry/exit--呼叫/退出中斷時觸發;dev_name裝置名;flags--IRQ handler的flags;irq中斷號;dir指向proc/irq/NN/name;handler中斷處理函式

softirq.entry/exit--呼叫/退出軟中斷;vec軟中斷容器;h;vec_nr軟中斷容器號;action軟中斷控制器指標


例1

當系統sys或者cs較高時,可以偵測哪些由哪些程式引起

每秒列印出佔用cpu和程式切換最多的5個任務

#! /usr/bin/env stap

probe scheduler.cpu_on {

  sys_cpu[execname()]++

}

probe scheduler.cpu_off {

  cs_cpu[task_prev,task_next]++

}

probe timer.s(1) {

  foreach (taskname in sys_cpu- limit 5) {

    printf(" %s execute %d times on cpu %d ",taskname,sys_cpu[task_prev])

  )

  foreach ([prename,nextname] in cs_cpu- limit 5) {

    printf(" s%[d%] --&gt s%[d%], total count d% ", task_execname(task_prev),task_pid(task_prev),task_execname(task_next),task_pid(task_next),cs_cpu[task_prev,task_next])

  }

}


例2

--smp_call_function

當程式申請跨CPU中斷時需要呼叫此函式,相當消耗較高

# stap scf.stp -c "sleep 0.2"

#! /usr/bin/env stap

global traces

probe begin { printf(" starting, press ctrl + c to stop\n") }

probe kernel.function("smp_call_function") { 

  traces[pid(), pexecname(), backtrace()] ++ 

}

probe end {

  foreach ([pid, name, stack] in traces-) { --按出現頻率排序

    printf("trace[%d,%s,\n",pid,name)

    printf_syms(stack)

    printf("] =%d\n", traces[pid,name,stack])

  }

}

process/chng_cpu.stp 

以任務名作為輸入引數,當其切換cpu時記錄當前CPU和執行緒id,以及被觸發的核心函式

#stap chng_cpu.stp -c "sleep 0.2" bash

#! /usr/bin/env stap

global threads

probe scheduler.cpu_on{

  if(threads[pid()] != cpu() && execname == @1) {

    printf("\nthread %d (%s) context switched on cpu%d state: %d\n", tid(),execname(),cpu(),task_state(task_current()));

    print_sysm(backtrace());

    thread[pid] = cpu();

  }

}

--print_sysm用於列印核心棧

process/migrate.stp

跟蹤在CPU間遷移的任務,輸入引數為程式名

#! /usr/bin/env stap

probe kernel.function("_migrate_task") {

  comm = kernel_string($p->comm);

  if (comm == @1) {

    printf("thread %d(%s) is migrating from %d to %d\n", pid(),comm,$src_cpu,$dest_cpu);

  }

}

interrupt/interrupts-by-dev.stp

每秒查獲發起中斷的裝置並按頻率排序

# stap interrupts-by-dev.stp -c "sleep 0.2"

#! /usr/bin/env stap

global devices

probe irq_handler.entry {

  devices[dev_name]++;

}

probe timer.ms(100) {

  foreach (devname in devices-) {

    printf(" %20s : %5d \n", kernel_string(devname),devices[dev_name]);

  }

}

很帥的一個案例

http://blog.yufeng.info/archives/2037  

背景:

Mysql伺服器使用倆千兆網路卡繫結做LB,資料庫流量可達150M;

壓力測試發現一個cpu core很繁忙,透過mpstat顯示soft%佔用率很高;

以下是解決思路:

OS為RH 6.1

檢視現有網路卡設定,呼叫lspci檢視PCI匯流排資訊

檢視 /proc/net/bonding/bond0,兩個網路卡繫結方式為active – backup

 

檢視中斷/軟中斷資訊 /proc/interrupts 和/proc/softirqs

粗略瀏覽可以驗證各個CPU core的NET_TX/NET_RX不是太均衡

 

編寫簡單的stap指令碼並呼叫stap再次檢測

獲知硬解析是均衡的 是軟解析的問題, 同時用到addr2line命令

 

其餘命令

lscpu –多核CPU檢視core的對應關係

Dmesg

Service irqbalance stop

解決方案:

採用多佇列萬M網路卡 / 採用google 的RPS patch分散軟中斷

採用簡易指令碼—事後確認由於有硬體中斷平衡,不需要該指令碼,而是採用另外一個

$cat em.sh  

#! /bin/bash                                                 

for i in `seq 0 7` 

do

  echo f|sudo tee /sys/class/net/em1/queues/rx-$i/rps_cpus >/dev/null 

  echo f|sudo tee /sys/class/net/em2/queues/rx-$i/rps_cpus >/dev/null  

done

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-762746/,如需轉載,請註明出處,否則將追究法律責任。

相關文章