关于
支持的内核版本
用法
可用的API
如何贡献
执照
我们的团队
Kprofiles 是一个简单的 Linux 内核模块,可用于调节内核内活动,例如通常不暴露给用户空间的提升。 Kprofiles 以面向配置文件的方式运行,因此,它有四种配置文件模式: Disabled
、 Battery
、 Balanced
和Performance
。每种模式都分配有一个模式编号。开发人员可以在条件下使用 Kprofiles API 函数来限制或启用某种配置模式下的内核任务(例如查看使用部分) 。用户空间可以通过调整/sys/kernel/kprofiles/kp_mode
中的模式编号与 Kprofile 交互。下表显示了与配置文件模式相对应的模式编号。
配置文件模式 | 模式编号 |
---|---|
禁用(默认) | 0 |
电池 | 1 |
均衡 | 2 |
表现 | 3 |
此外,Kprofiles 提供自动配置文件更改器 (auto Kprofiles),它使用FB notifier
、 MSM DRM notifier
或MI DRM notifier
在设备屏幕关闭时强制执行电池配置文件模式,并在设备唤醒时切换回之前的活动模式。用户可以通过更改/sys/module/kprofiles/parameters/auto_kp
中的 bool 值在运行时禁用或启用此功能,而无需重新编译内核
Kprofiles 另外还具有用于切换配置文件以响应任何内核事件的 API 函数。有关更多信息,请参阅可用 API 表
Kprofiles 在 Linux 3.10+ 内核上进行了测试
如果您使用git
,强烈建议使用git subtree
或git submodule
。
将此存储库添加到drivers/misc/kprofiles
修改drivers/misc/Kconfig
菜单“其他设备” 源“drivers/misc/genwqe/Kconfig”+源“drivers/misc/kprofiles/Kconfig”源“drivers/misc/echo/Kconfig” 结束菜单
修改drivers/misc/Makefile
obj-$(CONFIG_GENWQE) += genwqe/+obj-$(CONFIG_KPROFILES) += kprofiles/obj-$(CONFIG_ECHO) += echo/
使用 extern 在所需文件中定义您需要的 api 函数,Kprofiles 可以在各种地方使用,例如 boosting 驱动程序,下面是在 kernel/fork.c 中使用 kprofiles 来使用 kp_active_mode 在 zygote forking 期间控制 cpu 和 ddr boosts 的示例() API。
+ #ifdef CONFIG_KPROFILES+ extern int kp_active_mode(void);+ #endif/* * 好的,这是主要的 fork 例程。 * * 它复制该过程,如果成功则启动 * 它并等待它完成使用虚拟机(如果需要)。 */ 长 _do_fork(无符号长克隆标志, 无符号长堆栈_开始, 无符号长堆栈大小, int __user *parent_tidptr, int __user *child_tidptr, 无符号长 tls) { 结构任务结构*p; int 跟踪 = 0; 长nr; /* 当用户空间启动应用程序时,将 CPU 提升到最大值 50 毫秒 */ if (task_is_zygote(current)) {- cpu_input_boost_kick_max(50);- devfreq_boost_kick_max(DEVFREQ_MSM_LLCCBW, 50);- devfreq_boost_kick_max(DEVFREQ_MSM_CPUBW, 50);+ #ifdef CONFIG_KPROFILES+ /*+ * 提升 CPU 和如果性能模式处于活动状态,则 DDR 60 毫秒。+ * 如果默认模式处于活动状态,则将 CPU 和 DDR 提升 50 毫秒以保留默认行为。+ * 如果启用平衡配置文件,则将 CPU 和 DDR 提升 25 毫秒+ * 如果省电配置文件,则不要提升 CPU 和 DDR已启用+ */+ switch (kp_active_mode()) {+ case 0:+ cpu_input_boost_kick_max(60);+ devfreq_boost_kick_max(DEVFREQ_MSM_LLCCBW, 50);+ devfreq_boost_kick_max(DEVFREQ_MSM_CPUBW, 50);+ 中断;+ 情况 2:+ cpu_input_boost_kick_max(60);+ devfreq_boost_kick_max(DEVFREQ_MSM_LLCCBW, 25);+ devfreq_boost_kick_max(DEVFREQ_MSM_CPUBW, 25);+ 中断;+ 情况 3:+ cpu_input_boost_kick_max(60);+ devfreq_boost_kick_max(DEVFREQ_MSM_LLCCBW, 60);+ devfreq_boost_kick_max(DEVFREQ_MSM_CPUBW, 60);+ 中断;+ 默认值:+ pr_info("电池配置文件处于活动状态,跳过升压...n");+ 中断;+ }+ #else+ cpu_input_boost_kick_max(60);+ devfreq_boost_kick_max(DEVFREQ_MSM_LLCCBW, 50);+ devfreq_boost_kick_max(DEVFREQ_MSM_CPUBW, 50);+ #endif
一切顺利!
信息:此函数根据所选配置文件返回 0 到 3 之间的数字。它可以在调节升压和其他事情的情况下使用。
参数:无
例子:
#include <linux/kernel.h>#include <linux/cpufreq.h>#ifdef CONFIG_KPROFILESextern int kp_active_mode(void);void example_function(void) { // 根据活动配置文件模式,调整内核功能或设置开关 (kp_active_mode()) { case 1: // 当电池配置文件处于活动状态时要做的事情 case 2: // 当余额配置文件处于活动状态时要做的事情 case 3: // 当性能配置文件处于活动状态时要做的事情 default: // 当 kprofiles 被禁用或默认配置文件处于活动状态时要做的事情 } }#endif
信息:此函数可用于在任何内核事件期间将配置文件更改为任何给定模式。
论据:
level
:
类型:无符号整型
定义:要切换到的模式编号。
例子:
无效示例函数(无效) { if (required_kernel_event()) { // 切换到电池配置文件(模式 0) kp_set_mode(1); printk(KERN_INFO "切换到电池配置文件(模式 1)n"); } else { // 切换到平衡模式(模式 1) kp_set_mode(2); printk(KERN_INFO "切换到平衡配置文件(模式 2)n"); } }
信息:此函数可用于在任何内核事件期间的特定时间段内将配置文件更改为任何给定模式,然后返回到之前的活动模式。
论据:
level
:
类型:无符号整型
定义:要切换到的模式编号。
duration_ms
:
类型:无符号整型
定义:在切换回之前使用的模式之前指定模式应处于活动状态的时间量(以毫秒为单位)。
例子:
无效示例函数(无效) { if (required_kernel_event()) { // 切换到性能配置文件(模式 3)50 毫秒 kp_set_mode_rollback(3, 50); printk(KERN_INFO "切换到性能配置文件 50msn"); } }
信息:一旦通过用户或内核 API 更改配置文件模式,此基本事件通知程序就可以执行一系列代码。这对于在模式改变之后以同步方式执行一系列任务是有利的。
例子:
extern unsigned int KP_MODE_CHANGE;extern int kp_notifier_register_client(struct notifier_block *nb);extern int kp_notifier_unregister_client(struct notifier_block *nb);static int kp_mode_notifier_callback(struct notifier_block *nb, unsigned long event, void *data) { 无符号整型 profile_mode = (无符号整型) 数据; if (event == KP_MODE_CHANGE) { switch (profile_mode) { case 1: // 当电池配置文件处于活动状态时要做的事情 case 2: // 当平衡配置文件处于活动状态时要做的事情 case 3: // 当性能配置文件处于活动状态时要做的事情 default: // 当 kprofiles 被禁用或默认配置文件处于活动状态时要做的事情 } 返回NOTIFY_OK; }静态结构notifier_block kp_mode_notifier = { .notifier_call = kp_mode_notifier_callback, };静态 int __init example_driver_init(void) { // 将驱动模块注册为 Kprofiles 事件通知程序的客户端 kp_notifier_register_client(&kp_mode_notifier); 返回0; }静态无效__exit example_driver_exit(无效) { // 取消将驱动程序模块注册为 Kprofiles 事件通知程序的客户端 kp_notifier_unregister_client(&kp_mode_notifier); }module_init(example_driver_init);module_exit(example_driver_exit);
您可以通过向我们发送包含更改的拉取请求来为 Kprofiles 做出贡献,请在提交中提供准确的消息,解释您进行更改的原因。
该项目已获得 GPL-2.0 许可。
Dakkshesh :内核模块作者/维护者
Cyberknight777:内核模块联合维护者 | Kprofiles 经理 维护者
Vyom Desai:Kprofiles Manager(rom 包)作者/维护者
Martin Valba:Kprofiles Manager(独立应用程序)作者/维护者
Some5678 : Kprofiles Manager (rom 包) 联合维护者