S3 问题根因分析技术文档

S3 问题根因分析技术文档

问题背景

  • x86 1070 5.10
  • 联想昭阳k4e-iml 待机自动唤醒

首先我们看一下日志

我们可以看到在准备Disabling non-boot CPUs 的时候检测到wakeup事件了(wake up pending),abort CPU freeze

一般这个wakeup事件产生可能是某些设备下电的时候出现异常,或者此时外部设备来了一个中断,打断S3的操作导致S3停止

S3 待机流程

我们先来了解一下S3的流程是怎么样的

如上图所示,这是S3待机过程的流程图,简单介绍一下:

  • state_store:处理系统进入不同的电源状态
  • pm_suspend:suspend入口
  • suspend_prepare:suspend前的一些准备工作
  • suspend_freeze_processes:冻结用户进程以及内核线程
  • suspend_devices_and_enter:开始进行挂起设备
  • suspend_enter:关闭设备中断,关闭辅助cpu,检查irq事件,CPU进入suspend

处理问题

问题是它唤醒了,在知道了S3的流程以后,他在哪里检测唤醒事件呢?pm_wakeup_pending,没错就是这里,我们查看此部分代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool pm_wakeup_pending(void)
{
unsigned long flags;
bool ret = false;

raw_spin_lock_irqsave(&events_lock, flags);
if (events_check_enabled) {
unsigned int cnt, inpr;

split_counters(&cnt, &inpr);
ret = (cnt != saved_count || inpr > 0);
events_check_enabled = !ret;
}
raw_spin_unlock_irqrestore(&events_lock, flags);

if (ret) {
pm_pr_dbg("Wakeup pending, aborting suspend\n");
pm_print_active_wakeup_sources();
}

return ret || atomic_read(&pm_abort_suspend) > 0;
}

发现他在检测到中断事件的时候就会return false,暂停S3的操作

具体检测irq函数为pm_system_irq_wakeup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void pm_system_irq_wakeup(unsigned int irq_number)
{
unsigned long flags;

raw_spin_lock_irqsave(&wakeup_irq_lock, flags);

if (wakeup_irq[0] == 0)
wakeup_irq[0] = irq_number;
else if (wakeup_irq[1] == 0)
wakeup_irq[1] = irq_number;
else
irq_number = 0;

raw_spin_unlock_irqrestore(&wakeup_irq_lock, flags);

if (irq_number)
pm_system_wakeup();
}

在这个函数里面我们可以添加printk打印出中断号,或者可以使用bpftrace工具进行打印,kprobe:pm_system_irq_wakeup

此时发现中断号为122,接下来通过cat /proc/interrupts 查看这个中断相应的中断处理程序

此中断所挂载的相关中断处理程序是aerdrv和pcie-dpc,这2个中断处理程序主要负责处理pcie上面的错误信号的

通过lspci -tv查看到这个pcie总线上挂载了一张amd的显卡,此时基本可以判断问题出在显卡驱动上面

AER和DPC

  • AER:是一种用于检测和报告PCIe设备中发生的错误的机制。它允许PCIe设备检测到并报告各种类型的错误,如非致命的、可恢复的以及严重的错误。AER在PCIe设备上实现了一组寄存器和相应的错误通知机制,可以通过读取这些寄存器来获取关于错误的信息。使用AER,系统能够更好地监控和处理PCIe设备的错误情况,以提高数据完整性和可靠性。
  • DPC:是一种用于处理PCIe链路中错误情况的机制。当PCIe链路上的一个设备发送错误信号时,DPC机制允许系统针对该错误进行处理,以避免错误的传播和影响其他设备。具体而言,DPC机制会隔离出故障设备,从而限制错误的影响范围,确保其他设备继续正常工作。

DPC机制依赖于AER提供的错误信息来进行错误处理

由于后期任务较多,该问题当时并未深究amdgpu驱动为何报错,不过知道了中断处理程序上报的错误,最后采用pcie_ports=compat进行规避。

1
2
3
4
5
6
7
8
9
pcie_ports=	[PCIE] PCIe port services handling:
native Use native PCIe services (PME, AER, DPC, PCIe hotplug)
even if the platform doesn't give the OS permission to
use them. This may cause conflicts if the platform
also tries to use these services.
dpc-native Use native PCIe service for DPC only. May
cause conflicts if firmware uses AER or DPC.
compat Disable native PCIe services (PME, AER, DPC, PCIe
hotplug).

compat参数用于禁用原生的 PCIe 服务,包括 PME、AER、DPC 和 PCIe 热插拔功能,忽略该错误进行规避。


S3 问题根因分析技术文档
https://tomwithkernel.github.io/pm/S3问题分析/
作者
Tom
发布于
2024年7月10日
更新于
2024年11月11日
许可协议