【Linux】【Kernel】【arm】调度

【Linux】【Kernel】【调度】

  • 代码路径
  • 函数
    • schedule
    • 调度算法的触发点
  • Linux 内核调度相关代码解析

代码路径

  • kernel/sched/core.c
  • arch/arm64/kernel/entry.S

函数

schedule

/** 位于 kernel/sched/core.c **/
asmlinkage __visible void __sched schedule(void);
static void __sched notrace __schedule(bool preempt);

驱动调度器进入__schedule,有以下的几种方式:

  • 显式阻塞:互斥锁、信号量、等待队列等
  • 在中断和用户空间返回路径上检查 TIF_NEED_RESCHED 标志 (这个可以留意arch/arm64/kernel/entry.S中的el1_irq定义)
  • 如果内核是可抢占的(CONFIG_PREEMPT=y):
    • 在系统调用或异常上下文中,在下一次最外层的 preempt_enable() 处调用。(可能就是 wake_up()spin_unlock() 之后!)
    • 在中断上下文中,从中断处理程序返回到可抢占的上下文。
  • 如果内核不可抢占(CONFIG_PREEMPT 没有设置),则在下一次出现以下情况时调用:
    • cond_resched() 调用
    • 显式的 schedule() 调用
    • 从系统调用或异常返回到用户空间;
    • 从中断处理程序返回到用户空间;

必须在禁用抢占的条件下进行__schedule

调度算法的触发点

/** kernel/sched/core.c **/
void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags);

Linux 内核调度相关代码解析

  1. deactivate_task(struct rq *rq, struct task_struct *p, int flags)
    该函数用于将任务标记为非活跃状态并执行相应的操作。

  2. ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags, struct rq_flags *rf)
    该函数用于将任务标记为可运行状态并执行唤醒-抢占操作。

  3. wq_worker_sleeping(struct task_struct *task)
    该函数用于处理工作线程进入睡眠状态的情况。

  4. try_to_wake_up_local(struct task_struct *p, struct rq_flags *rf)
    该函数尝试唤醒本地任务,并在运行队列锁定状态下执行。

  5. enqueue_task(struct rq *rq, struct task_struct *p, int flags)
    该函数用于将任务加入运行队列,并执行相应的操作。

你可能感兴趣的:(linux,arm开发,算法)