调度器30—task_struct相关成员说明

一、p->wake_cpu

1. p->wake_cpu 的赋值位置

//kernel/sched/sched.h
static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
{
    set_task_rq(p, cpu);
#ifdef CONFIG_SMP
    /*
     * After ->cpu is set up to a new value, task_rq_lock(p, ...) can be
     * successfully executed on another CPU. We must ensure that updates of
     * per-task data have been completed by this moment.
     */
    smp_wmb();
#ifdef CONFIG_THREAD_INFO_IN_TASK
    WRITE_ONCE(p->cpu, cpu);
#else
    WRITE_ONCE(task_thread_info(p)->cpu, cpu);
#endif
    p->wake_cpu = cpu; //这里赋值
#endif
}

2. p->wake_cpu 的赋值流程:

set_task_cpu(p, new_cpu) //kernel/sched/core.c
    __set_task_cpu(p, new_cpu);

显式调用set_task_cpu,p->wake_cpu 赋值为指定的cpu.

sched_fork //kernel/sched/core.c
    __set_task_cpu(p, smp_processor_id());

对于fork的新任务,p->wake_cpu 赋值为当前正在执行的cpu.

wake_up_new_task //kernel/sched/core.c
    __set_task_cpu(p, select_task_rq(p, task_cpu(p), SD_BALANCE_FORK, 0));

对于唤醒的任务,p->wake_cpu 赋值为为其选择的cpu.

    sched_init //kernel/sched/core.c 传参current, smp_processor_id(),也就是将当前线程认为是idle线程,当前cpu当做wake_cpu
idle_init //将per-cpu的idle线程的wake_cpu赋值为自己的cpu
    fork_idle(cpu) //fork.c
        init_idle(idle, cpu) //kernel/sched/core.c
            __set_task_cpu(idle, cpu);

对于idle线程初始化的时候,其 p->wake_cpu 赋值为为其选择的cpu.

migration_cpu_stop //core.c 若 p->on_rq != TASK_ON_RQ_QUEUED 时赋值
    p->wake_cpu = arg->dest_cpu;
__migrate_swap_task //core.c 若 p->on_rq != TASK_ON_RQ_QUEUED 时赋值
    p->wake_cpu = cpu;

TODO: 待叙

3. p->wake_cpu 的使用:

try_to_wake_up
    cpu = select_task_rq(p, p->wake_cpu, SD_BALANCE_WAKE, wake_flags);

在选核时 p->wake_cpu 作为 prev_cpu 来使用,也就是当做任务之前运行的CPU。

4. 总结
p->wake_cpu 赋值为给任务选定的CPU,在唤醒任务时作为任务之前运行的CPU使用。

 

上一篇:三种基本结构


下一篇:第九章 压缩和存储 【开启Map输出阶段压缩、开启Reduce输出阶段压缩】