ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

【Note】《Linux 内核深度解析:基于 ARM64 架构的 Linux 4.x 内核》第二章:进程管理(Process Management)

【Note】《Linux 内核深度解析:基于 ARM64 架构的 Linux 4.x 内核》第二章:进程管理(Process Management)

《Linux 内核深度解析:基于 ARM64 架构的 Linux 4.x 内核》 第二章:进程管理(Process Management)

本章深入 Linux 内核的进程管理子系统,涵盖进程(Task)数据结构、创建与销毁、调度机制、上下文切换,以及与进程管理密切相关的信号、倒计时器与 CPU 热插拔等内容。


1. 进程与线程——Task 描述符

1.1 task_struct

在 Linux 内核中,每个执行单元(包括用户态进程与内核线程)都由一个 struct task_struct 描述,位于内核头文件 include/linux/sched.h。其核心字段包括:

  • 进程标识

    • pid:进程号
    • tgid:线程组 ID(针对线程模型)
  • 状态与优先级

    • state:TASK_RUNNING、TASK_INTERRUPTIBLE、TASK_UNINTERRUPTIBLE、TASK_STOPPED、TASK_TRACED 等
    • priostatic_prionormal_priort_priority:调度优先级
  • 上下文保存

    • thread:架构相关的寄存器集(struct thread_struct),包含通用寄存器、SP_ELx、PSTATE、SVE/FP 上下文等
  • 调度与运行队列

    • run_list:链接同一调度队列中的双向链表节点
    • on_rq:是否在运行队列
  • 进程树

    • parentchildrensibling:管理父子关系
  • 文件与内存

    • files:文件描述符表
    • mm:用户空间地址空间(struct mm_struct)或 NULL(内核线程)
1.2 thread_struct(架构相关)

arch/arm64/include/asm/thread_info.harch/arm64/include/asm/thread_struct.h 中,定义了 ARM64 特有的线程上下文:

  • 一组通用寄存器 x0x30
  • 程序计数器 pc
  • 进程状态寄存器 pstate
  • 堆栈指针 sp 对应各特权级别的 SP_EL0/SP_EL1
  • SVE/FP 扩展的上下文保存指针

在上下文切换时,内核通过 __switch_to() (定义在 arch/arm64/kernel/switch.S)精确地保存与恢复这些寄存器。


2. 进程创建与销毁

2.1 fork()clone()

系统调用接口位于 kernel/fork.c,核心入口为 sys_clone()do_fork()。进程创建流程:

  1. 参数解析

    • clone_flags 决定是否共享地址空间(CLONE_VM)、文件描述符(CLONE_FILES)、信号处理(CLONE_SIGHAND)等。
  2. 分配 task_struct

    • 调用 dup_task_struct(),复制父进程的 task_struct,并初始化必要字段,如清空 exit state。
  3. 分配与复制进程上下文

    • 若非线程(CLONE_VM 未设置),调用 copy_process_mm() 复制 mm_struct
    • 调用 copy_thread()arch/arm64/kernel/process.c)设置子进程内核栈与寄存器上下文,实现子进程在用户态返回 0。
  4. 文件、信号、cgroup、namespaces

    • 根据 clone_flags,共享或复制文件描述符表、信号处理结构、命名空间等。
  5. 进程就绪

    • 将子进程放入调度器运行队列(enqueue_task()),并返回子进程 PID 给父进程。
2.2 进程退出:exit()

当用户进程调用 exit() 或者内核线程调用 do_exit(),会走以下路径:

  1. 释放资源

    • 调用各类 release_ 函数,依次释放文件描述符、内存映射、信号处理、cgroup 关联、PID 等。
  2. 通知父进程

    • 将子进程状态设置为 TASK_DEAD,并唤醒在 wait() 上阻塞的父进程。
  3. 等待回收

    • 当父进程调用 waitpid(),内核调用 do_wait(),回收 task_struct 并最终销毁。

3. 调度器:完全公平调度(CFS)

Linux 默认调度器为 CFS(Completely Fair Scheduler),其目标是在可运行进程间分配“公平”的 CPU 时间。

3.1 红黑树与虚拟运行时间
  • 红黑树

    • CFS 维护一个按 vruntime(虚拟运行时间)排序的红黑树(struct rb_root_cached)。
    • 每当进程运行时,其 vruntime 按照权重(优先级)增长。
  • 选取下一个进程

    • 调度时,调用 pick_next_task_fair(),选择红黑树中最左侧(min_vruntime)的节点。
  • 负载平衡

    • 在 SMP 系统中,内核周期性地执行 load_balance(),将任务在各 CPU 之间迁移,以均衡负载。
3.2 时间片与 sched_latency
  • 调度周期(sched_latency_ns

    • 所有可运行进程在完整周期内至少能获得一次运行机会。
  • 最小/最大时间片

    • 每个任务的时间片由 sched_min_granularity_ns 与进程权重共同决定:

      time_slice = weight/task_sum_weight * sched_latency
      

4. 上下文切换(Context Switch)

上下文切换是调度器的核心支撑。在 ARM64 上,通过汇编与 C 混合实现:

  1. 保存当前上下文

    • __switch_to()arch/arm64/kernel/switch.S)中,先保存通用寄存器到当前进程的 thread_struct
  2. 更新 current

    • 将内核的 current 指针指向新进程的 task_struct
  3. 恢复新进程上下文

    • 从新进程的 thread_struct 恢复通用寄存器、SP、PSTATE 等;
    • 最后跳转到用户态或内核态继续执行。

性能优化要点:

  • 批量 TLBI:切换页面表时使用 tlbi 批指令清理旧映射。
  • Lazy FPU/SVE:仅在进程首次使用浮点/SVE 时才保存与恢复 FP/SVE 寄存器,减少上下文切换开销。

5. 信号与定时器

5.1 信号(Signals)
  • 信号队列

    • 每个 task_struct 包含 struct sigpending pendingstruct k_sigaction sigaction[NSIG]
  • 发送与处理

    • 内核调用 force_sig()kill_proc() 等发送信号;
    • do_signal() 中,根据进程状态(可中断/不可中断)决定是否立即中断系统调用并执行信号处理函数。
5.2 进程定时器

进程可创建多种定时器(alarm(timer_t)setitimer()timerfd等)。内核通过:

  • 系统范围时钟事件clockevents):驱动硬件定时器,分发 tick_sched_timer()
  • 高精度定时器(hrtimer):基于 HRTIMER API,支持纳秒级精度。

在调度与信号处理过程中,定时器触发会产生软中断(softirq),最终由 do_softirq() 调用相关处理函数,如 hrtimer_run()


6. CPU 热插拔与负载迁移

在 NUMA 或需热插拔 CPU 的系统中:

  1. 离线 CPU

    • 通过 /sys/devices/system/cpu/cpuX/online 控制,调用 cpu_disable(),迁移该 CPU 上的所有进程到其它在线 CPU。
  2. 上线 CPU

    • 调用 cpu_enable(),重新将 CPU 添加到调度器的 CPU 掩码,并参与后续负载均衡。

负载迁移依赖 sched_domains 架构,用于定义不同层级的负载平衡范围(同簇、同节点、跨节点)。


本章小结

本章详细剖析了 Linux 4.x 内核在 ARM64 平台上的进程管理子系统:

  1. task_structthread_struct 的关键字段及架构相关扩展;
  2. 进程创建(fork/clone销毁(exit 流程;
  3. CFS 调度器 的红黑树设计、时间片计算与负载均衡;
  4. 上下文切换 在 ARM64 上的实现细节与性能优化;
  5. 信号处理与定时器 机制;
  6. CPU 热插拔 与任务迁移策略。

理解这些机制,是后续深入 内存管理中断与设备驱动 以及 文件系统 等子系统的基础。

返回列表