linux排程器/proc資訊解讀
轉載自 https://blog.csdn.net/wudongxu/article/details/8574755
注下面的時間或時刻都是從rq->clock中獲得的,而這個值是由update_rq_clock底層cpu來更新的。並且很多資訊是需要核心配置CONFIG_SCHEDSTATS才有。
/proc/<pid>/sched
$cat /proc/28733/sched cpu_test (28733, #threads: 1) --------------------------------------------------------- se.exec_start : 2781299327.397282 //此程序最近被排程到的開始執行時刻(這個值是每次update_curr都進行更新) se.vruntime : 3144603.079903 //虛擬執行時間 se.sum_exec_runtime: 2843625.998498 //累計執行的物理時間時間 se.wait_start : 0.000000 //最近一次當前程序被入隊的時刻 se.sleep_start : 0.000000 //此程序最近一次被從佇列裡取出,並被置S狀態的時刻 se.block_start : 0.000000 //此程序最近一次被從佇列裡取出,並被置D狀態的時刻 se.sleep_max : 0.000000 //最長處於S狀態時間 se.block_max : 0.000000 //最長處於D狀態時間 se.exec_max : 1.004266 //最長單次執行時間 se.slice_max : 998.456300 //曾經獲得時間片的最長時間 se.wait_max : 0.455235 //最長在就緒佇列裡的等待時間 se.wait_sum : 15.615407 //累計在就緒佇列裡的等待時間 se.wait_count : 3147 //累計等待次數 se.iowait_sum : 215.825267 //io等待時間 se.iowait_count : 67 //io等待次數 io_schedule呼叫次數 sched_info.bkl_count: 0 //此程序大核心鎖呼叫次數 se.nr_migrations : 0 //需要遷移當前程序到其他cpu時累加此欄位 se.nr_migrations_cold: 0 se.nr_failed_migrations_affine: 194 //程序設定了cpu親和,程序遷移時檢查失敗的次數 se.nr_failed_migrations_running: 0 se.nr_failed_migrations_hot: 0 //當前程序因為是cache hot導致遷移失敗的次數 se.nr_forced_migrations : 0 //在當前程序cache hot下,由於負載均衡嘗試多次失敗,強行進行遷移的次數 se.nr_wakeups : 0 //被喚醒的累計次數(從不可執行到可執行) se.nr_wakeups_sync : 0 //同步喚醒次數,即a喚醒b,a立刻睡眠,b被喚醒的次數 se.nr_wakeups_migrate : 0 //被喚醒得到排程的當前cpu,不是之前睡眠的cpu的次數 se.nr_wakeups_local : 0 //被本地喚醒的次數(喚醒後在當前cpu上執行) se.nr_wakeups_remote : 0 //非本地喚醒累計次數 se.nr_wakeups_affine : 0 //考慮了任務的cache親和性的喚醒次數 se.nr_wakeups_affine_attempts: 0 se.nr_wakeups_passive : 0 se.nr_wakeups_idle : 0 avg_atom : 903.886204 //本程序平均耗時sum_exec_runtime/ nr_switches avg_per_cpu : 0.000001 nr_switches : 3146 //主動切換和被動切換的累計次數 nr_voluntary_switches : 0 //主動切換次數(由於prev->state為不可執行狀態引起的切換) nr_involuntary_switches : 3146 //被動切換次數 se.load.weight : 1024 //該se的load policy : 0 //排程策略 normal prio : 120 //優先順序(nice=0) clock-delta : 51 |
大多數字段的計算在sched.c及sched_fair.c裡,在這兩個檔案裡搜尋相應的欄位就能得到相應的計算方法。
/proc/<pid>/schedstat
$cat /proc/28733/schedstat 5726055470233 30451531 6336 |
該資訊的入口在fs/proc/base.c的proc_pid_schedstat函式裡。
/proc/<pid>/status
$cat /proc/28733/status Name: cpu_test State: R (running) Tgid: 28733 Pid: 28733 PPid: 5573 TracerPid: 0 Uid: 52170 52170 52170 52170 // uid euid suid fsuid Gid: 100 100 100 100 // gid egid sgid fsgid Utrace: 0 FDSize: 256 Groups: 100 19051 //啟動該程序的使用者所屬的組的id,並不是組排程的組 VmPeak: 3976 kB VmSize: 3912 kB //任務虛擬地址空間的大小 (total_vm-reserved_vm),其中total_vm為程序的地址空間的大小,reserved_vm:程序在預留或特殊的記憶體間的物理頁,該值也是top的VIRT欄位 VmLck: 0 kB //任務已經鎖住的實體記憶體的大小。鎖住的實體記憶體不能交換到硬碟 (locked_vm) VmHWM: 328 kB //檔案記憶體對映和匿名記憶體對映的大小 VmRSS: 328 kB //應用程式正在使用的實體記憶體的大小,就是用top的res欄位 VmData: 44 kB //程式資料段的大小(所佔虛擬記憶體的大小),存放初始化了的資料; (total_vm-shared_vm-stack_vm) VmStk: 88 kB //任務在使用者態的棧的大小 (stack_vm) VmExe: 4 kB //程式所擁有的可執行虛擬記憶體的大小,程式碼段,不包括任務使用的庫 (end_code-start_code) VmLib: 1700 kB //被映像到任務的虛擬記憶體空間的庫的大小 (exec_lib) VmPTE: 32 kB //該程序的所有頁表的大小,單位:kb VmSwap: 0 kB Threads: 1 //執行緒數 SigQ: 1/193060 //待處理訊號的個數 SigPnd: 0000000000000000 //遮蔽位,儲存了該執行緒的待處理訊號 ShdPnd: 0000000000000000 //遮蔽位,儲存了該執行緒組的待處理訊號 SigBlk: 0000000000000000 //存放被阻塞的訊號 SigIgn: 0000000000000000 //存放被忽略的訊號 SigCgt: 0000000000000000 //存放被捕捉到的訊號 CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: ffffffffffffffff Cpus_allowed: 000008 //可以使用的cpu bit Cpus_allowed_list: 3 //可以使用的cpu id list Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001 //可使用的mem Mems_allowed_list: 0 //可使用的mem list voluntary_ctxt_switches: 0 //主動的切換 nonvoluntary_ctxt_switches: 8310 //被動的切換 |
入口在fs/proc/array.c的proc_pid_status函式裡,參考http://www.kerneltravel.net/?p=294
/proc/<pid>/stat
在核心中,該檔案的內容由do_task_stat函式(fs/proc/array.c)寫。主要操作是
28733 (cpu_test) R 5573 28733 5573 34824 5573 4202496 176 0 0 0 1797172 80 0 20 0 1 0 2782750364005888 82 184467440737095516154194304 4195884 140733625322688 140733625322136 41954610 0 0 0 0 0 0 17 3 00 0 0 0 seq_printf(m, "%d (%s) %c %d %d%d %d %d %u %lu \ %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ %lu %lu %lu %lu %lu %lu%lu %lu %d %d %u %u %llu %lu %ld\n", 1 .pid_nr_ns(pid, ns), //pid 2 .tcomm, //程序名 3 .state, //程序狀態 4 .ppid, //父程序號 5 .pgid, //執行緒組ID 6 .sid, //會話組ID 7 .tty_nr, //該程序的tty終端的裝置號,INT(34817/256)=主裝置號,(34817-主裝置號)=次裝置號 8 .tty_pgrp, //終端的程序組號,當前執行在該程序所在終端的前臺程序(包括shell應用程式)的PID 9 .task->flags, //程序標誌位,檢視該程序的特性(定義在/include/kernel/sched.h中) 10.min_flt, //累計程序的次缺頁數(Copy on Write頁和匿名頁) 11.cmin_flt, //該程序所有的子程序發生的次缺頁的次數 12.maj_flt, //主缺頁數(從對映檔案或交換裝置讀入的頁面數) 13.cmaj_flt, //該程序所有的子程序發生的主缺頁的次數 14.cputime_to_clock_t(utime), //該程序在使用者態執行的時間,單位為jiffies 15.cputime_to_clock_t(stime), //該程序在核心態執行的時間,單位為jiffies 16.cputime_to_clock_t(cutime), //該程序所有的子程序在使用者態執行的時間總和,單位為jiffies 17.cputime_to_clock_t(cstime), //該程序所有的子程序在核心態執行的時間的總和,單位為jiffies 18.priority, //程序的優先順序 19.nice, //程序的靜態優先順序 20.num_threads, //該程序所在的執行緒組裡執行緒的個數 21.//0 22.start_time, //該程序建立的時間 23.vsize, //該程序的虛擬地址空間大小 24.mm ? get_mm_rss(mm) : 0, //該程序當前駐留實體地址空間的大小 25.rsslim, //該程序能駐留實體地址空間的最大值 26.mm ? (permitted ? mm->start_code : 1) : 0, //該程序在虛擬地址空間的程式碼段的起始地址 27.mm ? (permitted ? mm->end_code : 1) : 0, //該程序在虛擬地址空間的程式碼段的結束地址 28.(permitted && mm) ? mm->start_stack : 0, //該程序在虛擬地址空間的棧的結束地址 29.esp, //esp(32 位堆疊指標) 的當前值,與在程序的核心堆疊頁得到的一致 30.eip, //指向將要執行的指令的指標, EIP(32位指令指標)的當前值 31.task->pending.signal.sig[0] & 0x7fffffffUL, //待處理訊號的點陣圖,記錄傳送給程序的普通訊號 32.task->blocked.sig[0] & 0x7fffffffUL, //阻塞訊號的點陣圖 33.sigign .sig[0] & 0x7fffffffUL, //忽略的訊號的點陣圖 34.sigcatch .sig[0] & 0x7fffffffUL, //被捕捉的訊號的點陣圖 35.wchan, //如果該程序是睡眠狀態,該值給出排程的呼叫點 36.0UL, 37.0UL, 38.task->exit_signal, //該程序結束時,向父程序所傳送的訊號 39.task_cpu(task), //執行在哪個CPU上 40.task->rt_priority, //實時程序的相對優先級別 41.task->policy, //程序的排程策略 42.(unsigned long long)delayacct_blkio_ticks(task), 43.cputime_to_clock_t(gtime), 44.cputime_to_clock_t(cgtime)); |
注:這個輸出的中間自動填充了個0,在22 start_time前。參考http://www.kerneltravel.net/?p=291
/proc/sched_debug
這個打印出所有cpu的資訊,這裡我們過濾出cpu3來解釋
$cat /proc/sched_debug | grep "cpu#3" -A 73 Sched Debug Version: v0.09, 2.6.32-220.23.1.tb704.el6.x86_64 #1 now at 2805981745.049080 msecs .jiffies : 7100649040 //cpu時間 .sysctl_sched_latency : 20.000000 .sysctl_sched_min_granularity : 4.000000 .sysctl_sched_wakeup_granularity : 4.000000 .sysctl_sched_child_runs_first : 0.000000 .sysctl_sched_features : 3183 .sysctl_sched_tunable_scaling : 1 (logaritmic) cpu#3, 2399.773 MHz .nr_running : 2 //cpu3 rq執行佇列的程序個數(包括正在執行的) .load : 2048 //cpu3 rq執行佇列的load .nr_switches : 42606615 //cpu3累計的程序切換次數 .nr_load_updates : 220734972 //load更新次數,也是呼叫update_cpu_load次數 .nr_uninterruptible : 0 // uninterruptible發生的次數 .next_balance : 7100.059585 //下次執行負載均衡的時間 .curr->pid : 25329 //當前執行的程序pid .clock : 2801062666.343504 //當前執行佇列的clock .cpu_load[0] : 2048 //該cpu的歷史load .cpu_load[1] : 2048 .cpu_load[2] : 2048 .cpu_load[3] : 2048 .cpu_load[4] : 2048 .yld_count : 1 //呼叫yield次數 .sched_switch : 0 .sched_count : 160158232 //呼叫schedule的次數 .sched_goidle : 21108490 //切換到idle程序的次數 .avg_idle : 1000000 // cpu處於idle的平均時間 .ttwu_count : 21244621 //此cpu try_to_wake_up喚醒程序的次數 .ttwu_local : 20424010 //本地喚醒的次數,即程序睡眠前所在cpu為當前cpu .bkl_count : 1 //此cpu上大核心鎖呼叫次數 //下面是相應的cfs_rq內容,另外我們的執行程序在/cgroup/one 這個二級cgroup裡 cfs_rq[3]:/one //one group .exec_clock : 22907786.300379 // .MIN_vruntime : 22901158.741275 //紅黑樹最左邊的vruntime .min_vruntime : 22901158.741275 //cfs_rq當前的min_vruntime .max_vruntime : 22901158.741275 //最右邊的vruntime(這裡因為只有一個,另一個在執行,所以最左與最右相等) .spread : 0.000000 .spread0 : -300525615.387521 // cpu0上的min_vruntime與當前cpu的min_vruntime差值 .nr_spread_over : 0 .nr_running : 2 //該cfs_rq執行佇列的程序個數(注:雖然執行的程序不在紅黑樹裡,但是它還是cfs_rq裡) .load : 2048 //該cfs_rq的load,是它下面兩個程序的load之和(在account_entity_enqueue、account_entity_dequeue更新) .load_avg : 16496.090916 //update_cfs_load的統計值 .load_period : 8.054731 .load_contrib : 2047 .load_tg : 2047 .se->exec_start : 2801062666.343504 //該cgroup的se排程實體(非它下面程序的se,而是它自身的se)下面的關於se的內容與每個程序自身的/proc/<pid>/sched內的含意是一樣的 .se->vruntime : 188458882.115828 .se->sum_exec_runtime : 22907786.300379 .se->wait_start : 0.000000 .se->sleep_start : 0.000000 .se->block_start : 0.000000 .se->sleep_max : 0.000000 .se->block_max : 0.000000 .se->exec_max : 1.073055 .se->slice_max : 0.000000 .se->wait_max : 0.041254 .se->wait_sum : 121.099885 .se->wait_count : 28673 .se->load.weight : 2048 //這個se本身的load,它是通過update_cfs_shares更新
cfs_rq[3]:/ //同上 .exec_clock : 182645727.024410 .MIN_vruntime : 0.000001 .min_vruntime : 188458882.115828 .max_vruntime : 0.000001 .spread : 0.000000 .spread0 : -134967892.012968 .nr_spread_over : 4 .nr_running : 1 .load : 2048 .load_avg : 0.000000 .load_period : 0.000000 .load_contrib : 0 .load_tg : 0
runnable tasks: //執行佇列裡的程序,有兩個28733,25329,並且當前執行的是25329 task PID tree-key switches prio exec-runtime sum-exec sum-sleep ---------------------------------------------------------------------------------------------------------- cpu_test 28733 22901158.741275 26280 120 22901158.741275 22600181.659870 0.000000 /one R cpu_test 25329 22901163.146132 404 120 22901163.146132 6413.013913 0.000000 /one
|
該資訊的列印入口在sched_debug.c的sched_debug_show函式。
注:上面的很多資訊是從網上搜索,再加上自己對排程器相關欄位的驗證,其它的內容沒有驗證
參考資料
http://chxxxyg.blog.163.com/blog/static/1502811932012912546208/
http://blog.csdn.net/chenyu105/article/details/7068758
proc目錄解析:http://www.kerneltravel.net/?p=294
rq結構的註釋:http://blog.csdn.net/bullbat/article/details/7160246