sched_child_runs_first
私が理解できることから、機能が実装されている場所は関数内にあり、ここでtask_fork_fair
見ることができるソースです。
その関数の重要な部分は次のようになります。
if (curr)
se->vruntime = curr->vruntime;
place_entity(cfs_rq, se, 1);
if (sysctl_sched_child_runs_first && curr && entity_before(curr, se)) {
swap(curr->vruntime, se->vruntime);
resched_task(rq->curr);
}
seは新しいスケジューリング エンティティで、currは現在のタスクのスケジューリング エンティティです。
新しいエンティティのvruntimeは、最初に現在のタスクと同じ値で初期化されることに注意してください。呼び出しはcurrのvruntimeがseのvruntimeより小さいentity_before
かどうかをチェックしているため、これは重要です。
したがって、その条件が成功する唯一の方法は、呼び出しがseのvruntimeをより大きな値にplace_entity
設定する場合です。それでは、そのソースを見てみましょう。キービットは次のとおりです。
u64 vruntime = cfs_rq->min_vruntime;
if (initial && sched_feat(START_DEBIT))
vruntime += sched_vslice(cfs_rq, se);
se->vruntime = max_vruntime(se->vruntime, vruntime);
したがって、START_DEBIT
機能が設定されていると仮定すると (これは事実のようです)、vruntimeは実行キューのmin_vruntimeに加えてsched_vslice
呼び出しが返すものに設定されます。これが現在のvruntimeよりも大きい場合は設定されています。そうでない場合は、初期のvruntime値が残され、条件は成功しません。
Linux のスケジューリングについては、断言できるほどよく理解していませんが、ほとんどの場合、 min_vruntimeに加えsched_vslice
て十分な大きさではないと推測しています。
ほとんどの場合、私がテストしていたとき、子プロセスを最初に実行することができたので、少なくとも時々そう言います。そのため、パラメーターによって違いが生じる可能性がありsched_child_runs_first
ます。これは、何かを保証するものではありません。
もう 1 つの可能性は、コードのバグであり、関数で初期値を計算するときに、実行キューのmin_vruntimeではなく、現在のタスクのvruntimeで開始する必要があることです。これにより、条件が成功することが保証されます。しかし、私が理解していない理由があると思います。place_entity