Como iterar tarefas em um cgroup, uma cpu de cada vez, segurando o bloqueio do runqueue?

0

Eu quero alcançar 3 metas.

  1. Iterar task s por meio de task_group

  2. Aquire rq task s anexado a.

  3. 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!

    
por wuyihao 01.03.2018 / 07:45

0 respostas