当前位置: 首页 > news >正文

Linux psi_task_change任务状态切换PSI计算

Linux psi_task_change任务状态切换PSI计算

psi_task_change是PSI(Pressure Stall Information)子系统的核心函数,负责在任务状态发生切换时更新per-CPU的stall追踪状态。任务状态的变化直接决定了cgroup当前是否处于IO、内存或CPU资源压力的stall状态,以及stall的严重程度(some vs full)。

函数核心逻辑

psi_task_change接收当前任务、新旧任务状态flags以及是否睡眠等参数,根据这些信息判断stall状态是否发生变化,并更新per-CPU的统计累积时间。

```c
void psi_task_change(struct task_struct *task, int clear, int set)
{
struct psi_group *group;
int cpu = task_cpu(task);
struct psi_group_cpu *groupc;
u64 now;
int state_mask;

if (!task->pid)
return;

group = task_psi_group(task);
if (!group)
return;

now = cpu_clock(cpu);
groupc = per_cpu_ptr(group->pcpu, cpu);

raw_spin_lock(&groupc->lock);

/*
* 计算新状态掩码,先清除旧flags再设置新flags,
* 排除TASK_NONIDLE等非PSI状态位
*/
state_mask = (groupc->state_mask & ~clear) | set;
state_mask &= PSI_TASK_STATE_MASK;

if (state_mask != groupc->state_mask) {
u64 delta;

/*
* 计算从上次状态改变到现在的stall持续时间,
* 累加到对应状态的times数组中
*/
delta = now - groupc->state_start;
if (delta > 0) {
int s;

for (s = 0; s < NR_PSI_STATES; s++) {
if (groupc->state_mask & (1 << s))
groupc->times[s][groupc->state_mask] += delta;
}
}

groupc->state_mask = state_mask;
groupc->state_start = now;

/*
* 如果新状态包含非空闲标志,需要设置
* nonidle_start时间戳,用于非idle时间跟踪
*/
if (state_mask & TASK_NONIDLE) {
if (!groupc->nonidle_start)
groupc->nonidle_start = now;
} else {
if (groupc->nonidle_start) {
delta = now - groupc->nonidle_start;
groupc->nonidle_time += delta;
groupc->nonidle_start = 0;
}
}
}

raw_spin_unlock(&groupc->lock);

/*
* 如果状态变化涉及可运行状态(running/runnable)的切换,
* 需要通知调度器更新psi_sched统计
*/
if (task->psi_flags & TSK_RUNNING) {
if (!(set & TSK_RUNNING)) {
psi_sched_account(task, true);
}
}
}
```

PSI状态的分类体系

PSI定义了三种资源类型(IO、Memory、CPU)和两种stall严重程度(Some、Full)。Some表示至少有一个任务处于stall状态但非全部,Full表示所有非idle任务都处于stall状态。

```c
enum psi_states {
PSI_IO_SOME,
PSI_IO_FULL,
PSI_MEM_SOME,
PSI_MEM_FULL,
PSI_CPU_SOME,
PSI_CPU_FULL,
NR_PSI_STATES,
};
```

psi_task_switch调度器入口

调度器在进程切换时调用psi_task_switch,该函数包装了psi_task_change并提供额外的上下文信息,是调度器与PSI子系统的主要接口。

```c
void psi_task_switch(struct task_struct *prev, struct task_struct *next,
bool sleep)
{
struct psi_group *group, *prev_group;

if (!static_branch_likely(&psi_disabled))
return;

if (prev->pid) {
prev_group = task_psi_group(prev);
if (prev->state == TASK_RUNNING) {
psi_task_change(prev, TSK_RUNNING, 0);
} else if (sleep) {
/*
* 任务进入睡眠状态,设置TSK_SLEEP标志,
* 此时该任务不再贡献活跃度
*/
psi_task_change(prev, TSK_RUNNING, TSK_SLEEP);
if (prev->in_iowait)
psi_task_change(prev, 0, TSK_IOWAIT);
}
}

if (next->pid) {
group = task_psi_group(next);
if (next->state == TASK_RUNNING) {
psi_task_change(next, 0, TSK_RUNNING);
}
}

/*
* 如果任务迁移到不同cgroup,需要同步
* per-CPU的psi_group_cpu统计
*/
if (prev_group != group && prev->pid && next->pid)
psi_group_change_sync(prev, prev_group, next, group, cpu);
}
```

memstall与iowait的处理

当任务因缺页等待IO时,内核标记PF_MEMSTALL标志。psi_memstall_enter和psi_memstall_leave通过psi_task_change切换TSK_MEMSTALL状态,使PSI能够追踪内存stall导致的任务等待。

```c
void psi_memstall_enter(unsigned long *flags)
{
struct task_struct *task = current;

if (!static_branch_likely(&psi_disabled))
return;

*flags = task->flags & PF_MEMSTALL;
task->flags |= PF_MEMSTALL;

if (!(*flags & PF_MEMSTALL))
psi_task_change(task, 0, TSK_MEMSTALL);
}

void psi_memstall_leave(unsigned long *flags)
{
struct task_struct *task = current;

if (!static_branch_likely(&psi_disabled))
return;

if (*flags & PF_MEMSTALL)
return;

task->flags &= ~PF_MEMSTALL;
psi_task_change(task, TSK_MEMSTALL, 0);
}
```

通过psi_task_change的精细状态追踪,PSI能够准确区分不同资源类型的stall,并为系统管理员提供精确的拥塞度量,这是cgroup v2资源隔离能力的关键组成部分。

http://www.jsqmd.com/news/1061153/

相关文章:

  • 南京视频号代运营服务机构综合实力排行 - 起跑123
  • Qwen3VL训练为何必须用TransformerEngine:显存、精度与多模态对齐硬约束
  • 安徽升本率优质中专推荐|合肥腾飞学校 2026 升学详情 - 辛云教育资讯
  • 2026 郑州管道疏通 + 水电综合避坑汇!马桶 / 下水道 / 暗漏真实测评榜单 - 星际AI
  • DeepSeek V4 Pro降价背后的混部池技术真相
  • 如何在Switch上安装wiliwili:第三方B站客户端的完整使用指南
  • 杭州卖黄金防套路指南,正规回收门店称重验金全程可视 - 奢侈品回收评测
  • 2026年河南中小企业AI搜索推广服务商选型指南:GEO优化如何助力本地获客 - 优质企业观察收录
  • 2026自动洗地机十大品牌推荐:谁才是真王者? - 工业清洁测评社
  • 医学影像AI新突破:SGMRI-VQA如何实现动态MRI的时空推理与视觉问答
  • 数据库分片(Sharding)实战:从分片键设计到在线扩容
  • 讲真的2026年北京工伤律师 这5位值得推荐 - 本地品牌推荐
  • pinout 用于查询 GPIO 引脚输出信息的实用程序。
  • 双层平面腔磁子-极化子激发研究与应用
  • MonkeyCode定制化训练:打造企业专属AI编程模型
  • 2026年开封AI搜索推广服务商怎么选?GEO优化与企业获客深度指南 - 优质企业观察收录
  • 2026主流AI Pro服务技术栈深度解析与工作流适配指南
  • AI与仿真融合:构建电力系统动态交互式教学新范式
  • 2026长沙黄金回收靠谱门店清单:六大主城区实地核验 正规资质一目了然 - 逸程
  • 互联网大厂面试中的 Java 技术考察:燕双非的搞笑应对
  • 2026年6月最新宝珀中国官方售后客服服务热线电话地址网点 - 亨得利官方服务中心
  • AI Agent如何从一行while循环进化出五十万行自治代码
  • 2026宜昌空调维修公司排名|本地口碑好的正规上门平台推荐 - 邻家快修
  • 电动车托运怎么最省钱?3招搞定 - 快递物流资讯
  • CircleCI + Argo CD 实现 Kubernetes GitOps 生产级交付
  • 魔兽世界开发终极指南:5分钟掌握wow_api完整使用技巧
  • Hermes Agent RL训练流水线:让AI助手学会聪明调用工具
  • 2025-2026年变频器风机供应商推荐:五大排名专业评测案例性价比高价格 - 品牌推荐
  • 面向国内开发者的AI服务协同工作流平台
  • 2026实力之选:汇聚南京高淳,为中小企业与制造业量身定制的产品研发管理软件供应商解析 - 企业推荐官【官方】