調度器9—調度相關trace匯總—Qcom


1. sched_find_best_target

打印:

cat-32758 [001] d..4  5235.529561: sched_find_best_target: pid=18090 comm=kworker/u16:25 start_cpu=0 best_idle=-1 most_spare_cap=-1 target=0 order_index=0 end_index=0 skip=-1 running=0

形參:

TP_PROTO(struct task_struct *tsk, unsigned long min_util, int start_cpu, int best_idle, int most_spare_cap, int target, int order_index, int end_index, int skip, bool running),

打印解析:

pid: 取參數 tsk->pid
comm: 取參數 tsk->comm
tart_cpu: 取參數 start_cpu
best_idle: 取參數 best_idle
most_spare_cap: 取參數 most_spare_cap
target: 取參數 target
order_index: 取參數 order_index
end_index: 取參數 end_index
skip: 取參數 skip
running: 取參數 running
注:min_util 傳參了,但是沒有打印它。

調用路徑:

check_for_migration
select_task_rq_fair
    find_energy_efficient_cpu //fair.c
        walt_find_best_target //fair.c
            trace_sched_find_best_target

說明:
是對任務p選核路徑中的trace,Qcom的WALT算法帶入的函數。

調用傳參: 

trace_sched_find_best_target(p, min_util, start_cpu, best_idle_cpu, most_spare_cap_cpu, target_cpu, order_index, end_index, fbt_env->skip_cpu, p->state == TASK_RUNNING);

實參解析:

p: 
    為p選核
min_util:
    返回的是被鉗位在 uclamp_max 和 uclamp_min 之間的 p->wts.demand_scaled 值,就是被鉗位后p的util值。但是 trace 沒有打印它。
start_cpu:
    表示從哪個cluster中開始選核,walt_get_indicies()中做邏輯判斷,若是有BOOST就按BOOST類型選核,若沒有,則找一個算力大於任務demand的CPU核開始選。從這里的執行邏輯看,start_cpu一
    定是某個cluster的首個CPU.
best_idle_cpu:
    初始化為-1,首先從start_cpu開始遍歷所有cpu,找到一個idle深度最淺的cpu,但是若選核任務是rtg標記的任務,就又把best_idle_cpu清成-1了。
most_spare_cap_cpu:
    初始化為-1,從start_cpu開始遍歷所有cpu,表示找到的空閑算力最大的cpu。空閑算力指的是此CPU的算力減去任務p在此CPU上的貢獻,若任務p是新    建或剛喚醒或之前不是運行在這個CPU上,直接返
    回task_util(cpu),也就是WALT下的 cpu_rq(cpu)->wrq.walt_stats.cumulative_runnable_avg_scaled。
target_cpu: 
    (1)快速路徑:任務p之前運行的cpu的算力和start_cpu相同(不多不少)或兩者是兄弟cpu,並且之前運行的cpu是onlline的,並且沒有isolate,並且是idle狀態,並且idle深度小於或等於1,然后走快速路徑,
    直接選prev_cpu為target_cpu,設置為候選者。
    (2)慢速路徑:若快速路徑沒有選到CPU,則會從start_cpu開始遍歷所有CPU進行選核。依次為:Android留了hook接口vendor廠商可以自己制定策略剔除一部分CPU。剔除非active的CPU。    剔除isolated的CPU。
    剔除尚未完成的遷移的目標CPU。剔除irq負載高的CPU。若是當前CPU喚醒比較多剔除當前CPU。若某個CPU上的當前任務正在per-task的boost就剔除這個CPU。    CPU原來的利用率加上任務p的利用率后超過其算
    力了也剔除。若是idle cpu,但不是idle最淺的cpu也剔除,若dile深度一致但之前有發現idle的cpu是任務之前運行的cpu時 或 這個CPU雖然idle深度和之前選出的一樣,但是不是任務p之前運行的CPU並且其
    利用率也比之前選的idle CPU的高,也剔除。若P->state=RUNNING的主動遷移的任務剔除非idle的CPU。若p是rtg組    里的任務並且優先級數值低於99,若此CPU上有比之前記錄的CPU的rtg高優先級任務多,也
    剔除,若數量相同,非空余算力最大的也剔除。若以上都沒剔除,就將此CPU作為best_target,然后遍歷下一個CPU。
    最終將 target_cpu 和 best_idle_cpu 都作為選出的best target cpu 設置進候選CPU中去了。
order_index:
    walt_get_indicies() 中修改的,應該是根據算力和BOOST情況選出來的從哪個cluster開始選核
end_index:
    walt_get_indicies() 中有修改,若是有BOOST可能大於0,應該表示結束選核的cluster.
fbt_env->skip_cpu:
    若當前CPU上有超過1000個任務待喚醒時,將當前CPU設置到skip的,為p選核時不選它。
p->state == TASK_RUNNING:
    表示為任務選核時任務的狀態是不是正在running,若是就表示是active遷移的任務,只會為其選擇idle核。

 

2. sched_task_util

打印:

kworker/u16:1-23809 [001] d..3 280354.250435: sched_task_util: pid=23645 comm=kworker/u16:4 util=156 prev_cpu=3 candidates=0x8 best_energy_cpu=3 sync=0 need_idle=0
fastpath=2 placement_boost=0 latency=2343 stune_boosted=0 is_rtg=0 rtg_skip_min=0 start_cpu=0 unfilter=20000000 affinity=ff task_boost=0 low_latency=0

形參:

TP_PROTO(struct task_struct *p, unsigned long candidates, int best_energy_cpu, bool sync, int need_idle, int fastpath, bool placement_boost, u64 start_t,
        bool uclamp_boosted, bool is_rtg, bool rtg_skip_min, int start_cpu),

打印解析:

pid: 取自 p->pid
comm: 取自 p->comm
util: 取自參數p的 task_util(p),WALT算法下是 p->wts.demand_scaled,PELT算法下是 p->se.avg.util_avg
prev_cpu: 取自參數p的 task_cpu(p),即 p->cpu
candidates: 取自參數 candidates
best_energy_cpu: 取自參數 best_energy_cpu
sync: 取自參數 sync
need_idle: 取自參數 need_idle
fastpath: 取自參數 fastpath
placement_boost: 取自參數 placement_boost
latency: 取自 sched_clock() - 參數 start_t
stune_boosted: 取自參數 uclamp_boosted
is_rtg: 取自參數 is_rtg
rtg_skip_min: 取自參數 rtg_skip_min
start_cpu: 取自參數 start_cpu
unfilter: 取自 p->wts.unfilter
affinity: 取自 cpumask_bits(&p->cpus_mask)[0],即 ((&p->cpus_mask)->bits)[0]
task_boost: 取自 per_task_boost(p),即 p->wts.boost
low_latency: 取自 walt_low_latency_task(p),即 p->wts.low_latency && (task_util(p) < sysctl_walt_low_latency_task_threshold),目前Qcom還沒enable此功能,因此一直是0.

調用路徑:

check_for_migration //qc_vas.c
select_task_rq_fair //fair.c
    find_energy_efficient_cpu //fair.c 函數結束位置調用
        trace_sched_task_util

說明:
在為任務的選核路徑中,對任務的信息進行trace.

調用傳參: 

trace_sched_task_util(p, cpumask_bits(candidates)[0], best_energy_cpu, sync, fbt_env.need_idle, fbt_env.fastpath,
        task_boost_policy(p), start_t, boosted, is_rtg, walt_get_rtg_status(p), start_cpu);

實參解析:

p:
    為任務p選核
cpumask_bits(candidates)[0]:
    walt_find_best_target()中為任務p選出來的候選cpu,位掩碼,是怎么選的可參考 trace_sched_find_best_target,如0x8就是CPU3
best_energy_cpu:
    初始化為prev_cpu,然后根據條件進行更新,是 find_energy_efficient_cpu() 的最終返回結果。
sync:
    是 find_energy_efficient_cpu() 傳入的參數,如果想sync喚醒,又是時間敏感,或任務和當前任務都是rtg組中的任務,就清除掉sync標志。sync標志會導致更傾向於喚醒后運行在在當前cpu上,
    只要條件滿足:cpu在任務p允許運行的cpu里面,並且是active的,並且cpu的算力要大於start_cpu的算力。
fbt_env.need_idle:
    任務p通過 /proc/<PID>/sched_wake_up_idle 設置過,或其所在的任務組通過 /dev/cpuctl/<xx_group>/cpu.uclamp.latency_sensitive 賦值過,任務就有 wakeup_idle 屬性了。有此屬性后,就會
    將sync標志清0,也更傾向於選擇 walt_find_best_target 選出來的cpu,降低通過EAS選核的概率。
fbt_env.fastpath:
    滿足sync的同步喚醒的話,賦值為 SYNC_WAKEUP=1,若在 walt_find_best_target 中滿足快速路徑選核心,會被設置為 PREV_CPU_FASTPATH=2
task_boost_policy(p):
    返回全局變量 boost_policy 的值,來自 /proc/sys/kernel/sched_boost,只能取 SCHED_BOOST_NONE=0 或 SCHED_BOOST_ON_BIG=1
start_t:
    是個事件點,選核流程開始前 sched_clock() 獲取的時間,trace中打印的 latency 值大概可以表示選核花費的時間,大概 1-6us
boosted: 
    來自 is_uclamp_boosted || (task_boost > 0),前者來自 /dev/cpuctl/<xx_group>/cpu.uclamp.min 的賦值,后者是來自 p->wts.boost,由 /proc/<pid>/sched_boost 設置,它是per-task的boot,並且
    可以指定boost的時間段的長短,若是boost了,就更傾向於不經過EAS選核流程。
is_rtg: 
    p->wts.grp != NULL 表示被選核的任務p不是rtg組中的任務。為真的話就會將sync標志清0,也更傾向於選擇 walt_find_best_target 選出來的cpu,降低通過EAS選核的概率。
walt_get_rtg_status(p): 
    主要是返回 grp->skip_min 的值,應該是表示是否跳過小核,但是在選核路徑中還沒發現他起什么作用。
start_cpu: 
    從 start_cpu 開始選核,start_cpu 是根據算力需求得來的。

 

3. sched_migrate_task

打印:

adbd-1290  [003] d..3 260655.930040: sched_migrate_task: comm=UsbFfs-worker pid=17754 prio=120 orig_cpu=3 dest_cpu=1 running=0

形參:

TP_PROTO(struct task_struct *p, int dest_cpu)

打印解析:

comm: 取自 p->comm
pid: 取自 p->pid
prio: 取自 p->prio
orig_cpu: 取自task_cpu(p),表示遷移前任務的cpu
dest_cpu: 取自參數 dest_cpu
running:  bool值,取自 p->state == TASK_RUNNING,walt_find_best_target 中描述:為true表示是active遷移,dest_cpu只選idle核。

調用路徑:

move_queued_task //core.c
__migrate_swap_task //core.c
try_to_wake_up //發現任務p的prev_cpu和選核選出來的cpu不是同一個cpu時調用
dl_task_offline_migration
push_dl_task //deadline.c
pull_dl_task //deadline.c
detach_task //fair.c
push_rt_task //rt.c
pull_rt_task //rt.c
    set_task_cpu //core.c
        trace_sched_migrate_task(p, new_cpu);

說明:
在任務的遷移路徑中trace

調用傳參: 

trace_sched_migrate_task(p, new_cpu);

實參解析:

p: 
    被遷移的任務
dest_cpu: 
    遷移的目的CPU

 

4. sched_isolate

打印:

core_ctl/0-434   [002] .... 304625.209544: sched_isolate: iso cpu=5 cpus=0x30 time=1595 us isolated=1
core_ctl/0-434   [001] .... 304628.095985: sched_isolate: iso cpu=4 cpus=0x20 time=460 us isolated=0

形參:

TP_PROTO(unsigned int requested_cpu, unsigned int isolated_cpus, u64 start_time, unsigned char isolate),

打印解析:

iso cpu: 取自參數 requested_cpu
cpus: 取自參數 isolated_cpus
time: 取自 div64_u64(sched_clock() - start_time, 1000),時間差值轉換為us,表示隔離CPU操作和去掉隔離CPU操作各花費多少時間
isolated: 取自參數 isolate

調用路徑:

try_to_isolate //core_ctl.c
cpu_isolate_pm_notify //drivers\thermal\qcom\cpu_isolate.c
cpu_isolate_set_cur_state //drivers\thermal\qcom\cpu_isolate.c
hyp_core_ctl_do_reservation //drivers\soc\qcom\hyp_core_ctl.c
    sched_isolate_cpu
        trace_sched_isolate(cpu, cpumask_bits(cpu_isolated_mask)[0], start_time, 1) //隔離


    isolation_cpuhp_state //core_ctl.c
    cpu_isolate_hp_offline //core_ctl.c
    hyp_core_ctl_hp_offline //drivers\soc\qcom\hyp_core_ctl.c
__try_to_unisolate //core_ctl.c
cpu_isolate_set_cur_state //cpu_isolate.c
hyp_core_ctl_undo_reservation //hyp_core_ctl.c
hyp_core_ctl_do_reservation //hyp_core_ctl.c
hyp_core_ctl_cpu_cooling_cb //hyp_core_ctl.c
    sched_unisolate_cpu //kernel/sched/qc_vas.c
        sched_unisolate_cpu_unlocked
            trace_sched_isolate(cpu, cpumask_bits(cpu_isolated_mask)[0], start_time, 0); //取消隔離

說明:

trace要隔離/取消隔離的cpu、時間、cpu核的隔離狀態。

調用傳參:

見調用路徑

實參解析:

cpu: 
    要被隔離和取消隔離的cpu
cpumask_bits(cpu_isolated_mask)[0]: 
    已經被isolate的cpus的mask,不算正在被操作的這個
start_time: 
    開始進行隔離/取消隔離的時間點
1/0: 
    1是隔離cpu,0是取消隔離cpu.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM