Qual é a prioridade da tarefa ociosa?

1

Como explicado por vários (um pouco antigos) artigos , a tarefa inativa do Linux (PID = 0, um por CPU) é executada quando não há outras tarefas para executar. Para obter o agendador, a tarefa ociosa deve ter a prioridade mais baixa reservada para ela. O antigo Documentation/ftrace.txt no artigo LWN vinculado diz explicitamente que

The prio "140" is reserved for the idle task which is the lowest priority thread (pid 0).

Isso faz sentido, mas no Linux 4.9

# perf record -e sched:sched_switch sleep 1
# perf script
   sleep  6526 [000] 362661.310842: sched:sched_switch: sleep:6526 [120] S ==> swapper/0:0 [120]

informa uma prioridade de 120 para swapper/0 (no colchete de fechamento), contradizendo o acima.

Como o agendador de Linux lida com a tarefa ociosa hoje em dia? O commits alterando ftrace.txt (87d80de28, 294ae4011) não ajudou.

    
por Ferenc Wágner 02.04.2018 / 19:22

1 resposta

0

Eu tenho uma resposta bacana de Till Smejkal na lista de discussão do kernel do Linux:

The idle task has its own scheduling class that only handles the idle threads per CPU core. This scheduling class has the lowest priority of the scheduling classes available in the kernel. This means that it is the last one in the list of scheduling classes that are asked at a task switch whether they have a task to schedule on the CPU. Hence, the idle task is not managed by CFS and accordingly doesn't have any nice value or priority (or at least it is not important nowadays). Interesting files in the kernel source that might contain more information are kernel/sched/idle_task.c, kernel/sched/sched.h and kernel/sched/core.c.

No entanto, de acordo com o meu entendimento, as tarefas podem ter prioridade apesar de não serem gerenciadas pelo CFS: tarefas em tempo real ( SCHED_FIFO e SCHED_RR ) pertencem a rt_sched_class e certamente têm prioridades significativas (conforme exigido pelo POSIX):

static inline int rt_policy(int policy)
{
    return policy == SCHED_FIFO || policy == SCHED_RR;
}

Mas o ponto principal agora é agendar as prioridades classe , que são implementadas pelas seguintes estruturas const struct sched_class sendo vinculadas por seus .next ponteiros nesta ordem:

stop_sched_class
dl_sched_class
rt_sched_class
fair_sched_class
idle_sched_class

Esta lista vinculada é percorrida por ( kernel/sched/sched.h )

#ifdef CONFIG_SMP
#define sched_class_highest (&stop_sched_class)
#else
#define sched_class_highest (&dl_sched_class)
#endif
#define for_each_class(class) \
   for (class = sched_class_highest; class; class = class->next)

Como mencionado na citação acima, pick_next_task() in kernel/sched/core.c solicita a cada classe uma tarefa executável como esta:

again:
    for_each_class(class) {
            p = class->pick_next_task(rq, prev, rf);
            if (p) {
                    if (unlikely(p == RETRY_TASK))
                            goto again;
                    return p;
            }
    }

Tudo isso significa que as tarefas ociosas têm um valor de prioridade (algum padrão), mas nunca são consultadas durante as decisões de planejamento, porque são as únicas tarefas (fixadas em CPUs específicas) em idle_sched_class .

O texto acima deixa a questão do valor de prioridade alterado aberto, mas isso é principalmente de importância histórica até agora (as citações de código acima são do Linux 4.16).

    
por 09.04.2018 / 19:32