LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

Linux PM:wakeup count、wakelock、autosleep

 在进行wakeup count、wakelock、autosleep之前,先参考《Linux电源管理(7)_Wakeup events framework (wowotech.net)》。

下面简单跟一下,wakeup count、wakelock、autosleep,及其使用方法。

1 PM初始化

PM子系统初始化:

pm_init
  pm_start_workqueue
  hibernate_image_size_init
  hibernate_reserved_size_init
  pm_states_init
  kobject_create_and_add--创建/sys/power目录。
  sys_create_groups--在/sys/power下创建一系列属性。
  pm_print_times_init
  pm_autosleep_init
    wakeup_source_register--创建名为autosleep的wakeup source,在autosleep关键路径时,阻止系统睡眠。
    alloc_ordered_workqueue--创建名为autosleep的有序workqueue,用于触发休眠动作。

PM suspend调试统计节点:

pm_debugfs_init
    debugfs_create_file--创建suspend_stats节点。

查看/sys/kernel/debug/suspend_stats:

success: 1
fail: 0
failed_freeze: 0
failed_prepare: 0
failed_suspend: 0
failed_suspend_late: 0
failed_suspend_noirq: 0
failed_resume: 0
failed_resume_early: 0
failed_resume_noirq: 0
failures:
  last_failed_dev:

  last_failed_errno:    0
                        0
  last_failed_step:

2 wakeup_count

关于wakeup_count参考《Linux电源管理(8)_Wakeup count功能 (wowotech.net)》。

获取wakeup_count:

cat  /sys/power/wakeup_count

写入wakeup_count:

echo <count> > /sys/power/wakeup_count

如果写入的count和实际的wakeup_count不一致,则返回错误。

如果一致,说明可以操作/sys/power/state进行低功耗流程。

3 wakelock

关于wakelock参考《Linux电源管理(9)_wakelocks (wowotech.net)》。

3.1 wakelock使用方法

获取一个wakelock:

echo <lockname> > /sys/power/wake_lock

获取一个带超时的wakelock,超时后wakelock自动消失。时间单位是ns:

echo <lockname> <duration> > /sys/power/wake_unlock

查看当前生效的wakelock:

cat /sys/power/wake_lock

释放一个wakelock:

echo <lockname> > /sys/power/wake_unlock

查看非活跃wakelock:

cat /sys/power/wake_unlock

3.2 wakelock代码流程

wakelock获取代码流程:

wake_lock_show
  pm_show_wakelocks--遍历wakelocks_tree,输出活跃的wakelock名称。
wake_lock_store
  pm_wake_lock
    ->解析wakelock名称,以及是否有超时参数。
    ->wakelock_lookup_add--查找并添加wakelock。
    ->__pm_wakeup_event/__pm_stay_awake--保持唤醒一段时间,或者一直保持唤醒。
    ->wakelocks_lru_most_recent--加入wakelocks_lru_list。

wakelock释放代码流程:

wake_unlock_show
  pm_show_wakelocks--遍历wakelocks_tree,输出非活跃wakelock名称。
wake_unlock_store
  pm_wake_unlock
    wakelock_lookup_add--查找,如果没找到不添加wakelock。
    __pm_relax--找到wakelock后则释放。
    wakelocks_lru_most_recent
    wakelocks_gc--当释放wakelock时,不是立即销毁相关数据。而是启动一个work,保留last_time之后的WL_GC_TIME_SEC秒时间,默认为300秒。
      schedule_work--调度wakelock_work。
        __wakelocks_gc
          wakeup_source_unregister--对于非active,并且在last_time超过WL_GC_TIME_SEC时间后开始回收资源。
          rb_erase--从wakelocks_tree移除节点。

4 autosleep

关于autosleep参考《Linux电源管理(10)_autosleep (wowotech.net)》。

4.1 autosleep使用方法

对/sys/power/autosleep写入,触发sleep:

echo mem > /sys/power/autosleep

可能的值包括:freeze、standby、mem、disk、off。

4.2 autosleep代码流程

autosleep流程如下:

autosleep_show
  pm_autosleep_state--获取autosleep_state值,根据状态从pm_states[]获取字符串。 autosleep_store decode_state--根据字符串匹配对应的state。 pm_autosleep_set_state     __pm_stay_awake--获取autosleep wakesource。
    __pm_relax--释放autosleep wakesource。
    pm_wakeup_autosleep_enabled
    queue_up_suspend_work
      queue_work--将suspend_work放到autosleep_wq上。
        try_to_suspend--据autosleep_state进入hibernate或者suspemd。
          hibernate
          pm_suspend
          queue_up_suspend_work--再次进行suspend队列。

 

posted on 2024-06-15 23:59  ArnoldLu  阅读(222)  评论(0编辑  收藏  举报

导航