├── syscalls.stp ├── doc ├── netdevstap.txt ├── vfsstap.txt ├── stap.man ├── syscallstap.txt └── kerneltrace.txt ├── tcp_conn.stp ├── install-stp ├── udpdump.stp ├── probe-alias.stp ├── ngxconn.stp ├── topsys.stp ├── tcpdump.stp ├── cswmon.stp ├── inodewatch.stp ├── iointervals.stp ├── sigkill.stp ├── ioblktime.stp ├── dropwatch.stp ├── fedora-install.sh ├── leaks.stp ├── pstree.stp ├── nettop.stp ├── README.md ├── systemtap-setup.pl ├── get-dbgsym ├── kmalloc-top ├── tcp-recv-queue ├── stpscript2ko.pl ├── stpscripts2ko.pl ├── tcp-accept-queue └── viewcache.stp /syscalls.stp: -------------------------------------------------------------------------------- 1 | ##################usage################# 2 | # sudo stap -c ls syscalls.stp 3 | # 4 | 5 | probe syscall.* { 6 | println(thread_indent(4), "->", probefunc()) 7 | } 8 | 9 | probe syscall.*.return { 10 | println(thread_indent(-4), "<-", probefunc()) 11 | } 12 | -------------------------------------------------------------------------------- /doc/netdevstap.txt: -------------------------------------------------------------------------------- 1 | netdev.change_mac 2 | netdev.change_mtu 3 | netdev.change_rx_flag 4 | netdev.close 5 | netdev.get_stats 6 | netdev.hard_transmit 7 | netdev.ioctl 8 | netdev.open 9 | netdev.receive 10 | netdev.register 11 | netdev.rx 12 | netdev.set_promiscuity 13 | netdev.transmit 14 | netdev.unregister 15 | -------------------------------------------------------------------------------- /doc/vfsstap.txt: -------------------------------------------------------------------------------- 1 | ######### stap -l 'vfs.*' 2 | 3 | vfs.__set_page_dirty_buffers 4 | vfs.add_to_page_cache 5 | vfs.block_sync_page 6 | vfs.buffer_migrate_page 7 | vfs.do_mpage_readpage 8 | vfs.do_sync_read 9 | vfs.do_sync_write 10 | vfs.read 11 | vfs.readv 12 | vfs.remove_from_page_cache 13 | vfs.write 14 | vfs.writev 15 | -------------------------------------------------------------------------------- /tcp_conn.stp: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env stap 2 | 3 | probe begin { 4 | printf("%6s %16s %6s %6s %16s\n", 5 | "UID", "CMD", "PID", "PORT", "IP_SOURCE") 6 | } 7 | 8 | probe kernel.function("tcp_accept").return?, 9 | kernel.function("inet_csk_accept").return? { 10 | sock = $return 11 | if (sock != 0) 12 | printf("%6d %16s %6d %6d %16s\n", uid(), execname(), pid(), 13 | inet_get_local_port(sock), inet_get_ip_source(sock)) 14 | } 15 | -------------------------------------------------------------------------------- /doc/stap.man: -------------------------------------------------------------------------------- 1 | man page for systemtap 2 | ---------------------------------- 3 | man stapfuncs 4 | man stapprobes 5 | man stapex 6 | man stapvars 7 | man stappaths 8 | man stap 9 | man staprun 10 | 11 | To list the probeable functions in the kernel, use the listings mode. 12 | % stap -l 'kernel.function("*")' 13 | 14 | To list the probeable functions and local variables in the kernel, 15 | use another listings mode. 16 | % stap -L 'kernel.function("*")' 17 | 18 | man stap-server 19 | -------------------------------------------------------------------------------- /install-stp: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SYSTEMTAP_VERSION="2.6" 4 | 5 | sudo apt-get install \ 6 | zlib1g-dev \ 7 | elfutils \ 8 | libdw-dev 9 | 10 | ( 11 | cd /tmp 12 | 13 | if [[ ! -d /tmp/systemtap-$SYSTEMTAP_VERSION ]]; then 14 | wget https://sourceware.org/systemtap/ftp/releases/systemtap-$SYSTEMTAP_VERSION.tar.gz 15 | fi 16 | 17 | tar xzf systemtap-$SYSTEMTAP_VERSION.tar.gz 18 | cd systemtap-$SYSTEMTAP_VERSION 19 | 20 | ./configure 21 | make -j4 22 | sudo make install 23 | ) 24 | -------------------------------------------------------------------------------- /udpdump.stp: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env stap 2 | 3 | # A UDP dump like example 4 | # * sock - process id 5 | # * size - size of udp packet 6 | # Usage: 7 | # sudo stap udpdump.stp 8 | 9 | probe begin, timer.s(3) { 10 | ansi_clear_screen() 11 | printf("--------------------------------------------\n") 12 | printf(" Process name size \n") 13 | printf("--------------------------------------------\n") 14 | } 15 | 16 | probe udp.recvmsg { 17 | printf(" %15d %15d\n", 18 | sock, size) 19 | } 20 | 21 | -------------------------------------------------------------------------------- /probe-alias.stp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/stap 2 | 3 | global groups 4 | 5 | probe begin { 6 | printf("Collecting data... press Ctrl-C to stop.\n") 7 | } 8 | 9 | probe syscallgroup.io = syscall.open, syscall.close, 10 | syscall.read, syscall.write 11 | { groupname = "io" } 12 | 13 | probe syscallgroup.process = syscall.fork, syscall.execve 14 | { groupname = "process" } 15 | 16 | probe syscallgroup.* 17 | { groups [execname() . "/" . groupname]++ } 18 | 19 | probe end { 20 | foreach(eg+ in groups) 21 | printf("%s: %d\n", eg, groups[eg]) 22 | } 23 | 24 | -------------------------------------------------------------------------------- /ngxconn.stp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env stap 2 | # 3 | ######################################## 4 | 5 | probe process("/usr/sbin/nginx").function("ngx_process_events_and_timers"), 6 | process("/usr/sbin/nginx").function("ngx_http_handler") { 7 | if (pid() == target()) { 8 | cycle = &@var("ngx_cycle\@ngx_cycle.c") 9 | 10 | println("=====CONNECTIONS======") 11 | println("Max connections: ", cycle->connection_n) 12 | println("Free connections: ", cycle->free_connection_n) 13 | println("Used connections: ", cycle->connection_n - cycle->free_connection_n) 14 | } 15 | 16 | exit() 17 | } 18 | -------------------------------------------------------------------------------- /topsys.stp: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env stap 2 | # 3 | # This script continuously lists the top 20 systemcalls in the interval 4 | # 5 seconds 5 | # 6 | 7 | global syscalls_count 8 | 9 | probe syscall.* { 10 | syscalls_count[name]++ 11 | } 12 | 13 | function print_systop () { 14 | printf ("%25s %10s\n", "SYSCALL", "COUNT") 15 | foreach (syscall in syscalls_count- limit 20) { 16 | printf("%25s %10d\n", syscall, syscalls_count[syscall]) 17 | } 18 | delete syscalls_count 19 | } 20 | 21 | probe timer.s(5) { 22 | print_systop () 23 | printf("--------------------------------------------------------------\n") 24 | } 25 | -------------------------------------------------------------------------------- /tcpdump.stp: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env stap 2 | 3 | # A TCP dump like example 4 | # * urg - urgent 5 | # * ack - acknowledgement 6 | # * psh - push 7 | # * rst - reset 8 | # * syn - synchronize 9 | # * fin - finished 10 | # Usage: 11 | # sudo stap tcpdump.stp 12 | 13 | probe begin, timer.s(1) { 14 | ansi_clear_screen() 15 | printf("-----------------------------------------------------------------\n") 16 | printf(" Source IP Dest IP SPort DPort U A P R S F \n") 17 | printf("-----------------------------------------------------------------\n") 18 | } 19 | 20 | probe tcp.receive { 21 | printf(" %15s %15s %5d %5d %d %d %d %d %d %d\n", 22 | saddr, daddr, sport, dport, urg, ack, psh, rst, syn, fin) 23 | } 24 | 25 | -------------------------------------------------------------------------------- /cswmon.stp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env stap 2 | # 3 | ######################################## 4 | # sudo stap cswmon.stp 5 5 | 6 | global csw_count 7 | global idle_count 8 | 9 | probe scheduler.cpu_off { 10 | csw_count[task_prev, task_next]++ 11 | idle_count+=idle 12 | } 13 | 14 | function fmt_task(task_prev, task_next) { 15 | return sprintf("%s(%d)->%s(%d)", 16 | task_execname(task_prev), 17 | task_pid(task_prev), 18 | task_execname(task_next), 19 | task_pid(task_next)) 20 | } 21 | 22 | function print_cswtop () { 23 | printf ("%45s %10s\n", "Context switch", "COUNT") 24 | foreach ([task_prev, task_next] in csw_count- limit 20) { 25 | printf("%45s %10d\n", fmt_task(task_prev, task_next), 26 | csw_count[task_prev, task_next]) 27 | } 28 | 29 | printf("%45s %10d\n", "idle", idle_count) 30 | delete csw_count 31 | delete idle_count 32 | } 33 | 34 | probe timer.s($1) { 35 | print_cswtop () 36 | printf("————————————————————–\n") 37 | } 38 | -------------------------------------------------------------------------------- /inodewatch.stp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env stap 2 | 3 | #look up which process write or read from file(filename); 4 | 5 | # construct the scene: 6 | # rm -f test.dat && dd if=/dev/zero of=test.dat 7 | # look up inode of test.dat 8 | # stat -c '%i' test.dat 9 | 10 | # look the file of test.dat: major minor number 11 | # df 12 | # if lvm,look up device mapper like this: 13 | # ls -l /dev/disk/by-uuid/ff84db67-7d11-4732-ba0c-8681536dedd4 14670308 14 | # /dev/disk/by-uuid/ff84db67-7d11-4732-ba0c-8681536dedd4 -> ../../sda1 15 | # ls -l /dev/sdb1 16 | # brw-rw---- 1 root disk 8, 1 Feb 26 10:58 /dev/sda1 17 | # just like above output: major:8 and minor:1 18 | 19 | # run this script 20 | # sudo stap inodewatch.stp 21 | # eg: 22 | # sudo stap inodewatch.stp 8 1 789137 23 | 24 | probe vfs.write, vfs.read 25 | { 26 | # dev and ino are defined by vfs.write and vfs.read 27 | if (dev == MKDEV($1,$2) # major/minor device 28 | && ino == $3) 29 | printf ("%s(%d) %s 0x%x/%u\n", 30 | execname(), pid(), probefunc(), dev, ino) 31 | } 32 | -------------------------------------------------------------------------------- /iointervals.stp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env stap 2 | # iointervals.stp 3 | # Track time intervals for a subset of kernel 4 | # functions. Based on func_time_stats.stp. 5 | 6 | global startcall, intervals 7 | 8 | # apply multiple probe points when the call enter: 9 | probe syscall.open, syscall.close , 10 | syscall.read, syscall.write 11 | { 12 | startcall[name, tid()] = gettimeofday_us() 13 | } 14 | 15 | # when the call return, calculate the intervals: 16 | probe syscall.open.return, syscall.close.return, 17 | syscall.read.return, syscall.write.return 18 | { 19 | t = gettimeofday_us() 20 | old_t = startcall[name, tid()] 21 | if (old_t) intervals[name] <<< t - old_t 22 | delete startcall[name, tid()] 23 | } 24 | 25 | probe begin { 26 | printf("Collecting data... press Ctrl-C to stop.\n") 27 | } 28 | 29 | # when terminal the running, display the infomation. 30 | probe end { 31 | foreach (name in intervals) { 32 | printf("intervals for %s -- min:%dus avg:%dus max:%dus count:%d\n", 33 | name, @min(intervals[name]), @avg(intervals[name]), 34 | @max(intervals[name]), @count(intervals[name])) 35 | print(@hist_log(intervals[name])) 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /sigkill.stp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/stap 2 | # sigkill.stp 3 | # Copyright (C) 2007 Red Hat, Inc., Eugene Teo 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License version 2 as 7 | # published by the Free Software Foundation. 8 | # 9 | # /usr/share/systemtap/tapset/signal.stp: 10 | # [...] 11 | # probe signal.send = _signal.send.* 12 | # { 13 | # sig=$sig 14 | # sig_name = _signal_name($sig) 15 | # sig_pid = task_pid(task) 16 | # pid_name = task_execname(task) 17 | # [...] 18 | 19 | probe signal.send { 20 | if (sig_name == "SIGTERM" || sig_name == "SIGKILL") { 21 | printf("%s was sent to %s (pid:%d) by %s uid:%d time:%dus\n", 22 | sig_name, pid_name, sig_pid, execname(), uid(), gettimeofday_us()) 23 | printf("cmdline_arg(0) = %s\n", cmdline_arg(0)) 24 | printf("cmdline_arg(1) = %s\n", cmdline_arg(1)) 25 | printf("cmdline_arg(2) = %s\n", cmdline_arg(2)) 26 | printf("cmdline_arg(3) = %s\n", cmdline_arg(3)) 27 | printf("cmdline_arg(4) = %s\n", cmdline_arg(4)) 28 | printf("cmdline_arg(5) = %s\n", cmdline_arg(5)) 29 | 30 | printf("cmdline_str = %s\n", cmdline_str()) 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ioblktime.stp: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env stap 2 | 3 | ######################################################### 4 | # ioblktime.stp computes the average waiting time 5 | # for block I/O per device, and prints a list 6 | # every 10 seconds. 7 | # 8 | # Usage: 9 | # sudo stap ioblktime.stp -DMAXMAPENTRIES=10000. 10 | 11 | global req_time, etimes 12 | 13 | probe ioblock.request 14 | { 15 | req_time[$bio] = gettimeofday_us() 16 | } 17 | 18 | probe ioblock.end 19 | { 20 | t = gettimeofday_us() 21 | s = req_time[$bio] 22 | delete req_time[$bio] 23 | if(s) { 24 | etimes[devname, bio_rw_str(rw)] <<< t - s 25 | } 26 | } 27 | 28 | /* for time being delete things that get merged with others */ 29 | probe kernel.trace("block_bio_frontmerge"), 30 | kernel.trace("block_bio_backmerge") 31 | { 32 | delete req_time[$bio] 33 | } 34 | 35 | probe timer.s(10), end { 36 | ansi_clear_screen() 37 | printf("%10s %3s %10s %10s %10s\n", 38 | "device", "rw", "total(us)", "count", "avg(us)") 39 | foreach ([dev,rw] in etimes - limit 20) { 40 | printf("%10s %3s %10d %10d %10d\n", dev, rw, 41 | @sum(etimes[dev,rw]), @count(etimes[dev,rw]), @avg(etimes[dev,rw])) 42 | } 43 | delete etimes 44 | } 45 | 46 | -------------------------------------------------------------------------------- /dropwatch.stp: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env stap 2 | 3 | ############################################################ 4 | # Dropwatch.stp 5 | # Author: Neil Horman 6 | # An example script to mimic the behavior of the dropwatch utility 7 | # http://fedorahosted.org/dropwatch 8 | # 9 | # sudo stap --all-modules dropwatch.stp 10 | ############################################################ 11 | 12 | # Array to hold the list of drop points we find 13 | global locations, loc 14 | 15 | # Note when we turn the monitor on and off 16 | probe begin { printf("Monitoring for dropped packets\n") } 17 | probe end { printf("Stopping dropped packet monitor\n") } 18 | 19 | # increment a drop counter for every location we drop at 20 | # probe kernel.trace("kfree_skb") { locations[$location] <<< 1 } 21 | probe kfree_skb_1 = kernel.trace("kfree_skb") {loc = $location} 22 | probe kfree_skb_2 = kernel.function("kfree_skb") {loc = return_addr()} 23 | probe kfree_skb_1!, kfree_skb_2 {locations[loc] <<< 1} 24 | 25 | # Every 5 seconds report our drop locations 26 | probe timer.sec(5) 27 | { 28 | printf("\n") 29 | foreach (l in locations-) { 30 | printf("%d packets dropped at %s\n", 31 | @count(locations[l]), symname(l)) 32 | } 33 | delete locations 34 | } 35 | 36 | -------------------------------------------------------------------------------- /fedora-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | AUTO_INVOKE_SUDO=yes; 4 | curdir=$(dirname $(readlink -f $0)); 5 | 6 | function invoke_sudo() 7 | { 8 | if [ "`id -u`" != "`id -u $1`" ]; then 9 | echo "`whoami`:you need to be $1 privilege to run this script."; 10 | if [ "$AUTO_INVOKE_SUDO" == "yes" ]; then 11 | echo "Invoking sudo ..."; 12 | sudo -u "#`id -u $1`" bash -c "$2"; 13 | fi 14 | exit 0; 15 | fi 16 | } 17 | 18 | uid=`id -u` 19 | if [ $uid -ne '0' ]; then 20 | invoke_sudo root "${curdir}/$0 $@" 21 | fi 22 | #------------------------------------------------------------------------------ 23 | # Prerequisites 24 | #------------------------------------------------------------------------------ 25 | 26 | #------------------------------------------------------------------------------ 27 | # Install 28 | #------------------------------------------------------------------------------ 29 | # Development 30 | yum -y install systemtap 31 | debuginfo-install kernel 32 | yum -y install systemtap-runtime 33 | yum -y install kernel-devel 34 | yum -y install systemtap-client 35 | yum -y install systemtap-devel 36 | yum -y install kernel-debug-devel 37 | yum -y install kernel-debug-debuginfo 38 | yum -y install wget 39 | yum -y install dpkg 40 | 41 | -------------------------------------------------------------------------------- /leaks.stp: -------------------------------------------------------------------------------- 1 | global ptr2bt 2 | global ptr2size 3 | global bt_stats 4 | global quit 5 | 6 | probe begin { 7 | warn("Start tracing. Wait for 10 sec to complete.\n") 8 | } 9 | 10 | probe process("/lib*/libc.so*").function("malloc").return { 11 | if (pid() == target()) { 12 | if (quit) { 13 | foreach (bt in bt_stats) { 14 | print_ustack(bt) 15 | printf("\t%d\n", @sum(bt_stats[bt])) 16 | } 17 | 18 | exit() 19 | 20 | } else { 21 | 22 | //printf("malloc: %p (bytes %d)\n", $return, $bytes) 23 | ptr = $return 24 | bt = ubacktrace() 25 | ptr2bt[ptr] = bt 26 | ptr2size[ptr] = $bytes 27 | bt_stats[bt] <<< $bytes 28 | } 29 | } 30 | } 31 | 32 | probe process("/lib*/libc.so*").function("free") { 33 | if (pid() == target()) { 34 | //printf("free: %p\n", $mem) 35 | ptr = $mem 36 | 37 | bt = ptr2bt[ptr] 38 | delete ptr2bt[ptr] 39 | 40 | bytes = ptr2size[ptr] 41 | delete ptr2size[ptr] 42 | 43 | bt_stats[bt] <<< -bytes 44 | if (@sum(bt_stats[bt]) == 0) { 45 | delete bt_stats[bt] 46 | } 47 | } 48 | } 49 | 50 | probe timer.s(10) { 51 | quit = 1 52 | delete ptr2bt 53 | delete ptr2size 54 | } 55 | -------------------------------------------------------------------------------- /pstree.stp: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env stap 2 | # Copyright (C) 2014 Red Hat, Inc. 3 | # by Josh Stone 4 | # 5 | # pstree.stp generates a process diagram in DOT form. For instance, it may be 6 | # useful on a 'make' command to see all the processes that are started. 7 | # 8 | # Run the script with: 9 | # stap pstree.stp -c 'command_to_watch' -o output.dot 10 | # 11 | # Render the diagram with: 12 | # dot -Tsvg output.dot >output.svg 13 | 14 | probe begin 15 | { 16 | printf("digraph pstree {\n") 17 | printf("rankdir=\"LR\"\n") 18 | } 19 | 20 | function dot_escape(str) 21 | { 22 | # In DOT double-quoted strings, the only escape is " to \" 23 | return str_replace(str, "\"", "\\\"") 24 | } 25 | 26 | global depth 27 | probe process.begin 28 | { 29 | if (!(pid() in depth)) { 30 | depth[pid()] = 1 31 | if (pid() != target()) 32 | printf("PID%d_%d -> PID%d_1\n", ppid(), depth[ppid()], pid()) 33 | printf("PID%d_1 [ label=\"(%d) %s\" tooltip=\"forked from %d\" ];\n", 34 | pid(), pid(), dot_escape(execname()), ppid()) 35 | } 36 | } 37 | 38 | probe syscall.execve.return 39 | { 40 | if ($return == 0 && pid() in depth) { 41 | d = ++depth[pid()] 42 | printf("PID%d_%d -> PID%d_%d [ style=\"dashed\" ];\n", 43 | pid(), d-1, pid(), d) 44 | printf("PID%d_%d [ label=\"(%d) %s\" tooltip=\"%s\" ];\n", 45 | pid(), d, pid(), 46 | dot_escape(@entry(user_string($filename))), 47 | dot_escape(cmdline_str())) 48 | } 49 | } 50 | 51 | probe end 52 | { 53 | printf("}\n") 54 | } 55 | -------------------------------------------------------------------------------- /nettop.stp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env stap 2 | ##############usage################# 3 | # sudo stap nettop.stp 4 | # 5 | 6 | global ifxmit, ifrecv 7 | global ifmerged 8 | 9 | probe netdev.transmit 10 | { 11 | ifxmit[pid(), dev_name, execname(), uid()] <<< length 12 | } 13 | 14 | probe netdev.receive 15 | { 16 | ifrecv[pid(), dev_name, execname(), uid()] <<< length 17 | } 18 | 19 | function print_activity() 20 | { 21 | ansi_clear_screen() 22 | printf("%5s %5s %-7s %7s %7s %7s %7s %-15s\n", 23 | "PID", "UID", "DEV", "XMIT_PK", "RECV_PK", 24 | "XMIT_B", "RECV_B", "COMMAND") 25 | 26 | foreach ([pid, dev, exec, uid] in ifrecv) { 27 | ifmerged[pid, dev, exec, uid] += @count(ifrecv[pid,dev,exec,uid]); 28 | } 29 | foreach ([pid, dev, exec, uid] in ifxmit) { 30 | ifmerged[pid, dev, exec, uid] += @count(ifxmit[pid,dev,exec,uid]); 31 | } 32 | foreach ([pid, dev, exec, uid] in ifmerged-) { 33 | n_xmit = @count(ifxmit[pid, dev, exec, uid]) 34 | n_recv = @count(ifrecv[pid, dev, exec, uid]) 35 | if(n_xmit) { 36 | t_xmit = @sum(ifxmit[pid, dev, exec, uid]); 37 | if(t_xmit > 1024){ 38 | t_xmit = t_xmit / 1024; 39 | str_txmit = sprint(t_xmit) . "K"; 40 | } else { 41 | str_txmit = sprint(t_recv); 42 | } 43 | } else { 44 | str_txmit = "0"; 45 | } 46 | if(n_recv) { 47 | t_recv = @sum(ifrecv[pid, dev, exec, uid]); 48 | if(t_recv > 1024){ 49 | t_recv = t_recv / 1024; 50 | str_trecv = sprint(t_recv) . "K"; 51 | } else { 52 | str_trecv = sprint(t_recv); 53 | } 54 | } else { 55 | str_trecv = "0"; 56 | } 57 | printf("%5d %5d %-7s %7d %7d %7s %7s %-15s\n", 58 | pid, uid, dev, n_xmit, n_recv, str_txmit, str_trecv, exec) 59 | } 60 | 61 | print("\n") 62 | 63 | delete ifxmit 64 | delete ifrecv 65 | delete ifmerged 66 | } 67 | 68 | probe timer.ms(5000), end, error 69 | { 70 | print_activity() 71 | } 72 | 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | systemtap-script 2 | ================ 3 | 4 | useful systemtap script. 5 | just for study. 6 | 7 | setup for ubuntu: 8 | 9 | 1.install systemtap 10 | 11 | $sudo apt-get install systemtap 12 | $sudo apt-get install systemtap-runtime 13 | 14 | 2.install kernel-debug-info 15 | 16 | use source-list: 17 | (1)Install the Linux kernel debug image 18 | ---------------------------------------------------------- 19 | Add debug source to the sources list of Ubuntu 20 | 21 | Create an /etc/apt/sources.list.d/ddebs.list by running the following line at 22 | a terminal: 23 | echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse" | \ 24 | sudo tee -a /etc/apt/sources.list.d/ddebs.list 25 | 26 | Stable releases (not alphas and betas) require three more lines adding to the 27 | same file, which is done by the following terminal command: 28 | echo "deb http://ddebs.ubuntu.com $(lsb_release -cs)-updates main restricted universe multiverse 29 | deb http://ddebs.ubuntu.com $(lsb_release -cs)-security main restricted universe multiverse 30 | deb http://ddebs.ubuntu.com $(lsb_release -cs)-proposed main restricted universe multiverse" | \ 31 | sudo tee -a /etc/apt/sources.list.d/ddebs.list 32 | 33 | Import the debug symbol archive signing key: 34 | sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 428D7C01 35 | 36 | Then run: 37 | sudo apt-get update 38 | 39 | Get Linux kernel debug image 40 | sudo apt-get install linux-image-$(uname -r)-dbgsym 41 | 42 | -------------------------------------------------------- 43 | (2)General ddeb repository configuration 44 | # cat > /etc/apt/sources.list.d/ddebs.list << EOF 45 | deb http://ddebs.ubuntu.com/ precise main restricted universe multiverse 46 | EOF 47 | 48 | # apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ECDCAD72428D7C01 49 | # apt-get update 50 | 51 | download url: 52 | ubuntu kernel-debug-info: http://ddebs.ubuntu.com/pool/main/l/linux/ 53 | 54 | setup for fedora: 55 | 56 | yum install systemtap kernel-devel debuginfo-install kernel 57 | 58 | 59 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/soarpenguin/systemtap-script/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 60 | 61 | -------------------------------------------------------------------------------- /systemtap-setup.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # 3 | 4 | use strict; 5 | use Term::ANSIColor; 6 | #use Smart::Comments; 7 | 8 | my $user = `whoami`; 9 | chomp($user); 10 | ### $user 11 | my $password; 12 | ### $password 13 | 14 | if( $> != '0') { 15 | #&noecho(); 16 | #print "password for $user: "; 17 | #$password = <>; 18 | #&echo(); 19 | # 20 | #`sudo -s << "EOF" $password EOF perl $0;`; 21 | #print "\n$password\n"; 22 | &myprint("Must be root to run this script."); 23 | exit; 24 | } 25 | 26 | &main(); 27 | 28 | sub main { 29 | my $uname = `uname -r`; 30 | chomp($uname); 31 | my $error = 0; 32 | 33 | my @softlist = ('systemtap', 34 | 'systemtap-runtime', 35 | 'kernel-debuginfo', 36 | 'kernel-debuginfo-common', 37 | 'kernel-devel'); 38 | foreach my $soft (@softlist) { 39 | if($soft =~ /kernel/) { 40 | $soft .= "-$uname"; 41 | if(&install($soft) != 0) { 42 | $error = 1; 43 | } 44 | } else { 45 | if(&install($soft) != 0) { 46 | $error = 1; 47 | } 48 | } 49 | } 50 | 51 | if($error) { 52 | &myprint("Systemtap setup unsuccessful.\n"); 53 | } else { 54 | &yesinstall("Systamtap setup successful.\n"); 55 | } 56 | } 57 | 58 | sub noecho { 59 | print `stty -echo` 60 | } 61 | 62 | sub echo { 63 | print `stty sane` 64 | } 65 | 66 | sub install { 67 | my $soft = shift; 68 | ### $soft 69 | my $result; 70 | 71 | $result = `yum install -y $soft 2>&1`; 72 | if($result =~ "already installed" or $result =~ "Installed:" 73 | or $result =~ "Updated:" or $result =~ "already" 74 | or $result =~ "newly installed") { 75 | print color("blue"); 76 | print("+++The $soft installed successful.\n\n"); 77 | print color("reset"); 78 | $result = 0; 79 | } elsif ($result =~ "No package $soft available") { 80 | &myprint("Check the name of software: $soft\n"); 81 | $result = 1; 82 | } elsif ($result =~ "need to be root") { 83 | &myprint("Need to be root to install $soft.\n"); 84 | $result = 1; 85 | }else { 86 | &myprint("$result\n"); 87 | $result = 0; 88 | } 89 | 90 | return $result; 91 | } 92 | 93 | sub myprint { 94 | print color("red"); 95 | print("@_ \n"); 96 | print color("reset"); 97 | } 98 | 99 | sub yesinstall { 100 | print color("green"); 101 | print("@_ \n"); 102 | print color("reset"); 103 | } 104 | -------------------------------------------------------------------------------- /get-dbgsym: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #============================= get-dbgsym ====================================# 4 | # 5 | # Helper script for systemtap on Ubuntu. 6 | # It downloads and installs the debug image of the running kernel. 7 | # 8 | # Copyright Loic Domaigne , 9 | # Licensed under the Apache License, Version 2.0. 10 | # 11 | #=============================================================================# 12 | 13 | #--------------------------------------------------------------- 14 | # helper function for showing error 15 | #--------------------------------------------------------------- 16 | function error() { echo -e "\n$(tput bold)$(tput setaf 1)!!! ERROR !!! $(tput sgr0)"; return 0; } 17 | 18 | 19 | #--------------------------------------------------------------- 20 | # a few global variables 21 | #--------------------------------------------------------------- 22 | POOL="http://ddebs.ubuntu.com/pool/main/l/linux/" 23 | PKG_DIR=~/dpkg 24 | 25 | WGET=/usr/bin/wget 26 | MKDIR=/bin/mkdir 27 | RM=/bin/rm 28 | SUDO=/usr/bin/sudo 29 | DPKG=/usr/bin/dpkg 30 | 31 | #--------------------------------------------------------------- 32 | # check my architecture 33 | #--------------------------------------------------------------- 34 | HW=`uname -m` 35 | case "${HW}" in 36 | i386) 37 | ARCH="i386" 38 | ;; 39 | i686) 40 | ARCH="i386" 41 | ;; 42 | x86_64) 43 | ARCH="amd64" 44 | ;; 45 | *) 46 | error 47 | echo "-> Unknow architecture ${HW}" 48 | echo " please informs me at www.domaigne.com" 49 | echo 50 | exit 1 51 | esac 52 | echo "Architecture for kernel: ${ARCH}" 53 | 54 | #-------------------------------------------------------------- 55 | # check if image is already installed 56 | #-------------------------------------------------------------- 57 | KERNEL="linux-image-$(uname -r)-dbgsym" 58 | ${DPKG} -l "${KERNEL}" > /dev/null 59 | [ $? -eq 0 ] && echo "${KERNEL} is already installed. Quitting." && exit 0 60 | 61 | #--------------------------------------------------------------- 62 | # find matching kernel with debug symbols in pool 63 | #--------------------------------------------------------------- 64 | 65 | # note: there might be several dbgsym kernel in the pool for the 66 | # installed kernel. pick the latest one (tail -n 1) 67 | # 68 | # thanks to ysoh2 69 | 70 | DBG_KERNEL_LINK=`${WGET} ${POOL} -O - 2> /dev/null | grep "${KERNEL}" | grep ${ARCH} | sed 's/^.*href=\"//g' | sed 's/\".*$//g' | tail -n 1` 71 | 72 | #-------------------------------------------------------------- 73 | # if nothing found, abort 74 | #-------------------------------------------------------------- 75 | [ x"$DBG_KERNEL_LINK" == "x" ] && error && echo -e "-> Problem while looking for ${KERNEL}\n - either I could not connect to ${POOL}\n - or the kernel couldn't be found there" && exit 2 76 | 77 | #-------------------------------------------------------------- 78 | # change to ${PKG_DIR} (create if doesn't exist) 79 | #-------------------------------------------------------------- 80 | pushd . > /dev/null 81 | if [ ! -d ${PKG_DIR} ] 82 | then 83 | ${MKDIR} ${PKG_DIR} 84 | [ $? -ne 0 ] && error && echo "-> could not create ${PKG_DIR}" && exit 3 85 | fi 86 | cd ${PKG_DIR} 87 | [ $? -ne 0 ] && error && echo "-> could not change to directory ${PKG_DIR}" && exit 3 88 | 89 | #-------------------------------------------------------------- 90 | # load kernel with debug symbols from POOL 91 | #-------------------------------------------------------------- 92 | ${RM} ${DBG_KERNEL_LINK} 93 | ${WGET} ${POOL}/${DBG_KERNEL_LINK} 94 | RC=$? 95 | [ $RC -ne 0 ] && error && echo "-> failed to wget ${DBG_KERNEL_LINK} (code returned:$RC)" && popd && exit 4 96 | 97 | #-------------------------------------------------------------- 98 | # install the kernel 99 | #-------------------------------------------------------------- 100 | ${SUDO} ${DPKG} -i ${DBG_KERNEL_LINK} 101 | RC=$? 102 | [ $RC -ne 0 ] && echo -e "->package installation failed (code:$RC)" && popd && exit 5 103 | 104 | #-------------------------------------------------------------- 105 | # that's all folks! 106 | #-------------------------------------------------------------- 107 | popd 108 | exit 0 109 | -------------------------------------------------------------------------------- /kmalloc-top: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # This script accumulates the execution paths of all calls to kmalloc 4 | # in the kernel. On Ctrl-C (or exit of the command provided by -c option), 5 | # it sorts, filters and displays them on 6 | # stdout. 7 | # 8 | # The -e (exclude) option can be used to specify a comma-separated list 9 | # - any stack with contents matching any of the items in the list will 10 | # be excluded from the output. 11 | # 12 | # The -m (min) option can be used to specify the minimum number of 13 | # occurrences a stack needs to be included in the output. 14 | # 15 | # The -t (top) option can be used to specify printing only the 16 | # top N stack traces. 17 | # 18 | # The -c (command) option runs starts the command and script 19 | # only runs for the duration of the command. 20 | # 21 | # The -o (options) option passes the options to systemap. 22 | # 23 | # Usage: ./kmalloc-top [-m min] [-e exclude list] [-t top_n] [-c command] 24 | # [-o options] 25 | # Ctrl-c 26 | 27 | use Getopt::Std; 28 | 29 | my $kmalloc_stacks; 30 | my $total_kmallocs; 31 | my $filtered_kmallocs; 32 | my $sorted_stacks; 33 | my $first_n = 1000000000; 34 | my $min_count = 1; 35 | my $exclude; 36 | my $options; 37 | 38 | $SIG{INT} = \&sigint_handler; 39 | 40 | getopts('c:e:m:t:o:'); 41 | 42 | if ($opt_e) { 43 | $exclude = join('|', split(/,/, $opt_e)); 44 | print "Will exclude stacks containing: $exclude\n"; 45 | } 46 | 47 | if ($opt_t) { 48 | $first_n = $opt_t; 49 | print "Will print only the top $first_n stacks.\n"; 50 | } 51 | 52 | if ($opt_m) { 53 | $min_count = $opt_m; 54 | } 55 | 56 | if ($opt_c) { 57 | $command="-c \"$opt_c\"" 58 | } 59 | 60 | if ($opt_o) { 61 | $options=$opt_o 62 | } 63 | 64 | print "Will print stacks with counts >= $min_count.\n"; 65 | print STDERR "Press Ctrl-C to stop.\n"; 66 | 67 | #The systemtap script that instruments the kmalloc 68 | $script=" 69 | global kmalloc_stack 70 | 71 | probe kernel.function(\"__kmalloc\") { kmalloc_stack[backtrace()]++ } 72 | 73 | probe timer.ms(100), end 74 | { 75 | foreach (stack in kmalloc_stack) { 76 | printf(\"\\n\") 77 | print_syms(stack) 78 | printf(\"\\n\") 79 | printf(\"%d\\n\", kmalloc_stack[stack]) 80 | } 81 | delete kmalloc_stack 82 | } 83 | "; 84 | 85 | open STREAM, "stap $options -e '$script' $command|" or die "Couldn't get output stream $!"; 86 | 87 | while () { 88 | if (/(.*?)<\/hashval>/) { 89 | update_hash($key, $1); 90 | $key = ""; 91 | } elsif ($_ !~ (/|<\/hashkey>/)) { 92 | $key .= $_; 93 | } 94 | } 95 | 96 | $num_keys_before_filtering = scalar keys %kmalloc_stacks; 97 | $total_kmallocs = count_kmallocs(); 98 | filter_stacks(); 99 | sort_stacks(); 100 | top_stacks(); 101 | sort_stacks(); 102 | $num_keys_after_filtering = scalar keys %kmalloc_stacks; 103 | $filtered_kmallocs = count_kmallocs(); 104 | summarize(); 105 | exit(); 106 | 107 | sub update_hash 108 | { 109 | my($key, $val) = @_; 110 | $kmalloc_stacks{$key} += $val; 111 | } 112 | 113 | sub filter_stacks 114 | { 115 | while (($stack, $count) = each %kmalloc_stacks) { 116 | if ($count < $min_count) { 117 | delete $kmalloc_stacks{$stack}; 118 | } elsif ($exclude && $stack =~ /$exclude/) { 119 | delete $kmalloc_stacks{$stack}; 120 | } 121 | } 122 | } 123 | 124 | sub top_stacks 125 | { 126 | $count=0; 127 | foreach $stack(@sorted_stacks) { 128 | $count+=1; 129 | if ($count > $first_n) { 130 | delete $kmalloc_stacks{$stack}; 131 | } 132 | } 133 | } 134 | 135 | sub sort_stacks 136 | { 137 | @sorted_stacks = sort { $kmalloc_stacks{$b} <=> $kmalloc_stacks{$a} } keys %kmalloc_stacks; 138 | } 139 | 140 | sub count_kmallocs { 141 | $count = 0; 142 | foreach $stack(%kmalloc_stacks) { 143 | $count += $kmalloc_stacks{$stack}; 144 | } 145 | return $count; 146 | } 147 | 148 | sub summarize { 149 | print "\n"; 150 | foreach $stack(@sorted_stacks) { 151 | print "This path seen $kmalloc_stacks{$stack} times:\n$stack\n"; 152 | } 153 | 154 | if ($total_kmallocs > 0) { 155 | $percent = ($filtered_kmallocs)*100/$total_kmallocs; 156 | } else { 157 | $percent = 0; 158 | } 159 | print "Num stacks before filtering: $num_keys_before_filtering\n"; 160 | print "Num stacks after filtering: $num_keys_after_filtering\n"; 161 | print "Total kmallocs (before filtering): $total_kmallocs\n"; 162 | print "Total kmallocs (after filtering): $filtered_kmallocs\n"; 163 | print "The filter stacks have $percent of the total kmallocs\n"; 164 | 165 | close(STREAM); 166 | } 167 | 168 | sub sigint_handler 169 | { 170 | system("pkill kmalloc-stacks"); 171 | } 172 | -------------------------------------------------------------------------------- /tcp-recv-queue: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | # Copyright (C) Yichun Zhang (agentzh) 4 | 5 | use 5.006001; 6 | use strict; 7 | use warnings; 8 | 9 | use Getopt::Long qw( GetOptions ); 10 | 11 | GetOptions("a=s", \(my $stap_args), 12 | "d", \(my $dump_src), 13 | "h", \(my $help), 14 | "dport=i", \(my $dport), 15 | "time=i", \(my $time)) 16 | or die usage(); 17 | 18 | if ($help) { 19 | print usage(); 20 | exit; 21 | } 22 | 23 | if (!defined $dport) { 24 | die "No destination port specified by the --dport option.\n"; 25 | } 26 | 27 | if (!defined $stap_args) { 28 | $stap_args = ''; 29 | } 30 | 31 | if ($stap_args !~ /\b-D\s*MAXACTION=/) { 32 | $stap_args .= " -DMAXACTION=100000"; 33 | } 34 | 35 | my $ver = `stap --version 2>&1`; 36 | if (!defined $ver) { 37 | die "Systemtap not installed or its \"stap\" utility is not visible to the PATH environment: $!\n"; 38 | } 39 | 40 | if ($ver =~ /version\s+(\d+\.\d+)/i) { 41 | my $v = $1; 42 | if ($v < 2.1) { 43 | die "ERROR: at least systemtap 2.1 is required but found $v\n"; 44 | } 45 | 46 | } else { 47 | die "ERROR: unknown version of systemtap:\n$ver\n"; 48 | } 49 | 50 | my $stap_src; 51 | 52 | my $summary_code = <<_EOC_; 53 | if (!found) { 54 | println("\\nNo queued received packets found yet.") 55 | 56 | } else { 57 | println("\\n=== Distribution of First-In-First-Out Latency (us) in TCP Receive Queue ===") 58 | printf("min/avg/max: %d/%d/%d\\n", 59 | \@min(latency_stats), \@avg(latency_stats), \@max(latency_stats)) 60 | println(\@hist_log(latency_stats)) 61 | } 62 | _EOC_ 63 | 64 | my $postamble = <<_EOC_; 65 | probe end { 66 | $summary_code 67 | } 68 | _EOC_ 69 | 70 | my $tip; 71 | if (!defined $time) { 72 | $tip = "Hit Ctrl-C to end." 73 | 74 | } else { 75 | $tip = "Sampling for $time seconds."; 76 | $postamble .= <<_EOC_; 77 | probe timer.s($time) { 78 | exit() 79 | } 80 | _EOC_ 81 | } 82 | 83 | $stap_src = <<_EOC_; 84 | global latency_stats 85 | global start_times 86 | global found 87 | 88 | probe begin { 89 | warn("Tracing the TCP receive queues for packets to the port $dport...\\n$tip\\n") 90 | } 91 | 92 | /* TODO: take into account the TCP out_of_order queue (i.e., tcp_ofo_queue). */ 93 | 94 | probe kernel.function("tcp_queue_rcv")!, 95 | kernel.function("tcp_data_queue") 96 | { 97 | tcphdr = __get_skb_tcphdr(\$skb) 98 | dport = __tcp_skb_dport(tcphdr) 99 | sport = __tcp_skb_sport(tcphdr) 100 | 101 | if (dport == $dport && start_times[\$sk, sport] == 0) { 102 | //printf("tcp_queue_rcv: queue=%p sk=%p sport=%d\\n", 103 | //&\$sk->sk_receive_queue, \$sk, sport) 104 | if (\$skb->len > 0) { 105 | //println("probe func: ", probefunc()) 106 | if (\@cast(\$skb->cb, "tcp_skb_cb")->seq != \@cast(\$skb->cb, "tcp_skb_cb")->end_seq) { 107 | start_times[\$sk, sport] = gettimeofday_us() 108 | 109 | } else { 110 | //println("found seq == end_seq") 111 | } 112 | } 113 | } 114 | } 115 | 116 | probe kernel.function("tcp_recvmsg"), kernel.function("tcp_recv_skb") { 117 | q = &\$sk->sk_receive_queue 118 | skb = \$sk->sk_receive_queue->next 119 | if (q != skb) { 120 | /* queue is not empty */ 121 | tcphdr = __get_skb_tcphdr(skb) 122 | dport = __tcp_skb_dport(tcphdr) 123 | 124 | if (dport == $dport) { 125 | sport = __tcp_skb_sport(tcphdr) 126 | begin = start_times[\$sk, sport] 127 | if (begin > 0) { 128 | //printf("tcp recvmsg: port=$dport sk=%p\\n", \$sk) 129 | latency_stats <<< (gettimeofday_us() - begin) 130 | found = 1 131 | delete start_times[\$sk, sport] 132 | } 133 | } 134 | } 135 | } 136 | 137 | probe kernel.function("tcp_close"), kernel.function("tcp_disconnect") { 138 | q = &\$sk->sk_receive_queue 139 | skb = \$sk->sk_receive_queue->next 140 | if (q != skb) { 141 | /* queue is not empty */ 142 | tcphdr = __get_skb_tcphdr(skb) 143 | dport = __tcp_skb_dport(tcphdr) 144 | 145 | if (dport == $dport) { 146 | sport = __tcp_skb_sport(tcphdr) 147 | delete start_times[\$sk, sport] 148 | } 149 | } 150 | } 151 | 152 | $postamble 153 | _EOC_ 154 | 155 | if ($dump_src) { 156 | print $stap_src; 157 | exit; 158 | } 159 | 160 | open my $in, "|stap --all-modules $stap_args -" 161 | or die "Cannot run stap: $!\n"; 162 | 163 | print $in $stap_src; 164 | 165 | close $in; 166 | 167 | sub usage { 168 | return <<'_EOC_'; 169 | Usage: 170 | tcp-recv-queue [optoins] 171 | 172 | Options: 173 | -a Pass extra arguments to the stap utility. 174 | -d Dump out the systemtap script source. 175 | -h Print this usage. 176 | --dport= Specify the destination port to be analyzed. 177 | --time= Time to wait before printing out the report and exiting 178 | (Only meaningful with --distr) 179 | 180 | Examples: 181 | tcp-recv-queue --dport=11211 182 | tcp-recv-queue --dport=6379 --time=10 -a '-DMAXACTION=100000' 183 | _EOC_ 184 | } 185 | -------------------------------------------------------------------------------- /stpscript2ko.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # use for to convert script to kernel module. 4 | # stap -r 2.6.35.14-106.fc14.i686 nettop.stp -m nettop -p4 5 | # 6 | # -p NUM Stop after pass NUM. 7 | # The passes are numbered 1-5: parse, elaborate, translate, 8 | # compile, run. See the PROCESSING section for details. 9 | 10 | use strict; 11 | use warnings; 12 | use Getopt::Long; 13 | use File::Basename; 14 | use Term::ANSIColor; 15 | 16 | my $DEBUG = 0; 17 | if ($DEBUG) { 18 | eval q{ 19 | use Smart::Comments; 20 | }; 21 | die $@ if $@; 22 | } 23 | 24 | my $uname; 25 | chomp($uname = `uname -r`); ## $uname 26 | my $myscript; # systemstp script to convert. 27 | my $mymodule; # kernel module name. 28 | my $guru; # guru mode 29 | my $kerneldir; # kernel source code dir. 30 | my $bufsize; # bufsize (megebyte) for kernel-to-user data transfer. 31 | my $program = &_my_program(); 32 | 33 | my $command = 'stap'; 34 | 35 | my $usage = " 36 | Usage: $program [option] ... 37 | 38 | -g 39 | Guru mode. Enable parsing of unsafe expert-level 40 | constructs like embedded C.(Not enable default, 41 | if script contains embedded C, must enable it.) 42 | 43 | -h, --help 44 | Display this help and exit 45 | 46 | -m [modulename], --module [modulename] 47 | The output module name(default: scriptname.ko). 48 | 49 | -s scriptname, --script scriptname 50 | A script must be specified. 51 | The script name want to converted to *.ko. 52 | 53 | -r /DIR 54 | Build for kernel in given build tree. Can also 55 | be set with the SYSTEMTAP_RELEASE environment variable. 56 | 57 | -r RELEASE (default) 58 | Build for kernel in build tree /lib/modules/RELEASE/build. 59 | Can also be set with the SYSTEMTAP_RELEASE environment variable. 60 | 61 | -V Display version information. 62 | 63 | -sNUM 64 | Use NUM megabyte buffers for kernel-to-user data transfer. 65 | On a multiprocessor in bulk mode, this is a per-processor amount. 66 | "; 67 | 68 | my $ret = GetOptions( 69 | 'script|s=s' => \$myscript, 70 | 'module|m=s' => \$mymodule, 71 | 'help|h' => \&usage, 72 | 'V' => \&usage, 73 | 'g' => \$guru, 74 | 'r=s' => \$kerneldir, 75 | 'size=i' => \$bufsize 76 | ); 77 | 78 | $| =1; 79 | 80 | if(! $ret) { 81 | &usage(); 82 | } 83 | 84 | unless($myscript) { 85 | &mydie("A script must be specified."); 86 | } 87 | 88 | if(! -e $myscript) { 89 | &mydie("The input script: $myscript not existed."); 90 | } 91 | 92 | unless($mymodule) { 93 | if($myscript =~ /^((\w)+)\.(\w)+/) { 94 | $mymodule = "$1"; 95 | } else { 96 | $mymodule = "$myscript"; 97 | } 98 | 99 | if($mymodule =~ /[^_0-9a-zA-Z]/) { 100 | $mymodule =~ s/[^_0-9a-zA-Z]//g; 101 | } 102 | } 103 | ## $mymodule 104 | 105 | ## the command to finish convertion 106 | if(! $kerneldir) { 107 | print("\nUse current running kernel: \"$uname\"!\n"); 108 | if($uname =~ /^\'([^']+)\'/) { 109 | $uname = $1; 110 | } 111 | # print "$uname\n"; 112 | } else { 113 | if(-e $kerneldir) { 114 | ## $kerneldir 115 | if($kerneldir =~ /((.)+)\/$/) { 116 | $uname = $1; 117 | } else { 118 | $uname = $kerneldir; 119 | } 120 | ## $uname 121 | print("Use kernel build tree: \"$uname\"!\n"); 122 | } else { 123 | &myprint("The kernel build tree: \"$kerneldir\" not exists!\n"); 124 | print("Use current running kernel: \"$uname\"!\n"); 125 | if($uname =~ /^\'([^']+)\'/) { 126 | $uname = $1; 127 | } 128 | } 129 | } 130 | 131 | if($guru) { 132 | $command = 'stap -g'; 133 | } 134 | 135 | if($bufsize) { 136 | $bufsize = "-s$bufsize"; 137 | } else { 138 | $bufsize = ''; 139 | } 140 | 141 | my $result = `$command $bufsize -r $uname $myscript -m $mymodule -p4 2>&1`; 142 | chomp($result); 143 | ## $result 144 | if($? != 0) { 145 | if($result =~ 'embedded code' and !$guru) { 146 | &myprint("The script contains embedded C. Make try in enable guru mode use -g."); 147 | print("Trying enable guru mode.....\n"); 148 | # make try enable guru mode default. 149 | $command = 'stap -g'; 150 | $result = `$command $bufsize -r $uname $myscript -m $mymodule -p4 2>&1`; 151 | } 152 | 153 | if ($result =~ 'no probes') { 154 | &myprint("Make sure have probes."); 155 | } elsif ($? != 0) { 156 | &myprint("$result"); 157 | } 158 | } 159 | 160 | if($? == 0) { 161 | print color("green"); 162 | print "The $myscript successful converted to $result\n"; 163 | print color("reset"); 164 | } else { 165 | &myprint("The $myscript convertion is failed!\n"); 166 | } 167 | 168 | ##---------------------------------------------------- 169 | # 170 | sub _my_program { 171 | require File::Basename; 172 | return File::Basename::basename( $0 ); 173 | } 174 | 175 | sub usage { 176 | print $usage; 177 | exit; 178 | } 179 | 180 | sub mydie { 181 | print color("red"); 182 | print("@_ \n"); 183 | print color("reset"); 184 | &usage(); 185 | } 186 | 187 | sub myprint { 188 | print color("red"); 189 | print("@_ \n"); 190 | print color("reset"); 191 | } 192 | 193 | -------------------------------------------------------------------------------- /stpscripts2ko.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # use for to convert scripts to kernel module. 4 | # stap -r 2.6.35.14-106.fc14.i686 nettop.stp [scripts...] 5 | # 6 | 7 | use strict; 8 | use warnings; 9 | use Getopt::Long; 10 | use File::Basename; 11 | use Term::ANSIColor; 12 | 13 | my $DEBUG = 0; 14 | if ($DEBUG) { 15 | eval q{ 16 | use Smart::Comments; 17 | }; 18 | die $@ if $@; 19 | } 20 | 21 | my $uname; ## $uname 22 | my $module; # kernel module name. 23 | my $guru; # guru mode 24 | my $kerneldir; # kernel source code dir. 25 | my $bufsize; # bufsize (megebyte) for kernel-to-user data transfer. 26 | my $program = basename( $0 ); 27 | 28 | my $command = 'stap'; 29 | 30 | my $usage = " 31 | Usage: $program [options] [scripts] 32 | 33 | -g 34 | Guru mode. Enable parsing of unsafe expert-level 35 | constructs like embedded C.(Not enable default, 36 | if script contains embedded C, must enable it.) 37 | 38 | -h, --help 39 | Display this help and exit 40 | 41 | -r /DIR 42 | Build for kernel in given build tree. Can also 43 | be set with the SYSTEMTAP_RELEASE environment variable. 44 | 45 | -r RELEASE (default) 46 | Build for kernel in build tree /lib/modules/RELEASE/build. 47 | Can also be set with the SYSTEMTAP_RELEASE environment variable. 48 | 49 | -V Display version information. 50 | 51 | -sNUM 52 | Use NUM megabyte buffers for kernel-to-user data transfer. 53 | On a multiprocessor in bulk mode, this is a per-processor amount. 54 | "; 55 | 56 | my $ret = GetOptions( 57 | 'help|h' => \&usage, 58 | 'V' => \&usage, 59 | 'g' => \$guru, 60 | 'r=s' => \$kerneldir, 61 | 'size=i' => \$bufsize 62 | ); 63 | 64 | $| =1; 65 | 66 | if(! $ret) { 67 | &usage(); 68 | } elsif (scalar @ARGV < 1) { 69 | &myprint("A script must be specified."); 70 | &usage(); 71 | } 72 | 73 | chomp($uname = `uname -r`) unless($kerneldir); 74 | 75 | if(! $kerneldir) { 76 | print("\nUse current running kernel: \"$uname\"!\n"); 77 | if($uname =~ /^\'([^']+)\'/) { 78 | $uname = $1; 79 | } 80 | # print "$uname\n"; 81 | } else { 82 | if(-e $kerneldir) { 83 | ## $kerneldir 84 | if($kerneldir =~ /((.)+)\/$/) { 85 | $uname = $1; 86 | } else { 87 | $uname = $kerneldir; 88 | } 89 | ## $uname 90 | print("Use kernel build tree: \"$uname\"!\n"); 91 | } else { 92 | &myprint("The kernel build tree: \"$kerneldir\" not exists!\n"); 93 | print("Use current running kernel: \"$uname\"!\n"); 94 | if($uname =~ /^\'([^']+)\'/) { 95 | $uname = $1; 96 | } 97 | } 98 | } 99 | 100 | if($guru) { 101 | $command = 'stap -g'; 102 | } 103 | 104 | if($bufsize) { 105 | $bufsize = "-s$bufsize"; 106 | } else { 107 | $bufsize = ''; 108 | } 109 | 110 | my @failed = (); 111 | my $succeed = (); 112 | ## the command to finish convertion 113 | foreach my $script (@ARGV) { 114 | if(! -e $script) { 115 | warn("The input script: $script not existed."); 116 | push @failed, $script; 117 | next; 118 | } 119 | 120 | if($script =~ /^((\w)+)\.(\w)+/) { 121 | $module = "$1"; 122 | } else { 123 | $module = "$script"; 124 | } 125 | 126 | if($module =~ /[^_0-9a-zA-Z]/) { 127 | $module =~ s/[^_0-9a-zA-Z]//g; 128 | } 129 | 130 | my $result = `$command $bufsize -r $uname $script -m $module -p4 2>&1`; 131 | chomp($result); 132 | ## $result 133 | if($? != 0) { 134 | if($result =~ 'embedded code' and !$guru) { 135 | &myprint("The script $script contains embedded C. Make try enable guru mode use -g."); 136 | print("Trying enable guru mode.....\n"); 137 | # make try enable guru mode default. 138 | $command = 'stap -g'; 139 | $result = `$command $bufsize -r $uname $script -m $module -p4 2>&1`; 140 | } 141 | 142 | if ($result =~ 'no probes') { 143 | &myprint("Make sure $script have probes."); 144 | } elsif ($? != 0) { 145 | &myprint("$script: $result"); 146 | } 147 | } 148 | 149 | if($? == 0) { 150 | $succeed->{"$script"} = $module; 151 | } else { 152 | push @failed, $script; 153 | } 154 | } 155 | 156 | if(scalar $succeed > 0) { 157 | print color("green"); 158 | print "The scripts successful converted:\n"; 159 | ## $succeed 160 | &printhash($succeed); 161 | print color("reset"); 162 | } 163 | 164 | if(@failed > 0) { 165 | print color("red"); 166 | print "The scripts failed converted:\n"; 167 | &printarray(@failed); 168 | print color("reset"); 169 | } 170 | 171 | ##---------------------------------------------------- 172 | # 173 | sub usage { 174 | print $usage; 175 | exit; 176 | } 177 | 178 | sub mydie { 179 | print color("red"); 180 | print("@_ \n"); 181 | print color("reset"); 182 | &usage(); 183 | } 184 | 185 | sub myprint { 186 | print color("red"); 187 | print("@_ \n"); 188 | print color("reset"); 189 | } 190 | 191 | sub printarray { 192 | foreach my $element (@_) { 193 | print "\t$element\n"; 194 | } 195 | } 196 | 197 | sub printhash { 198 | my $ref = shift; 199 | my ($key, $value); 200 | while (($key, $value) = each(%$ref)) { 201 | print "\t$key => $value\n"; 202 | } 203 | } 204 | 205 | -------------------------------------------------------------------------------- /doc/syscallstap.txt: -------------------------------------------------------------------------------- 1 | #########stap -l 'syscall.*' 2 | 3 | syscall.accept 4 | syscall.access 5 | syscall.acct 6 | syscall.add_key 7 | syscall.adjtimex 8 | syscall.alarm 9 | syscall.bdflush 10 | syscall.bind 11 | syscall.brk 12 | syscall.capget 13 | syscall.capset 14 | syscall.chdir 15 | syscall.chmod 16 | syscall.chown 17 | syscall.chown16 18 | syscall.chroot 19 | syscall.clock_getres 20 | syscall.clock_gettime 21 | syscall.clock_nanosleep 22 | syscall.clock_settime 23 | syscall.close 24 | syscall.connect 25 | syscall.creat 26 | syscall.delete_module 27 | syscall.dup 28 | syscall.dup2 29 | syscall.epoll_create 30 | syscall.epoll_ctl 31 | syscall.epoll_pwait 32 | syscall.epoll_wait 33 | syscall.eventfd 34 | syscall.execve 35 | syscall.exit 36 | syscall.exit_group 37 | syscall.faccessat 38 | syscall.fadvise64 39 | syscall.fadvise64_64 40 | syscall.fchdir 41 | syscall.fchmod 42 | syscall.fchmodat 43 | syscall.fchown 44 | syscall.fchown16 45 | syscall.fchownat 46 | syscall.fcntl 47 | syscall.fdatasync 48 | syscall.fgetxattr 49 | syscall.flistxattr 50 | syscall.flock 51 | syscall.fork 52 | syscall.fremovexattr 53 | syscall.fsetxattr 54 | syscall.fstat 55 | syscall.fstatat 56 | syscall.fstatfs 57 | syscall.fstatfs64 58 | syscall.fsync 59 | syscall.ftruncate 60 | syscall.ftruncate64 61 | syscall.futex 62 | syscall.futimesat 63 | syscall.get_thread_area 64 | syscall.getcwd 65 | syscall.getdents 66 | syscall.getegid 67 | syscall.geteuid 68 | syscall.getgid 69 | syscall.getgroups 70 | syscall.gethostname 71 | syscall.getitimer 72 | syscall.getpeername 73 | syscall.getpgid 74 | syscall.getpgrp 75 | syscall.getpid 76 | syscall.getppid 77 | syscall.getpriority 78 | syscall.getresgid 79 | syscall.getresuid 80 | syscall.getrlimit 81 | syscall.getrusage 82 | syscall.getsid 83 | syscall.getsockname 84 | syscall.getsockopt 85 | syscall.gettid 86 | syscall.gettimeofday 87 | syscall.getuid 88 | syscall.getxattr 89 | syscall.init_module 90 | syscall.inotify_add_watch 91 | syscall.inotify_init 92 | syscall.inotify_rm_watch 93 | syscall.io_cancel 94 | syscall.io_destroy 95 | syscall.io_getevents 96 | syscall.io_setup 97 | syscall.io_submit 98 | syscall.ioctl 99 | syscall.ioperm 100 | syscall.iopl 101 | syscall.ioprio_get 102 | syscall.ioprio_set 103 | syscall.ipc 104 | syscall.kexec_load 105 | syscall.keyctl 106 | syscall.kill 107 | syscall.lchown 108 | syscall.lchown16 109 | syscall.lgetxattr 110 | syscall.link 111 | syscall.linkat 112 | syscall.listen 113 | syscall.listxattr 114 | syscall.llistxattr 115 | syscall.llseek 116 | syscall.lookup_dcookie 117 | syscall.lremovexattr 118 | syscall.lseek 119 | syscall.lsetxattr 120 | syscall.lstat 121 | syscall.madvise 122 | syscall.mincore 123 | syscall.mkdir 124 | syscall.mkdirat 125 | syscall.mknod 126 | syscall.mknodat 127 | syscall.mlock 128 | syscall.mlockall 129 | syscall.mmap2 130 | syscall.modify_ldt 131 | syscall.mount 132 | syscall.mprotect 133 | syscall.mq_getsetattr 134 | syscall.mq_notify 135 | syscall.mq_open 136 | syscall.mq_timedreceive 137 | syscall.mq_timedsend 138 | syscall.mq_unlink 139 | syscall.mremap 140 | syscall.msgctl 141 | syscall.msgget 142 | syscall.msgrcv 143 | syscall.msgsnd 144 | syscall.msync 145 | syscall.munlock 146 | syscall.munlockall 147 | syscall.munmap 148 | syscall.nanosleep 149 | syscall.nfsservctl 150 | syscall.ni_syscall 151 | syscall.nice 152 | syscall.open 153 | syscall.openat 154 | syscall.pause 155 | syscall.personality 156 | syscall.pipe 157 | syscall.pivot_root 158 | syscall.poll 159 | syscall.ppoll 160 | syscall.prctl 161 | syscall.pread 162 | syscall.pselect6 163 | syscall.ptrace 164 | syscall.pwrite 165 | syscall.quotactl 166 | syscall.read 167 | syscall.readahead 168 | syscall.readlink 169 | syscall.readlinkat 170 | syscall.readv 171 | syscall.reboot 172 | syscall.recv 173 | syscall.recvfrom 174 | syscall.recvmmsg 175 | syscall.recvmsg 176 | syscall.remap_file_pages 177 | syscall.removexattr 178 | syscall.rename 179 | syscall.renameat 180 | syscall.request_key 181 | syscall.restart_syscall 182 | syscall.rmdir 183 | syscall.rt_sigaction 184 | syscall.rt_sigpending 185 | syscall.rt_sigprocmask 186 | syscall.rt_sigqueueinfo 187 | syscall.rt_sigreturn 188 | syscall.rt_sigsuspend 189 | syscall.rt_sigtimedwait 190 | syscall.sched_get_priority_max 191 | syscall.sched_get_priority_min 192 | syscall.sched_getaffinity 193 | syscall.sched_getparam 194 | syscall.sched_getscheduler 195 | syscall.sched_rr_get_interval 196 | syscall.sched_setaffinity 197 | syscall.sched_setparam 198 | syscall.sched_setscheduler 199 | syscall.sched_yield 200 | syscall.select 201 | syscall.semctl 202 | syscall.semget 203 | syscall.semop 204 | syscall.semtimedop 205 | syscall.send 206 | syscall.sendfile 207 | syscall.sendmsg 208 | syscall.sendto 209 | syscall.set_thread_area 210 | syscall.set_tid_address 211 | syscall.setdomainname 212 | syscall.setfsgid 213 | syscall.setfsuid 214 | syscall.setgid 215 | syscall.setgroups 216 | syscall.sethostname 217 | syscall.setitimer 218 | syscall.setpgid 219 | syscall.setpriority 220 | syscall.setregid 221 | syscall.setregid16 222 | syscall.setresgid 223 | syscall.setresgid16 224 | syscall.setresuid 225 | syscall.setresuid16 226 | syscall.setreuid 227 | syscall.setreuid16 228 | syscall.setrlimit 229 | syscall.setsid 230 | syscall.setsockopt 231 | syscall.settimeofday 232 | syscall.setuid 233 | syscall.setxattr 234 | syscall.sgetmask 235 | syscall.shmat 236 | syscall.shmctl 237 | syscall.shmdt 238 | syscall.shmget 239 | syscall.shutdown 240 | syscall.sigaction 241 | syscall.sigaltstack 242 | syscall.signal 243 | syscall.signalfd 244 | syscall.sigpending 245 | syscall.sigprocmask 246 | syscall.sigreturn 247 | syscall.sigsuspend 248 | syscall.socket 249 | syscall.socketpair 250 | syscall.splice 251 | syscall.ssetmask 252 | syscall.stat 253 | syscall.statfs 254 | syscall.statfs64 255 | syscall.stime 256 | syscall.swapoff 257 | syscall.swapon 258 | syscall.symlink 259 | syscall.symlinkat 260 | syscall.sync 261 | syscall.sysctl 262 | syscall.sysfs 263 | syscall.sysinfo 264 | syscall.syslog 265 | syscall.tee 266 | syscall.tgkill 267 | syscall.time 268 | syscall.timer_create 269 | syscall.timer_delete 270 | syscall.timer_getoverrun 271 | syscall.timer_gettime 272 | syscall.timer_settime 273 | syscall.times 274 | syscall.tkill 275 | syscall.truncate 276 | syscall.umask 277 | syscall.umount 278 | syscall.uname 279 | syscall.unlink 280 | syscall.unlinkat 281 | syscall.unshare 282 | syscall.uselib 283 | syscall.ustat 284 | syscall.utime 285 | syscall.utimensat 286 | syscall.utimes 287 | syscall.vhangup 288 | syscall.vm86 289 | syscall.vm86old 290 | syscall.vmsplice 291 | syscall.wait4 292 | syscall.waitid 293 | syscall.write 294 | syscall.writev 295 | -------------------------------------------------------------------------------- /tcp-accept-queue: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | # Copyright (C) Yichun Zhang (agentzh) 4 | 5 | # Based on the systemtap script first shown by chaoslawful. 6 | 7 | use 5.006001; 8 | use strict; 9 | use warnings; 10 | 11 | use Getopt::Long qw( GetOptions ); 12 | 13 | GetOptions("a=s", \(my $stap_args), 14 | "d", \(my $dump_src), 15 | "distr", \(my $show_distr), 16 | "h", \(my $help), 17 | "limit=i", \(my $limit), 18 | "port=i", \(my $port), 19 | "time=i", \(my $time), 20 | "latency", \(my $check_latency)) 21 | or die usage(); 22 | 23 | if ($help) { 24 | print usage(); 25 | exit; 26 | } 27 | 28 | if (!defined $port) { 29 | die "No listening port specified by the -p option.\n"; 30 | } 31 | 32 | if (!defined $limit) { 33 | $limit = 10; 34 | } 35 | 36 | if (!defined $stap_args) { 37 | $stap_args = ''; 38 | } 39 | 40 | if ($stap_args !~ /\b-D\s*MAXACTION=/) { 41 | $stap_args .= " -DMAXACTION=100000"; 42 | } 43 | 44 | my $ver = `stap --version 2>&1`; 45 | if (!defined $ver) { 46 | die "Systemtap not installed or its \"stap\" utility is not visible to the PATH environment: $!\n"; 47 | } 48 | 49 | if ($ver =~ /version\s+(\d+\.\d+)/i) { 50 | my $v = $1; 51 | if ($v < 2.1) { 52 | die "ERROR: at least systemtap 2.1 is required but found $v\n"; 53 | } 54 | 55 | } else { 56 | die "ERROR: unknown version of systemtap:\n$ver\n"; 57 | } 58 | 59 | my $stap_src; 60 | 61 | if ($show_distr) { 62 | # show queue length distribution 63 | 64 | my $summary_code = <<_EOC_; 65 | if (max_syn_qlen == 0) { 66 | println("\\nNo new connections found yet.") 67 | 68 | } else { 69 | println("\\n=== SYN Queue ===") 70 | printf("min/avg/max: %d/%d/%d\\n", 71 | \@min(syn_qlen_stats), \@avg(syn_qlen_stats), \@max(syn_qlen_stats)) 72 | println(\@hist_log(syn_qlen_stats)) 73 | 74 | println("=== Accept Queue ===") 75 | printf("min/avg/max: %d/%d/%d\\n", 76 | \@min(acc_qlen_stats), \@avg(acc_qlen_stats), \@max(acc_qlen_stats)) 77 | println(\@hist_log(acc_qlen_stats)) 78 | } 79 | _EOC_ 80 | 81 | my $postamble = <<_EOC_; 82 | probe end { 83 | $summary_code 84 | } 85 | _EOC_ 86 | 87 | my $tip; 88 | if (!defined $time) { 89 | $tip = "Hit Ctrl-C to end." 90 | 91 | } else { 92 | $tip = "Sampling for $time seconds."; 93 | $postamble .= <<_EOC_; 94 | probe timer.s($time) { 95 | exit() 96 | } 97 | _EOC_ 98 | } 99 | 100 | $stap_src = <<_EOC_; 101 | global syn_qlen_stats 102 | global acc_qlen_stats 103 | global max_syn_qlen 104 | global max_acc_qlen 105 | 106 | probe begin { 107 | warn("Tracing SYN & ACK backlog queue length distribution on the listening port $port...\\n$tip\\n") 108 | } 109 | 110 | probe kernel.function("tcp_v4_conn_request") { 111 | tcphdr = __get_skb_tcphdr(\$skb) 112 | dport = __tcp_skb_dport(tcphdr) 113 | 114 | if (dport == $port) { 115 | syn_qlen = \@cast(\$sk, "struct inet_connection_sock")->icsk_accept_queue->listen_opt->qlen 116 | syn_qlen_stats <<< syn_qlen 117 | 118 | if (max_syn_qlen == 0) { 119 | max_qlen_log = \@cast(\$sk, "struct inet_connection_sock")->icsk_accept_queue->listen_opt->max_qlen_log 120 | max_syn_qlen = (1 << max_qlen_log) 121 | printf("SYN queue length limit: %d\\n", max_syn_qlen) 122 | } 123 | 124 | acc_qlen_stats <<< \$sk->sk_ack_backlog 125 | 126 | if (max_acc_qlen == 0) { 127 | max_acc_qlen = \$sk->sk_max_ack_backlog 128 | printf("Accept queue length limit: %d\\n", max_acc_qlen) 129 | } 130 | } 131 | } 132 | 133 | $postamble 134 | _EOC_ 135 | 136 | } elsif ($check_latency) { 137 | 138 | my $summary_code = <<_EOC_; 139 | if (!found) { 140 | println("\\nNo new connections found yet.") 141 | 142 | } else { 143 | println("\\n=== Accept Queueing Latency Distribution (microsends) ===") 144 | printf("min/avg/max: %d/%d/%d\\n", 145 | \@min(latency_stats), \@avg(latency_stats), \@max(latency_stats)) 146 | println(\@hist_log(latency_stats)) 147 | } 148 | _EOC_ 149 | 150 | my $postamble = <<_EOC_; 151 | probe end { 152 | $summary_code 153 | } 154 | _EOC_ 155 | 156 | my $tip; 157 | if (!defined $time) { 158 | $tip = "Hit Ctrl-C to end." 159 | 160 | } else { 161 | $tip = "Sampling for $time seconds."; 162 | $postamble .= <<_EOC_; 163 | probe timer.s($time) { 164 | exit() 165 | } 166 | _EOC_ 167 | } 168 | 169 | $stap_src = <<_EOC_; 170 | global begin_times 171 | global latency_stats 172 | global found 173 | 174 | probe begin { 175 | warn("Tracing accept queueing latency on the listening port $port...\\n$tip\\n") 176 | } 177 | 178 | probe kernel.function("tcp_openreq_init") { 179 | tcphdr = __get_skb_tcphdr(\$skb) 180 | dport = __tcp_skb_dport(tcphdr) 181 | 182 | if (dport == $port) { 183 | begin_times[\$req] = gettimeofday_us() 184 | //printf("tcp openreq init: %p %d\\n", \$req, dport) 185 | } 186 | } 187 | 188 | probe kernel.function("inet_csk_accept") { 189 | req = \@cast(\$sk, "struct inet_connection_sock")->icsk_accept_queue->rskq_accept_head 190 | begin = begin_times[req] 191 | if (begin) { 192 | elapsed = gettimeofday_us() - begin 193 | /* 194 | printf("inet csk accept: sk=%p, req=%p, latency=%d\\n", \$sk, req, 195 | elapsed) 196 | */ 197 | latency_stats <<< elapsed 198 | delete begin_times[req] 199 | found = 1 200 | } 201 | } 202 | 203 | $postamble 204 | _EOC_ 205 | 206 | } else { 207 | # trace queue overflows 208 | 209 | $stap_src = <<_EOC_; 210 | global count 211 | 212 | probe begin { 213 | warn("Tracing SYN & ACK backlog queue overflows on the listening port $port...\\n") 214 | } 215 | 216 | probe kernel.function("tcp_v4_conn_request") { 217 | tcphdr = __get_skb_tcphdr(\$skb) 218 | dport = __tcp_skb_dport(tcphdr) 219 | 220 | if (dport == $port) { 221 | syn_qlen = \@cast(\$sk, "struct inet_connection_sock")->icsk_accept_queue->listen_opt->qlen 222 | max_syn_qlen_log = \@cast(\$sk, "struct inet_connection_sock")->icsk_accept_queue->listen_opt->max_qlen_log 223 | max_syn_qlen = (2 << max_syn_qlen_log) 224 | 225 | if (syn_qlen > max_syn_qlen) { 226 | now = tz_ctime(gettimeofday_s()) 227 | printf("[%s] SYN queue is overflown: %d > %d\\n", now, syn_qlen, max_syn_qlen) 228 | count++ 229 | } 230 | 231 | //printf("syn queue: %d <= %d\\n", qlen, max_qlen) 232 | 233 | ack_backlog = \$sk->sk_ack_backlog 234 | max_ack_backlog = \$sk->sk_max_ack_backlog 235 | 236 | if (ack_backlog > max_ack_backlog) { 237 | now = tz_ctime(gettimeofday_s()) 238 | printf("[%s] ACK backlog queue is overflown: %d > %d\\n", now, ack_backlog, max_ack_backlog) 239 | count++ 240 | } 241 | 242 | //printf("ACK backlog queue: %d <= %d\\n", ack_backlog, max_ack_backlog) 243 | 244 | if (count >= $limit) { 245 | exit() 246 | } 247 | } 248 | } 249 | _EOC_ 250 | } 251 | 252 | if ($dump_src) { 253 | print $stap_src; 254 | exit; 255 | } 256 | 257 | open my $in, "|stap --all-modules $stap_args -" 258 | or die "Cannot run stap: $!\n"; 259 | 260 | print $in $stap_src; 261 | 262 | close $in; 263 | 264 | sub usage { 265 | return <<'_EOC_'; 266 | Usage: 267 | tcp-accept-queue [optoins] 268 | 269 | Options: 270 | -a Pass extra arguments to the stap utility. 271 | -d Dump out the systemtap script source. 272 | --distr Show queue length distribution only. 273 | -h Print this usage. 274 | --limit= Exit when queue overflowing issues are found. 275 | (Default to 10) 276 | --port= Specify the listening port to be analyzed. 277 | --time= Time to wait before printing out the report and exiting 278 | (Only meaningful with --distr) 279 | 280 | Examples: 281 | tcp-accept-queue --port 11211 282 | tcp-accept-queue --port 6379 --limit 10 -a '-DMAXACTION=100000' 283 | _EOC_ 284 | } 285 | -------------------------------------------------------------------------------- /viewcache.stp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/stap 2 | # 3 | # This Script used to scan buffer/cache and statistic each file mapped page 4 | # 5 | # 6 | 7 | %{ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | %} 15 | 16 | %{ 17 | 18 | %} 19 | 20 | %{ 21 | #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) 22 | 23 | static inline void 24 | add_page_to_active_list(struct zone *zone, struct page *page) 25 | { 26 | list_add(&page->lru, &zone->active_list); 27 | zone->nr_active++; 28 | } 29 | 30 | static inline void 31 | add_page_to_inactive_list(struct zone *zone, struct page *page) 32 | { 33 | list_add(&page->lru, &zone->inactive_list); 34 | zone->nr_inactive++; 35 | } 36 | 37 | %} 38 | 39 | %{ 40 | unsigned long NR_TO_SCAN = 128; //we scan a 64 page cluster for a time 41 | %} 42 | 43 | %{ 44 | #define prefetchw_prev_lru_page(_page, _base, _field) \ 45 | do { \ 46 | if ((_page)->lru.prev != _base) { \ 47 | struct page *prev; \ 48 | \ 49 | prev = lru_to_page(&(_page->lru)); \ 50 | prefetchw(&prev->_field); \ 51 | } \ 52 | } while (0) 53 | %} 54 | 55 | 56 | %{ 57 | static unsigned long isolate_lru_pages(unsigned long nr_to_scan, 58 | struct list_head *src, struct list_head *dst, 59 | unsigned long *scanned) 60 | { 61 | unsigned long nr_taken = 0; 62 | struct page *page; 63 | unsigned long scan; 64 | 65 | for (scan = 0; scan < nr_to_scan && !list_empty(src); scan++) { 66 | struct list_head *target; 67 | page = lru_to_page(src); 68 | prefetchw_prev_lru_page(page, src, flags); 69 | 70 | BUG_ON(!PageLRU(page)); 71 | 72 | list_del(&page->lru); 73 | target = src; 74 | if (likely(get_page_unless_zero(page))) { 75 | /* 76 | * Be careful not to clear PageLRU until after we're 77 | * sure the page is not being freed elsewhere -- the 78 | * page release code relies on it. 79 | */ 80 | ClearPageLRU(page); 81 | target = dst; 82 | nr_taken++; 83 | } /* else it is being freed elsewhere */ 84 | 85 | list_add(&page->lru, target); 86 | } 87 | 88 | *scanned = scan; 89 | return nr_taken; 90 | } 91 | %} 92 | 93 | 94 | //use B-Tree to store inode data 95 | %{ 96 | struct cache_node { 97 | unsigned long ino; // inode NO. 98 | unsigned long nr; // number of pages related to this inode current in memory 99 | struct cache_node *left, *right; 100 | }; 101 | 102 | typedef struct cache_node node; 103 | 104 | node * root; 105 | /* 106 | Given a binary tree, return true if a node 107 | with the target data is found in the tree. Recurs 108 | down the tree, chooses the left or right 109 | branch by comparing the target to each node. 110 | */ 111 | static int 112 | cache_node_lookup(node *node, unsigned long target) { 113 | // 1. Base case == empty tree 114 | // in that case, the target is not found so return false 115 | if (node == NULL) { 116 | return 0; 117 | } 118 | else { 119 | // 2. see if found here 120 | if (target == node->ino) { 121 | node->nr++; 122 | return 1; 123 | } else { 124 | // 3. otherwise recur down the correct subtree 125 | if (target < node->ino) return(cache_node_lookup(node->left, target)); 126 | else return(cache_node_lookup(node->right, target)); 127 | } 128 | } 129 | } 130 | 131 | static void 132 | insert_cache_node (node **tree,node *item) 133 | { 134 | if(!(*tree)) { 135 | *tree = item; 136 | return; 137 | } 138 | if(item->ino<(*tree)->ino) 139 | insert_cache_node(&(*tree)->left, item); 140 | else if(item->ino>(*tree)->ino) 141 | insert_cache_node(&(*tree)->right, item); 142 | } 143 | 144 | #ifdef SW 145 | static int 146 | find_get_cache_node(node * node, unsigned long target) 147 | { 148 | struct cache_node * n; 149 | if(cache_node_lookup(node, target)) //cache find 150 | return 1; 151 | else { // cache miss 152 | n = kmalloc(sizeof(struct cache_node), GFP_KERNEL); 153 | if (!n) return -ENOMEM; 154 | n->ino = target; 155 | n->nr = 1; 156 | n->left = NULL; 157 | n->right = NULL; 158 | insert_cache_node(&node, n); 159 | return 0; 160 | } 161 | } 162 | #endif 163 | 164 | static void 165 | traverse_tree(node *node) { 166 | if(node->left) traverse_tree(node->left); 167 | printk(KERN_ALERT "inode: %lu, num: %lu\n", node->ino, node->nr); 168 | if(node->right) traverse_tree(node->right); 169 | } 170 | 171 | static void 172 | destroy_tree(node *node) { 173 | if(node->left) traverse_tree(node->left); 174 | if(node->right) traverse_tree(node->right); 175 | kfree(node); 176 | } 177 | 178 | static int 179 | scan_hold_list(struct list_head *src, struct list_head *dst, unsigned long *nr) 180 | { 181 | struct page *page; 182 | while(!list_empty(src)) { 183 | page = lru_to_page(src); 184 | list_del(&page->lru); 185 | //we only do file mapped page , etl. skip the anonymous page 186 | if(!PageSwapCache(page) && !((unsigned long)page->mapping & PAGE_MAPPING_ANON)) { 187 | //because we don't have the page and inode lock, so 188 | //we must insure both mapping and inode object has not be freed 189 | if(likely(page->mapping && page->mapping->host)) { 190 | struct cache_node * curr; 191 | int ret; 192 | unsigned long ino = page->mapping->host->i_ino ; 193 | ret = cache_node_lookup(root, ino); 194 | if(ret != 1) {// not found, so create a new node; 195 | curr = kmalloc(sizeof(struct cache_node), GFP_KERNEL); 196 | //FIX me, we should put remain page back to LRU 197 | if (curr == NULL) return -ENOMEM; 198 | curr->ino = ino; 199 | curr->nr = 1; 200 | curr->left = NULL; 201 | curr->right = NULL; 202 | insert_cache_node(&root, curr); 203 | } 204 | } 205 | *nr++; 206 | } 207 | //put back page to zone's active list 208 | list_add(&page->lru, dst); 209 | } 210 | return 0; 211 | } 212 | %} 213 | 214 | function viewcache:long() 215 | %{ 216 | pg_data_t *pgdat; 217 | 218 | unsigned long i = 0, j = 0; 219 | int zone_idx, node_idx; 220 | int ret; 221 | struct zone *zone; 222 | struct page *page = NULL; 223 | // struct address_space *mapping; 224 | unsigned long pgmoved = 0; 225 | unsigned long scaned; 226 | unsigned long nr_to_scan = 0; 227 | //we use l_active and l_inactive to store the temp list stolened page from LRU 228 | LIST_HEAD(l_active); 229 | LIST_HEAD(l_inactive); 230 | LIST_HEAD(l_hold); 231 | unsigned long nr_active ,nr_inactive; 232 | 233 | //get the fist zone 234 | zone = NODE_DATA(first_online_node)->node_zones; 235 | 236 | cond_resched(); 237 | 238 | for (;;) { 239 | if (!zone) break; 240 | 241 | cond_resched(); 242 | 243 | nr_active = zone->nr_active; 244 | nr_inactive = zone->nr_inactive; 245 | node_idx = zone->zone_pgdat->node_id; 246 | zone_idx = zone - zone->zone_pgdat->node_zones; 247 | 248 | while(nr_active) { 249 | nr_to_scan = min(NR_TO_SCAN, nr_active); 250 | //lock the zone 251 | printk(KERN_ALERT "%d %d %ld %ld\n", node_idx, zone_idx, nr_active, nr_to_scan); 252 | spin_lock_irq(&zone->lru_lock); 253 | //we try to scan 'nr_to_scan' page, and save page scand in 'scaned' variable 254 | //and number of page be moved to tmp list is saved in pgmoved variable 255 | pgmoved = isolate_lru_pages(nr_to_scan, &zone->active_list, 256 | &l_active, &scaned); 257 | zone->pages_scanned += scaned; 258 | zone->nr_active -= pgmoved; 259 | spin_unlock_irq(&zone->lru_lock); 260 | //decrease the scaned page 261 | nr_active -= nr_to_scan; 262 | 263 | //here we have a 'l_active' list store the page stored from active list 264 | if(scan_hold_list(&l_active, &l_hold, &i) < 0 ) goto done; 265 | 266 | spin_lock_irq(&zone->lru_lock); 267 | while(!list_empty(&l_hold)) { 268 | page = lru_to_page(&l_hold); 269 | prefetchw_prev_lru_page(page, &l_hold, flags); 270 | list_del(&page->lru); 271 | BUG_ON(PageLRU(page)); 272 | SetPageLRU(page); 273 | BUG_ON(!PageActive(page)); 274 | add_page_to_active_list(zone, page); 275 | } 276 | spin_unlock_irq(&zone->lru_lock); 277 | //force to sleep 300 msec 278 | msleep(300); 279 | } 280 | while(nr_inactive) { 281 | nr_to_scan = min(NR_TO_SCAN, nr_inactive); 282 | printk(KERN_ALERT "%d %d %ld %ld\n", node_idx, zone_idx, nr_inactive, nr_to_scan); 283 | spin_lock_irq(&zone->lru_lock); 284 | pgmoved = isolate_lru_pages(nr_to_scan, &zone->inactive_list, 285 | &l_inactive, &scaned); 286 | zone->pages_scanned += scaned; 287 | zone->nr_inactive -= pgmoved; 288 | spin_unlock_irq(&zone->lru_lock); 289 | nr_inactive -= nr_to_scan; 290 | 291 | if (scan_hold_list(&l_inactive, &l_hold, &j)<0) goto done; 292 | 293 | spin_lock_irq(&zone->lru_lock); 294 | while(!list_empty(&l_hold)) { 295 | page = lru_to_page(&l_hold); 296 | BUG_ON(PageLRU(page)); 297 | SetPageLRU(page); 298 | list_del(&page->lru); 299 | if (PageActive(page)) 300 | add_page_to_active_list(zone, page); 301 | else 302 | add_page_to_inactive_list(zone, page); 303 | } 304 | spin_unlock_irq(&zone->lru_lock); 305 | //sleep 300 msecs 306 | msleep(300); 307 | } 308 | 309 | if (zone < zone->zone_pgdat->node_zones + MAX_NR_ZONES - 1) 310 | zone++; 311 | else { 312 | int nid = next_online_node(zone->zone_pgdat->node_id); 313 | if (nid == MAX_NUMNODES) 314 | pgdat = NULL; 315 | else 316 | pgdat = NODE_DATA(nid); 317 | if (pgdat) 318 | zone = pgdat->node_zones; 319 | else 320 | zone = NULL; 321 | } 322 | } 323 | done: 324 | //print result 325 | traverse_tree(root); 326 | //free memory 327 | destroy_tree(root); 328 | THIS->__retvalue = i+j; 329 | %} 330 | 331 | probe begin { 332 | printf("total file mapped LRU page = %d\n", viewcache()) 333 | exit() 334 | } 335 | -------------------------------------------------------------------------------- /doc/kerneltrace.txt: -------------------------------------------------------------------------------- 1 | #### stap -l 'kernel.trace("*")' 2 | 3 | kernel.trace("block_bio_backmerge") 4 | kernel.trace("block_bio_bounce") 5 | kernel.trace("block_bio_complete") 6 | kernel.trace("block_bio_frontmerge") 7 | kernel.trace("block_bio_queue") 8 | kernel.trace("block_getrq") 9 | kernel.trace("block_plug") 10 | kernel.trace("block_remap") 11 | kernel.trace("block_rq_abort") 12 | kernel.trace("block_rq_complete") 13 | kernel.trace("block_rq_insert") 14 | kernel.trace("block_rq_issue") 15 | kernel.trace("block_rq_remap") 16 | kernel.trace("block_rq_requeue") 17 | kernel.trace("block_sleeprq") 18 | kernel.trace("block_split") 19 | kernel.trace("block_unplug_io") 20 | kernel.trace("block_unplug_timer") 21 | kernel.trace("ext4_alloc_da_blocks") 22 | kernel.trace("ext4_allocate_blocks") 23 | kernel.trace("ext4_allocate_inode") 24 | kernel.trace("ext4_da_release_space") 25 | kernel.trace("ext4_da_reserve_space") 26 | kernel.trace("ext4_da_update_reserve_space") 27 | kernel.trace("ext4_da_write_begin") 28 | kernel.trace("ext4_da_write_end") 29 | kernel.trace("ext4_da_write_pages") 30 | kernel.trace("ext4_da_writepages") 31 | kernel.trace("ext4_da_writepages_result") 32 | kernel.trace("ext4_discard_blocks") 33 | kernel.trace("ext4_discard_preallocations") 34 | kernel.trace("ext4_forget") 35 | kernel.trace("ext4_free_blocks") 36 | kernel.trace("ext4_free_inode") 37 | kernel.trace("ext4_journalled_write_end") 38 | kernel.trace("ext4_mb_bitmap_load") 39 | kernel.trace("ext4_mb_buddy_bitmap_load") 40 | kernel.trace("ext4_mb_discard_preallocations") 41 | kernel.trace("ext4_mb_new_group_pa") 42 | kernel.trace("ext4_mb_new_inode_pa") 43 | kernel.trace("ext4_mb_release_group_pa") 44 | kernel.trace("ext4_mb_release_inode_pa") 45 | kernel.trace("ext4_mballoc_alloc") 46 | kernel.trace("ext4_mballoc_discard") 47 | kernel.trace("ext4_mballoc_free") 48 | kernel.trace("ext4_mballoc_prealloc") 49 | kernel.trace("ext4_ordered_write_end") 50 | kernel.trace("ext4_request_blocks") 51 | kernel.trace("ext4_request_inode") 52 | kernel.trace("ext4_sync_file") 53 | kernel.trace("ext4_sync_fs") 54 | kernel.trace("ext4_write_begin") 55 | kernel.trace("ext4_writeback_write_end") 56 | kernel.trace("ext4_writepage") 57 | kernel.trace("hrtimer_cancel") 58 | kernel.trace("hrtimer_expire_entry") 59 | kernel.trace("hrtimer_expire_exit") 60 | kernel.trace("hrtimer_init") 61 | kernel.trace("hrtimer_start") 62 | kernel.trace("irq_handler_entry") 63 | kernel.trace("irq_handler_exit") 64 | kernel.trace("itimer_expire") 65 | kernel.trace("itimer_state") 66 | kernel.trace("jbd2_checkpoint") 67 | kernel.trace("jbd2_checkpoint_stats") 68 | kernel.trace("jbd2_cleanup_journal_tail") 69 | kernel.trace("jbd2_commit_flushing") 70 | kernel.trace("jbd2_commit_locking") 71 | kernel.trace("jbd2_commit_logging") 72 | kernel.trace("jbd2_end_commit") 73 | kernel.trace("jbd2_run_stats") 74 | kernel.trace("jbd2_start_commit") 75 | kernel.trace("jbd2_submit_inode_data") 76 | kernel.trace("kfree") 77 | kernel.trace("kfree_skb") 78 | kernel.trace("kmalloc") 79 | kernel.trace("kmalloc_node") 80 | kernel.trace("kmem_cache_alloc") 81 | kernel.trace("kmem_cache_alloc_node") 82 | kernel.trace("kmem_cache_free") 83 | kernel.trace("kvm_ack_irq") 84 | kernel.trace("kvm_age_page") 85 | kernel.trace("kvm_apic") 86 | kernel.trace("kvm_apic_accept_irq") 87 | kernel.trace("kvm_apic_ipi") 88 | kernel.trace("kvm_cpuid") 89 | kernel.trace("kvm_cr") 90 | kernel.trace("kvm_emulate_insn") 91 | kernel.trace("kvm_entry") 92 | kernel.trace("kvm_exit") 93 | kernel.trace("kvm_fpu") 94 | kernel.trace("kvm_hv_hypercall") 95 | kernel.trace("kvm_hypercall") 96 | kernel.trace("kvm_inj_exception") 97 | kernel.trace("kvm_inj_virq") 98 | kernel.trace("kvm_invlpga") 99 | kernel.trace("kvm_ioapic_set_irq") 100 | kernel.trace("kvm_mmio") 101 | kernel.trace("kvm_mmu_get_page") 102 | kernel.trace("kvm_mmu_pagetable_walk") 103 | kernel.trace("kvm_mmu_paging_element") 104 | kernel.trace("kvm_mmu_set_accessed_bit") 105 | kernel.trace("kvm_mmu_set_dirty_bit") 106 | kernel.trace("kvm_mmu_sync_page") 107 | kernel.trace("kvm_mmu_unsync_page") 108 | kernel.trace("kvm_mmu_walker_error") 109 | kernel.trace("kvm_mmu_zap_page") 110 | kernel.trace("kvm_msi_set_irq") 111 | kernel.trace("kvm_msr") 112 | kernel.trace("kvm_nested_intercepts") 113 | kernel.trace("kvm_nested_intr_vmexit") 114 | kernel.trace("kvm_nested_vmexit") 115 | kernel.trace("kvm_nested_vmexit_inject") 116 | kernel.trace("kvm_nested_vmrun") 117 | kernel.trace("kvm_page_fault") 118 | kernel.trace("kvm_pic_set_irq") 119 | kernel.trace("kvm_pio") 120 | kernel.trace("kvm_set_irq") 121 | kernel.trace("kvm_skinit") 122 | kernel.trace("lock_kernel") 123 | kernel.trace("mce_record") 124 | kernel.trace("mm_page_alloc") 125 | kernel.trace("mm_page_alloc_extfrag") 126 | kernel.trace("mm_page_alloc_zone_locked") 127 | kernel.trace("mm_page_free_direct") 128 | kernel.trace("mm_page_pcpu_drain") 129 | kernel.trace("mm_pagevec_free") 130 | kernel.trace("module_free") 131 | kernel.trace("module_get") 132 | kernel.trace("module_load") 133 | kernel.trace("module_put") 134 | kernel.trace("module_request") 135 | kernel.trace("napi_poll") 136 | kernel.trace("power_end") 137 | kernel.trace("power_frequency") 138 | kernel.trace("power_start") 139 | kernel.trace("sched_kthread_stop") 140 | kernel.trace("sched_kthread_stop_ret") 141 | kernel.trace("sched_migrate_task") 142 | kernel.trace("sched_process_exit") 143 | kernel.trace("sched_process_fork") 144 | kernel.trace("sched_process_free") 145 | kernel.trace("sched_process_wait") 146 | kernel.trace("sched_stat_iowait") 147 | kernel.trace("sched_stat_runtime") 148 | kernel.trace("sched_stat_sleep") 149 | kernel.trace("sched_stat_wait") 150 | kernel.trace("sched_switch") 151 | kernel.trace("sched_wait_task") 152 | kernel.trace("sched_wakeup") 153 | kernel.trace("sched_wakeup_new") 154 | kernel.trace("scsi_dispatch_cmd_done") 155 | kernel.trace("scsi_dispatch_cmd_error") 156 | kernel.trace("scsi_dispatch_cmd_start") 157 | kernel.trace("scsi_dispatch_cmd_timeout") 158 | kernel.trace("scsi_eh_wakeup") 159 | kernel.trace("signal_deliver") 160 | kernel.trace("signal_generate") 161 | kernel.trace("signal_lose_info") 162 | kernel.trace("signal_overflow_fail") 163 | kernel.trace("skb_copy_datagram_iovec") 164 | kernel.trace("softirq_entry") 165 | kernel.trace("softirq_exit") 166 | kernel.trace("sys_enter") 167 | kernel.trace("sys_exit") 168 | kernel.trace("timer_cancel") 169 | kernel.trace("timer_expire_entry") 170 | kernel.trace("timer_expire_exit") 171 | kernel.trace("timer_init") 172 | kernel.trace("timer_start") 173 | kernel.trace("unlock_kernel") 174 | kernel.trace("workqueue_creation") 175 | kernel.trace("workqueue_destruction") 176 | kernel.trace("workqueue_execution") 177 | kernel.trace("workqueue_insertion") 178 | kernel.trace("xfs_agf") 179 | kernel.trace("xfs_alloc_busy") 180 | kernel.trace("xfs_alloc_busysearch") 181 | kernel.trace("xfs_alloc_exact_done") 182 | kernel.trace("xfs_alloc_exact_error") 183 | kernel.trace("xfs_alloc_near_error") 184 | kernel.trace("xfs_alloc_near_first") 185 | kernel.trace("xfs_alloc_near_greater") 186 | kernel.trace("xfs_alloc_near_lesser") 187 | kernel.trace("xfs_alloc_near_nominleft") 188 | kernel.trace("xfs_alloc_size_done") 189 | kernel.trace("xfs_alloc_size_error") 190 | kernel.trace("xfs_alloc_size_neither") 191 | kernel.trace("xfs_alloc_size_noentry") 192 | kernel.trace("xfs_alloc_size_nominleft") 193 | kernel.trace("xfs_alloc_small_done") 194 | kernel.trace("xfs_alloc_small_error") 195 | kernel.trace("xfs_alloc_small_freelist") 196 | kernel.trace("xfs_alloc_small_notenough") 197 | kernel.trace("xfs_alloc_unbusy") 198 | kernel.trace("xfs_alloc_vextent_allfailed") 199 | kernel.trace("xfs_alloc_vextent_badargs") 200 | kernel.trace("xfs_alloc_vextent_loopfailed") 201 | kernel.trace("xfs_alloc_vextent_noagbp") 202 | kernel.trace("xfs_alloc_vextent_nofix") 203 | kernel.trace("xfs_attr_list_add") 204 | kernel.trace("xfs_attr_list_full") 205 | kernel.trace("xfs_attr_list_leaf") 206 | kernel.trace("xfs_attr_list_leaf_end") 207 | kernel.trace("xfs_attr_list_node_descend") 208 | kernel.trace("xfs_attr_list_notfound") 209 | kernel.trace("xfs_attr_list_sf") 210 | kernel.trace("xfs_attr_list_sf_all") 211 | kernel.trace("xfs_attr_list_wrong_blk") 212 | kernel.trace("xfs_bdstrat_shut") 213 | kernel.trace("xfs_bmap_post_update") 214 | kernel.trace("xfs_bmap_pre_update") 215 | kernel.trace("xfs_btree_corrupt") 216 | kernel.trace("xfs_buf_bawrite") 217 | kernel.trace("xfs_buf_bdwrite") 218 | kernel.trace("xfs_buf_cond_lock") 219 | kernel.trace("xfs_buf_delwri_dequeue") 220 | kernel.trace("xfs_buf_delwri_queue") 221 | kernel.trace("xfs_buf_delwri_split") 222 | kernel.trace("xfs_buf_error_relse") 223 | kernel.trace("xfs_buf_find") 224 | kernel.trace("xfs_buf_free") 225 | kernel.trace("xfs_buf_get") 226 | kernel.trace("xfs_buf_get_noaddr") 227 | kernel.trace("xfs_buf_hold") 228 | kernel.trace("xfs_buf_init") 229 | kernel.trace("xfs_buf_iodone") 230 | kernel.trace("xfs_buf_ioerror") 231 | kernel.trace("xfs_buf_iorequest") 232 | kernel.trace("xfs_buf_iowait") 233 | kernel.trace("xfs_buf_iowait_done") 234 | kernel.trace("xfs_buf_item_committed") 235 | kernel.trace("xfs_buf_item_format") 236 | kernel.trace("xfs_buf_item_format_stale") 237 | kernel.trace("xfs_buf_item_iodone") 238 | kernel.trace("xfs_buf_item_iodone_async") 239 | kernel.trace("xfs_buf_item_pin") 240 | kernel.trace("xfs_buf_item_push") 241 | kernel.trace("xfs_buf_item_pushbuf") 242 | kernel.trace("xfs_buf_item_relse") 243 | kernel.trace("xfs_buf_item_size") 244 | kernel.trace("xfs_buf_item_size_stale") 245 | kernel.trace("xfs_buf_item_trylock") 246 | kernel.trace("xfs_buf_item_unlock") 247 | kernel.trace("xfs_buf_item_unlock_stale") 248 | kernel.trace("xfs_buf_item_unpin") 249 | kernel.trace("xfs_buf_item_unpin_stale") 250 | kernel.trace("xfs_buf_lock") 251 | kernel.trace("xfs_buf_lock_done") 252 | kernel.trace("xfs_buf_ordered_retry") 253 | kernel.trace("xfs_buf_pin") 254 | kernel.trace("xfs_buf_read") 255 | kernel.trace("xfs_buf_rele") 256 | kernel.trace("xfs_buf_unlock") 257 | kernel.trace("xfs_buf_unpin") 258 | kernel.trace("xfs_bunmap") 259 | kernel.trace("xfs_da_btree_corrupt") 260 | kernel.trace("xfs_delalloc_enospc") 261 | kernel.trace("xfs_dir2_block_addname") 262 | kernel.trace("xfs_dir2_block_lookup") 263 | kernel.trace("xfs_dir2_block_removename") 264 | kernel.trace("xfs_dir2_block_replace") 265 | kernel.trace("xfs_dir2_block_to_leaf") 266 | kernel.trace("xfs_dir2_block_to_sf") 267 | kernel.trace("xfs_dir2_grow_inode") 268 | kernel.trace("xfs_dir2_leaf_addname") 269 | kernel.trace("xfs_dir2_leaf_lookup") 270 | kernel.trace("xfs_dir2_leaf_removename") 271 | kernel.trace("xfs_dir2_leaf_replace") 272 | kernel.trace("xfs_dir2_leaf_to_block") 273 | kernel.trace("xfs_dir2_leaf_to_node") 274 | kernel.trace("xfs_dir2_leafn_add") 275 | kernel.trace("xfs_dir2_leafn_moveents") 276 | kernel.trace("xfs_dir2_leafn_remove") 277 | kernel.trace("xfs_dir2_node_addname") 278 | kernel.trace("xfs_dir2_node_lookup") 279 | kernel.trace("xfs_dir2_node_removename") 280 | kernel.trace("xfs_dir2_node_replace") 281 | kernel.trace("xfs_dir2_node_to_leaf") 282 | kernel.trace("xfs_dir2_sf_addname") 283 | kernel.trace("xfs_dir2_sf_create") 284 | kernel.trace("xfs_dir2_sf_lookup") 285 | kernel.trace("xfs_dir2_sf_removename") 286 | kernel.trace("xfs_dir2_sf_replace") 287 | kernel.trace("xfs_dir2_sf_to_block") 288 | kernel.trace("xfs_dir2_sf_toino4") 289 | kernel.trace("xfs_dir2_sf_toino8") 290 | kernel.trace("xfs_dir2_shrink_inode") 291 | kernel.trace("xfs_dqadjust") 292 | kernel.trace("xfs_dqalloc") 293 | kernel.trace("xfs_dqattach_found") 294 | kernel.trace("xfs_dqattach_get") 295 | kernel.trace("xfs_dqflush") 296 | kernel.trace("xfs_dqflush_done") 297 | kernel.trace("xfs_dqflush_force") 298 | kernel.trace("xfs_dqget_hit") 299 | kernel.trace("xfs_dqget_miss") 300 | kernel.trace("xfs_dqinit") 301 | kernel.trace("xfs_dqlookup_done") 302 | kernel.trace("xfs_dqlookup_found") 303 | kernel.trace("xfs_dqlookup_freelist") 304 | kernel.trace("xfs_dqlookup_want") 305 | kernel.trace("xfs_dqput") 306 | kernel.trace("xfs_dqput_free") 307 | kernel.trace("xfs_dqput_wait") 308 | kernel.trace("xfs_dqread") 309 | kernel.trace("xfs_dqread_fail") 310 | kernel.trace("xfs_dqreclaim_dirty") 311 | kernel.trace("xfs_dqreclaim_unlink") 312 | kernel.trace("xfs_dqreclaim_want") 313 | kernel.trace("xfs_dqrele") 314 | kernel.trace("xfs_dqreuse") 315 | kernel.trace("xfs_dqtobp_read") 316 | kernel.trace("xfs_dquot_dqalloc") 317 | kernel.trace("xfs_dquot_dqdetach") 318 | kernel.trace("xfs_extlist") 319 | kernel.trace("xfs_file_buffered_write") 320 | kernel.trace("xfs_file_direct_write") 321 | kernel.trace("xfs_file_read") 322 | kernel.trace("xfs_file_splice_read") 323 | kernel.trace("xfs_file_splice_write") 324 | kernel.trace("xfs_free_extent") 325 | kernel.trace("xfs_iext_insert") 326 | kernel.trace("xfs_iext_remove") 327 | kernel.trace("xfs_iget_alloc") 328 | kernel.trace("xfs_iget_found") 329 | kernel.trace("xfs_iget_reclaim") 330 | kernel.trace("xfs_iget_skip") 331 | kernel.trace("xfs_ihold") 332 | kernel.trace("xfs_ilock") 333 | kernel.trace("xfs_ilock_demote") 334 | kernel.trace("xfs_ilock_nowait") 335 | kernel.trace("xfs_inode") 336 | kernel.trace("xfs_inode_item_push") 337 | kernel.trace("xfs_inode_pin") 338 | kernel.trace("xfs_inode_unpin") 339 | kernel.trace("xfs_inode_unpin_nowait") 340 | kernel.trace("xfs_invalidatepage") 341 | kernel.trace("xfs_iomap_alloc") 342 | kernel.trace("xfs_iomap_enter") 343 | kernel.trace("xfs_iomap_found") 344 | kernel.trace("xfs_irele") 345 | kernel.trace("xfs_itruncate_finish_end") 346 | kernel.trace("xfs_itruncate_finish_start") 347 | kernel.trace("xfs_itruncate_start") 348 | kernel.trace("xfs_iunlock") 349 | kernel.trace("xfs_log_done_nonperm") 350 | kernel.trace("xfs_log_done_perm") 351 | kernel.trace("xfs_log_grant_enter") 352 | kernel.trace("xfs_log_grant_error") 353 | kernel.trace("xfs_log_grant_exit") 354 | kernel.trace("xfs_log_grant_sleep1") 355 | kernel.trace("xfs_log_grant_sleep2") 356 | kernel.trace("xfs_log_grant_wake1") 357 | kernel.trace("xfs_log_grant_wake2") 358 | kernel.trace("xfs_log_recover_buf_cancel") 359 | kernel.trace("xfs_log_recover_buf_cancel_add") 360 | kernel.trace("xfs_log_recover_buf_cancel_ref_inc") 361 | kernel.trace("xfs_log_recover_buf_dquot_buf") 362 | kernel.trace("xfs_log_recover_buf_inode_buf") 363 | kernel.trace("xfs_log_recover_buf_not_cancel") 364 | kernel.trace("xfs_log_recover_buf_recover") 365 | kernel.trace("xfs_log_recover_buf_reg_buf") 366 | kernel.trace("xfs_log_recover_inode_cancel") 367 | kernel.trace("xfs_log_recover_inode_recover") 368 | kernel.trace("xfs_log_recover_inode_skip") 369 | kernel.trace("xfs_log_recover_item_add") 370 | kernel.trace("xfs_log_recover_item_add_cont") 371 | kernel.trace("xfs_log_recover_item_recover") 372 | kernel.trace("xfs_log_recover_item_reorder_head") 373 | kernel.trace("xfs_log_recover_item_reorder_tail") 374 | kernel.trace("xfs_log_regrant_reserve_enter") 375 | kernel.trace("xfs_log_regrant_reserve_exit") 376 | kernel.trace("xfs_log_regrant_reserve_sub") 377 | kernel.trace("xfs_log_regrant_write_enter") 378 | kernel.trace("xfs_log_regrant_write_error") 379 | kernel.trace("xfs_log_regrant_write_exit") 380 | kernel.trace("xfs_log_regrant_write_sleep1") 381 | kernel.trace("xfs_log_regrant_write_sleep2") 382 | kernel.trace("xfs_log_regrant_write_wake1") 383 | kernel.trace("xfs_log_regrant_write_wake2") 384 | kernel.trace("xfs_log_reserve") 385 | kernel.trace("xfs_log_umount_write") 386 | kernel.trace("xfs_log_ungrant_enter") 387 | kernel.trace("xfs_log_ungrant_exit") 388 | kernel.trace("xfs_log_ungrant_sub") 389 | kernel.trace("xfs_pagecache_inval") 390 | kernel.trace("xfs_perag_clear_reclaim") 391 | kernel.trace("xfs_perag_get") 392 | kernel.trace("xfs_perag_get_reclaim") 393 | kernel.trace("xfs_perag_put") 394 | kernel.trace("xfs_perag_set_reclaim") 395 | kernel.trace("xfs_releasepage") 396 | kernel.trace("xfs_reset_dqcounts") 397 | kernel.trace("xfs_swap_extent_after") 398 | kernel.trace("xfs_swap_extent_before") 399 | kernel.trace("xfs_trans_bhold") 400 | kernel.trace("xfs_trans_bhold_release") 401 | kernel.trace("xfs_trans_binval") 402 | kernel.trace("xfs_trans_bjoin") 403 | kernel.trace("xfs_trans_brelse") 404 | kernel.trace("xfs_trans_commit_lsn") 405 | kernel.trace("xfs_trans_get_buf") 406 | kernel.trace("xfs_trans_get_buf_recur") 407 | kernel.trace("xfs_trans_getsb") 408 | kernel.trace("xfs_trans_getsb_recur") 409 | kernel.trace("xfs_trans_log_buf") 410 | kernel.trace("xfs_trans_read_buf") 411 | kernel.trace("xfs_trans_read_buf_io") 412 | kernel.trace("xfs_trans_read_buf_recur") 413 | kernel.trace("xfs_trans_read_buf_shut") 414 | kernel.trace("xfs_unwritten_convert") 415 | kernel.trace("xfs_writepage") 416 | --------------------------------------------------------------------------------