stap监控cpu脚本小结

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/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/15480802/viewspace-762746/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值