Eu quero alcançar 3 metas.
Iterar task
s por meio de task_group
Aquire rq
task
s anexado a.
Agrupe os task
s por rq
e, em seguida, bloqueie o rq
antes de iterar task
s (a razão para isso é que eu quero que cfs_rq
tenha uma visualização consistente)
Eu tentei 4 abordagens. Eu sou novo no kernel, então eles podem parecer bobos.
Approache 1
cgrp = css_tg(tg)->cgroup;
css_task_iter_start(&cgrp->self, &it);
while ((tsk = css_task_iter_next(&it))) {
rq = task_rq_lock(tsk, &rf);
do_sth_with(tsk, rq);
task_rq_unlock(rq, tsk, &rf);
}
css_task_iter_end(&it);
Isso não funciona. Não atinge o objetivo # 3
Approache 2
for_each_possible_cpu(cpu) {
rq = cpu_rq(cpu);
raw_spin_lock_irq(&rq->lock);
rbtree_postorder_for_each_entry_safe(p, n, tg->cfs_rq[cpu]->tasks_timeline, se.runnode) {
do_sth_with(p, rq);
}
raw_spin_unlock_irq(&rq->lock);
}
Isso não funciona, porque as tarefas podem migrar entre CPUs.
Approache 3
Semelhante à abordagem 1, mas, enquanto iterada, eu agrupo task
s por cpu e armazeno-os em uma matriz de lista por cpu:
struct my_list {
struct list_head my_list_head;
struct task_struct *tsk;
} my_list_head[cpu];
Depois, faço uma iteração de tarefas em cada rq.
Isso não funciona, até eu os agrupo. Da próxima vez, eles ainda podem ter migrado entre processadores. Porque task->pi_lock
nunca está bloqueado.
Approache 4
Eu queria saber se freezer
pode resolver esse problema. Mas saiu, todas as tarefas não são freezable.
Todas essas abordagens bobas que eu inventei não podem resolver o meu problema.
Por fim, usar stop_machine
para interromper a máquina inteira resolve esse problema. Mas é muito pesado.
Você pode me dar alguns conselhos sobre esse problema? Obrigado!