当前位置:首页>Linux>Linux 内核功耗子系统(十三):系统睡眠之DPM框架梳理

Linux 内核功耗子系统(十三):系统睡眠之DPM框架梳理

  • 2026-07-04 21:38:22
Linux 内核功耗子系统(十三):系统睡眠之DPM框架梳理

参考资料:Linux kernel 源码 drivers/base/power/main.cinclude/linux/pm.hinclude/linux/pm_runtime.h。主题:DPM(Device Power Management)框架如何在整机休眠时按依赖顺序遍历所有设备。

全景介绍

第七篇讲了 Runtime PM:单个设备 idle 了可以自己 suspend,忙了再 resume,和别的设备没关系,中断和调度器都正常工作。

但 system sleep 不一样。用户按下电源键或合上盖子,内核要把所有设备按正确顺序逐个 suspend,然后才能调平台固件进入深度低功耗。这个"按正确顺序遍历所有设备"的工作,由 DPM(Device Power Management) 框架完成。

DPM 是 PM Core 中管理设备 suspend/resume 遍历顺序的核心机制。它解决的问题很具体:给定一棵设备树,怎么保证父设备不比子设备先关掉?怎么在每个阶段(prepare → suspend → suspend_late → suspend_noirq)正确遍历?resume 时怎么反向恢复?

这不是 Runtime PM 能做的事。Runtime PM 关心的是"一个设备什么时候该 suspend",DPM 关心的是"所有设备按什么顺序 suspend"。两者通过 struct dev_pm_ops 共享同一套回调结构体,但遍历逻辑完全不同。

实际情况

DPM 的实现里,有两个设计决策直接影响驱动行为。

第一,遍历顺序是链表,不是树。DPM 维护全局链表 dpm_list,设备在 device_add() 时按拓扑序插入。suspend 时从链表尾部反向遍历,先 suspend 子设备再 suspend 父设备;resume 时正向遍历,先 resume 父设备再 resume 子设备。

第二,回调查找有优先级。设备的 system sleep 回调不只来自驱动,DPM 按 pm_domain > type > class > bus > driver 的优先级查找,找到第一个非 NULL 就调用。SoC 厂商可以在 pm_domain 层面统一处理所有设备的 suspend/resume,驱动自己的回调不会被调用。

抽象对象

dpm_list:全局设备链表



1
2
3
4
5
6
7

// drivers/base/power/main.c
static LIST_HEAD(dpm_list);           // 所有待 suspend 的设备
static LIST_HEAD(dpm_prepared_list);  // 已完成 prepare
static LIST_HEAD(dpm_suspended_list); // 已完成 suspend
static LIST_HEAD(dpm_late_early_list); // 已完成 suspend_late
static LIST_HEAD(dpm_noirq_list);    // 已完成 suspend_noirq


设备在每个阶段完成后从当前链表移到下一条链表。这是 DPM 的核心数据结构——五条链表追踪设备当前所处的阶段。

设备在 device_add() 时插入 dpm_list,顺序由设备树拓扑决定。dpm_suspend() 遍历 dpm_prepared_list,对每个设备调用 suspend 回调,成功后移到 dpm_suspended_list。以此类推。

dev_pm_ops:回调结构体



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

// include/linux/pm.h
struct dev_pm_ops {
    int (*prepare)(struct device *dev);
    void (*complete)(struct device *dev);
    int (*suspend)(struct device *dev);
    int (*resume)(struct device *dev);
    int (*suspend_late)(struct device *dev);
    int (*resume_early)(struct device *dev);
    int (*suspend_noirq)(struct device *dev);
    int (*resume_noirq)(struct device *dev);
    int (*freeze)(struct device *dev);
    int (*thaw)(struct device *dev);
    int (*poweroff)(struct device *dev);
    int (*restore)(struct device *dev);
    int (*runtime_suspend)(struct device *dev);
    int (*runtime_resume)(struct device *dev);
    int (*runtime_idle)(struct device *dev);
};


看着多,实际分四组:

  • • suspend/resume 组:用于 mem(suspend-to-RAM)路径
  • • freeze/thaw 组:用于 freeze(s2idle)路径
  • • poweroff/restore 组:用于 hibernation 路径
  • • runtime 组:Runtime PM 路径

每组又分三个子阶段:suspend → suspend_late → suspend_noirq。驱动通常用 SET_SYSTEM_SLEEP_PM_OPS 宏来注册 suspend/resume 对。

dpm_suspend:遍历函数



1
2
3
4
5
6
7
8
9
10
11

// drivers/base/power/main.c
void dpm_suspend(pm_message_t state)
{
struct device *dev;
    list_for_each_entry_reverse(dev, &dpm_prepared_list, power.entry) {
        error = device_suspend(dev);
        if (!error)
            list_move(&dev->power.entry, &dpm_suspended_list);
    }
}


dpm_suspend() 用 list_for_each_entry_reverse 从链表尾部开始遍历——因为 dpm_prepared_list 的顺序是父在前、子在后,反向遍历就是先 suspend 子设备再 suspend 父设备。

模型

多阶段遍历模型

DPM 把 suspend/resume 分成五个阶段,每个阶段遍历同一条链表,成功后把设备移到下一条链表。这个设计的好处是:每个阶段的上下文限制不同(中断是否屏蔽、是否可睡眠),驱动可以根据需要选择在哪个阶段做操作。

suspend 方向(从叶子到根):



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

dpm_prepare():
    遍历 dpm_list(正向,父在前子在后)
    对每个设备调用 dev->pm_domain->ops.prepare()
    成功 → list_move_tail(dev, &dpm_prepared_list)

dpm_suspend():
    遍历 dpm_prepared_list(反向,先遇到子设备)
    对每个设备调用 .suspend()
    成功 → list_move(dev, &dpm_suspended_list)

dpm_suspend_late():
    遍历 dpm_suspended_list(反向)
    对每个设备调用 .suspend_late()
    成功 → list_move(dev, &dpm_late_early_list)

dpm_suspend_noirq():
    遍历 dpm_late_early_list(反向)
    对每个设备调用 .suspend_noirq()
    成功 → list_move(dev, &dpm_noirq_list)


resume 方向(从根到叶子),每步正向遍历,回调反向调用:



1
2
3
4
5

dpm_resume_noirq():  dpm_noirq_list 

→ .resume_noirq() 

→ 移回 dpm_late_early_list

dpm_resume_early():  dpm_late_early_list 

→ .resume_early() 

→ 移回 dpm_suspended_list

dpm_resume():        dpm_suspended_list 

→ .resume()

 → 移回 dpm_prepared_list

dpm_complete():      dpm_prepared_list 

→ .complete() 

→ 移回 dpm_list


上图展示了五条链表和设备在各阶段间的迁移。suspend 方向水平箭头表示从左到右依次迁移;resume 方向折线箭头表示反向迁移。

依赖顺序保证

设备在 dpm_list 中的顺序在 device_add() 时确定。如果设备 B 的 parent 是 A,那么 A 在 B 前面。DPM 的 suspend 遍历用 list_for_each_entry_reverse 从尾部开始,所以先遇到子设备 B,suspend B 之后才 suspend A。

resume 时用 list_for_each_entry 正向遍历,先遇到父设备 A,先 resume A,再 resume B。

这保证了:suspend 时子设备先关、父设备后关;resume 时父设备先开、子设备后开。子设备在 suspend 回调里访问父设备提供的资源(时钟、电源、总线)时,父设备一定还活着。

回调查找优先级

DPM 调用回调时,不直接用 dev->driver->pm,而是按优先级查找:



1
2
3
4
5
6
7
8
9
10
11

// drivers/base/power/main.c
static int dev_pm_get_callbacks(struct device *dev, ...)
{
    if (dev->pm_domain) return 1;  // 用 pm_domain->ops
    if (dev->type && dev->type->pm) return 2;
    if (dev->class && dev->class->pm) return 3;
    if (dev->bus && dev->bus->pm) return 4;
    if (dev->driver && dev->driver->pm) return 5;
    return 0;
}


优先级:pm_domain > type > class > bus > driver。找到第一个非 NULL 就调用。这意味着:

  • • 如果 SoC 厂商在 pm_domain 层面定义了统一的 suspend/resume,驱动自己的回调不会被调用
  • • 如果总线层(如 PCI、I2C)定义了通用的 suspend/resume,驱动可以不实现——总线层的回调会覆盖
  • • 驱动自己实现的 
.suspend()/.resume只有在上面四层都没有回调时才会被调用

上图展示了这个五级查找链:从 dev->pm_domain->ops

开始,逐级向下查找,找到第一个非 NULL 就停止。

数据流

从用户态写 /sys/power/state 到所有设备 suspend 完,再到唤醒恢复,完整的调用链如下。上图展示了这条调用链的全景——suspend 路径从上往下走,resume 路径从下往上走。

suspend 路径



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

enter_state(state)
  │
  ├─ 1. suspend_prepare(state)
  │    ├─ pm_prepare_console()           // 切换到安全控制台
  │    ├─ pm_notifier_call_chain(PM_SUSPEND_PREPARE)
  │    │    // 通知所有注册了 PM notifier 的模块:"准备 suspend 了"
  │    │    // 内核子系统(如 workqueue、RCU)在这里做准备工作
  │    ├─ suspend_freeze_processes()      // 冻结所有用户态进程
  │    │    // 发送 fake signal,等待所有进程进入 frozen 状态
  │    │    // 这一步之后,用户态不会再有新的 I/O 请求
  │    └─ dpm_prepare(state)             // 遍历 dpm_list,调用 prepare
  │         └─ list_for_each_entry(dev, &dpm_list)
  │              → device_prepare(dev)   // 查找回调并调用 .prepare()
  │              → 成功: list_move_tail(dev, &dpm_prepared_list)
  │              → 失败: 跳过,继续下一个设备
  │
  ├─ 2. suspend_devices_and_enter(state)
  │    ├─ suspend_device_irqs()          // 屏蔽所有非 wakeup IRQ
  │    │    // 这一步之后,只有标记了 IRQF_NO_SUSPEND 的 IRQ 还能触发
  │    │    // 设备驱动的中断处理函数不会再被调用
  │    │
  │    ├─ dpm_suspend(state)             // 遍历 dpm_prepared_list(反向)
  │    │    └─ list_for_each_entry_reverse(dev, &dpm_prepared_list)
  │    │         → device_suspend(dev)   // 查找回调并调用 .suspend()
  │    │         → 成功: list_move(dev, &dpm_suspended_list)
  │    │         → 失败: 中止 suspend,开始 resume 恢复
  │    │
  │    ├─ dpm_suspend_late(state)        // 遍历 dpm_suspended_list(反向)
  │    │    └─ 此时 IRQ 已屏蔽,回调不能做 I2C/SPI 等需要中断的操作
  │    │    └→ .suspend_late() 通常用于关闭中断相关的资源
  │    │
  │    ├─ dpm_suspend_noirq(state)       // 遍历 dpm_late_early_list(反向)
  │    │    └─ 此时仅 NMI 还能触发,回调只能做最简单的硬件状态确认
  │    │
  │    ├─ disable_nonboot_cpus()         // 关闭除 boot CPU 以外的所有 CPU
  │    │    // 减少功耗,确保只有 boot CPU 在运行 suspend 代码
  │    │
  │    ├─ syscore_suspend()              // 系统核心模块的 suspend
  │    │    // 中断控制器、时钟源、timer 等核心模块在这里保存状态
  │    │
  │    └─ suspend_ops->enter()           // 调用平台固件的 enter 接口
  │         // ARM: PSCI firmware 调用,CPU 进入深度低功耗
  │         // x86: ACPI _PTS + 写 PM1a_CNT 寄存器
  │         // 到这里,CPU 已经停止执行,等待唤醒事件


resume 路径

唤醒事件(GPIO 中断、RTC alarm、Power 键等)触发 CPU 从低功耗状态恢复:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

│    // --- CPU 被唤醒事件唤醒,从这里开始 resume ---
  │
  │    ├─ suspend_ops->wake()            // 平台固件的 wake 接口
  │    ├─ syscore_resume()               // 恢复中断控制器、时钟源、timer
  │    ├─ enable_nonboot_cpus()          // 重新启动其他 CPU
  │    │
  │    ├─ dpm_resume_noirq(state)        // 遍历 dpm_noirq_list(正向)
  │    │    └→ .resume_noirq() 恢复硬件状态,为后续 resume 做准备
  │    │
  │    ├─ dpm_resume_early(state)        // 遍历 dpm_late_early_list(正向)
  │    │    └→ .resume_early() 恢复中断相关的资源
  │    │
  │    ├─ resume_device_irqs()           // 重新启用设备 IRQ
  │    │    // 这一步之后,设备中断处理函数可以正常触发
  │    │
  │    ├─ dpm_resume(state)              // 遍历 dpm_suspended_list(正向)
  │    │    └→ .resume() 恢复设备功能,重新初始化硬件
  │    │    └→ 此时 IRQ 已启用,可以做 I2C/SPI 等操作
  │    │
  │    └─ dpm_complete(state)            // 遍历 dpm_prepared_list(正向)
  │         └→ .complete() 清理 prepare 阶段的标记
  │         └→ list_move_tail(dev, &dpm_list)  // 移回原始链表
  │
  └─ 3. suspend_finish(state)
       ├─ thaw_processes()               // 解冻用户态进程
       └─ pm_notifier_call_chain(PM_POST_SUSPEND)
            // 通知所有模块:"suspend/resume 结束了"


关键设计点

这条调用链有几个值得注意的设计:

运行

回调阶段与上下文限制

DPM 的五个阶段,每个阶段的中断状态和可睡眠性不同。驱动必须根据回调里需要做什么操作,选择合适的阶段:

阶段
中断状态
可睡眠
可做 I/O
典型用途
prepare
正常
可以
可以
检查设备状态,失败可回滚
suspend
正常
可以
可以
关闭设备功能,I2C/SPI 写寄存器
suspend_late
IRQ 已屏蔽
不可
简单 MMIO
关闭中断相关的资源
suspend_noirq
仅 NMI
不可
极受限
硬件状态最终确认
suspend_ops->enter


不可
不可
固件接管
    • I2C 设备驱动:需要通过 I2C 总线写寄存器 → 只能在 suspend 阶段(I2C传输依赖中断)
    1. 1. 失败回滚:任何阶段的 suspend 失败,都会触发 resume 路径恢复已 suspend 的设备。不会留下"半 suspend"的状态。
    2. 2. IRQ 屏蔽时机suspend_device_irqs() 在 dpm_suspend() 之前调用。这意味着 dpm_suspend() 阶段设备 IRQ 已经被屏蔽了——但 suspend 回调本身还可以做 I2C/SPI 操作(因为这些操作不依赖设备 IRQ,而是由 CPU 主动发起)。
    3. 3. CPU 下线顺序disable_nonboot_cpus() 在所有设备 suspend 完之后才调用。这保证了多核系统上,所有 CPU 都参与了设备 suspend 的工作。
    4. 4. dpm_complete 的角色dpm_complete() 是 prepare 的逆操作。prepare 阶段检查设备是否可以 suspend,complete 阶段清理这些检查标记,把设备移回 dpm_list,为下一次 suspend 做准备。
  • • GPIO 中断控制器:需要关闭中断资源 → 在 suspend_late 阶段做(此时 IRQ 已屏蔽,不会出现"关到一半来了个新中断"的情况)
  • • PCI 设备:需要写 PCI 配置空间 → 在 suspend 阶段做(MMIO 可以在任何阶段,但 PCI config space 访问可能依赖中断)
  • • 平台时钟驱动:需要关闭 PLL → 在 suspend_noirq 阶段做(确保所有设备都 suspend 完了,没人再用这个时钟)
  • SET_SYSTEM_SLEEP_PM_OPS 宏

    内核提供了宏来简化驱动注册,避免直接填充 dev_pm_ops 结构体:



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    // 最常用:suspend/resume 对
    #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
        .suspend = suspend_fn, .resume = resume_fn

    // 如果需要在 late 阶段做操作(IRQ 屏蔽后)
    #define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
        .suspend_late = suspend_fn, .resume_early = resume_fn

    // 如果需要在 noirq 阶段做操作
    #define SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
        .suspend_noirq = suspend_fn, .resume_noirq = resume_fn


    大多数驱动只用 SET_SYSTEM_SLEEP_PM_OPS。只有需要在 IRQ 屏蔽后做操作的驱动才用 SET_LATE_SYSTEM_SLEEP_PM_OPS。使用示例:



    1
    2
    3
    4

    static conststruct dev_pm_ops my_device_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(my_device_suspend, my_device_resume)
    };


    DPM 与 Runtime PM 的交互

    DPM 和 Runtime PM 通过 pm_runtime_force_suspend() / pm_runtime_force_resume() 交互。驱动在 system sleep 的 suspend 回调里调用 pm_runtime_force_suspend(),确保设备不是 runtime active 状态:



    1
    2
    3
    4
    5
    6
    7
    8

    static int my_device_suspend(struct device *dev)
    {
        // 先确保设备不是 runtime active
        pm_runtime_force_suspend(dev);
        // 然后做设备特定的 suspend 操作
        return 0;
    }


    这避免了"设备 runtime active 时被 system sleep 强制关掉"导致的状态不一致。如果设备在 system sleep 时还是 runtime active(比如用户态一直在用),pm_runtime_force_suspend() 会先把它 suspend 掉,再让 system sleep 继续。

    DPM 的错误处理

    DPM 对 suspend 失败的处理是"立即 resume 恢复已 suspend 的设备":



    1
    2
    3
    4
    5

    dpm_suspend() 失败:
      1. 记录失败设备的错误码
      2. 调用 dpm_resume_for_each_dev() 恢复已 suspend 的设备
      3. 返回错误码,enter_state() 会调用 suspend_finish() 清理


    这意味着驱动的 suspend 回调返回非零值时,DPM 会自动 resume 所有已经 suspend 的设备。驱动不需要自己做回滚——DPM 框架会处理。

    上图展示了完整的 suspend/resume 调用链:suspend 路径从上到下(prepare → suspend → suspend_late → suspend_noirq → enter),resume 路径从下到上(wake → resume_noirq → resume_early → resume → complete)。左侧是 suspend 阶段,右侧是 resume 阶段,中间是各阶段的链表迁移方向。

    I2C suspend 超时

    一个 I2C 设备驱动在 suspend 回调里通过 I2C 写寄存器让设备进入低功耗模式。但 suspend 时报错 "i2c transfer timeout"。

    从 ftrace 日志看到 DPM 遍历顺序:



    1
    2
    3

    dpm_suspend: i2c-adapter (i2c-0) → suspend OK
    dpm_suspend: my-device (i2c-0:0x48) → suspend FAIL (i2c timeout)


    问题:i2c-0 的 suspend 回调把 I2C 控制器的时钟关了,但 my-device 的 suspend 回调还在执行。因为 dpm_suspend() 用 list_for_each_entry_reverse 遍历,i2c-0 先被 suspend,然后才轮到 my-device——但此时 I2C 控制器已经关了。

    修复:i2c-0 应该用 suspend_late 而不是 suspend,确保在所有 I2C 设备 suspend 完后才关控制器时钟。或者用 SET_LATE_SYSTEM_SLEEP_PM_OPS 宏注册 suspend_late 回调。

    pm_domain 统一 suspend

    SoC 平台有 20 多个设备,每个设备的 suspend 都需要写同一个 power domain 寄存器。如果每个驱动都自己写,代码重复且容易出错。

    解决方案:在 pm_domain 层面实现统一的 suspend/resume:



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    static int my_soc_pd_suspend(struct device *dev)
    {
        return my_soc_pd_set_low_power(dev->pm_domain);
    }

    staticstruct dev_pm_domain my_soc_pd_domain = {
        .ops = {
            .suspend = my_soc_pd_suspend,
            .resume = my_soc_pd_resume,
        },
    };


    所有设备的 dev->pm_domain 指向同一个 domain。DPM 回调查找时,pm_domain->ops 优先级最高,驱动自己的 suspend 回调不会被调用。这实现了"SoC 厂商统一处理,驱动无需关心"的效果。

    总结

    DPM 是 System Sleep 的"骨架"——它负责在整机休眠时按依赖顺序遍历所有设备,调用每个阶段的回调。

    核心机制:

    1. 1. 五条链表dpm_list → dpm_prepared_list → dpm_suspended_list → dpm_late_early_list → dpm_noirq_list,设备在每阶段完成后迁移。
    2. 2. 反向遍历dpm_suspend() 用 list_for_each_entry_reverse 从链表尾部开始,先 suspend 子设备再 suspend 父设备。
    3. 3. 回调查找优先级pm_domain > type > class > bus > driver,SoC 厂商可以在 pm_domain 层面统一处理。
    4. 4. 与 Runtime PM 共享:通过 struct dev_pm_ops 共享同一套回调结构体,但遍历逻辑完全不同。
    5. 5. 错误回滚:任何阶段 suspend 失败,DPM 自动 resume 已 suspend 的设备。

    DPM 解决的是"所有设备按什么顺序 suspend",Runtime PM 解决的是"一个设备什么时候该 suspend"。理解了 DPM,System Sleep 设备遍历逻辑就清楚了。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-05 00:23:48 HTTP/2.0 GET : https://f.mffb.com.cn/a/503450.html
  2. 运行时间 : 0.095799s [ 吞吐率:10.44req/s ] 内存消耗:4,519.02kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=8cc44284f0c2124ea4fdfc24bae312ed
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000746s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000785s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000305s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000264s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000608s ]
  6. SELECT * FROM `set` [ RunTime:0.000270s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000691s ]
  8. SELECT * FROM `article` WHERE `id` = 503450 LIMIT 1 [ RunTime:0.001368s ]
  9. UPDATE `article` SET `lasttime` = 1783182228 WHERE `id` = 503450 [ RunTime:0.014603s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000521s ]
  11. SELECT * FROM `article` WHERE `id` < 503450 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000535s ]
  12. SELECT * FROM `article` WHERE `id` > 503450 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000362s ]
  13. SELECT * FROM `article` WHERE `id` < 503450 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001028s ]
  14. SELECT * FROM `article` WHERE `id` < 503450 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001386s ]
  15. SELECT * FROM `article` WHERE `id` < 503450 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001293s ]
0.097549s