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

深圳网站建设延安网站建设 東道网络

深圳网站建设延安,网站建设 東道网络,国家官方网站,宇宙设计网站推荐目录 Linux devfreq 简介核心数据结构devfreq_dev_profile 结构体devfreq_governor 结构体devfreq 结构体 工作流程devFreq framework 初始化governor 初始化devfreq Device 注册动态变频的实现device_unregister 流程 用户空间节点参考文章 Linux devfreq 简介 现在的 Soc 由…

目录

      • Linux devfreq 简介
      • 核心数据结构
        • devfreq_dev_profile 结构体
        • devfreq_governor 结构体
        • devfreq 结构体
      • 工作流程
        • devFreq framework 初始化
        • governor 初始化
        • devfreq Device 注册
        • 动态变频的实现
        • device_unregister 流程
      • 用户空间节点
        • 参考文章

Linux devfreq 简介

现在的 Soc 由众多的子模块构成,比如CNNDSPISPCPU等,在不同的场景下,并非所有的模块都要保持最高的性能,因此,SoC 设计的时候会划分一些电压域,这些电压域内的模块,可以根据具体需要调整电压和频率,从而达到既能实现功能,又能降低功耗的目的

不过频率电压并不是随意搭配的,一般情况下,高频对应着高压,低频对应着低压,这是由于晶体管的电器特性决定的

Linux 内核用 OPP(Operation Performance Point) 对这些设备支持的频率和电压进行描述和管理,CPUDVFS 也就是 cpufreq 也是基于 OPP 实现的,但是仅仅支持 CPU 设备的调频和调压,这里主要介绍的是设备的 DVFS,也是基于 OPP 实现的,Linux 内核实现了一个 devfreq framework 用于实现和管理 devicedvfs,用于支持非CPU设备的调频,调压,并且设备可以匹配自己的 governor 策略

devFreq framework 规范了设备调频调压的过程,也标准化了用户空间的控制接口,通过设备的需求,利用 governor 策略控制频率,进而根据 opp table 选择对应的电压
devfreq_framework

核心数据结构

devfreq_dev_profile 结构体

devfreq_dev_profile 结构体, OPP device 注册到 devfreq framework 的数据结构,主要包含 OPP 设备的频率信息和相关的回调函数,是 devfreq frameworkOPP device 的交互接口,将 OPP device driverdevfreq 的使用,简化为对 devfreq profile 结构体的填充

// drivers/devfreq/devfreq.c 
// include/linux/devfreq.h
struct devfreq_dev_profile {// devfreq 注册的初始化频率unsigned long initial_freq;// governor polling 的时间间隔,单位 msunsigned int polling_ms;// devfreq framework用于设定 OPP device frequency的回调函数int (*target)(struct device *dev, unsigned long *freq, u32 flags);// devfreq framework 用于获取 OPP device 负载状态的回调函数int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat);// devfreq framework 用于获取当前频率的回调函数int (*get_cur_freq)(struct device *dev, unsigned long *freq);// 当 devfreq 设备从 devfreq framework 移除的时候调用// 调用时机是 error 或者 devfreq_remove_device() callvoid (*exit)(struct device *dev);unsigned long *freq_table;unsigned int max_state;
};
devfreq_governor 结构体

devfreq_governorgovernor 注册到devfreq framework 的数据结构,主要包含 governor 的相关属性和具体的函数实现,是devfreq frameworkgovernor 的交互接口

struct devfreq_governor {// 将 devfreq_governor 作为链表节点进行管理struct list_head node;// governor nameconst char name[DEVFREQ_NAME_LEN];// 是否可以切换为其他 governor 1:不能切换const unsigned int immutable;// governor 注册到 devfreq framework 的算法实现函数,返回调整后的频率int (*get_target_freq)(struct devfreq *this, unsigned long *freq);// governor 注册到 devfreq framework 的 event 处理函数,处理 start,stop,suspend,resume 等 eventint (*event_handler)(struct devfreq *devfreq,unsigned int event, void *data);
};

其中的 get_target_freq 一般会调用 devfreq_dev_profile.get_dev_status() 获取当前 OPP device 的负载情况 (load = busy_time / total_time)

devfreq 结构体

devfreq 结构体是 devfreq device 的核心结构,每个注册的设备都会新建一个 devfreq 结构体,
作用是将上述 OPP devicedevfreq_dev_profilegovernordevfreq_governor 连接到一起,
并通过设备模型的 device 类,为user空间提供接口

struct devfreq {struct list_head node;struct mutex lock;// device 属于 devfreq_class, 父节点就是使用 devfreq 的 device 比如 GPU,DDR等struct device dev;// OPP device 注册到 devfreq framework 的配置信息struct devfreq_dev_profile *profile;// governor注册到devfreq framework的配置信息const struct devfreq_governor *governor;char governor_name[DEVFREQ_NAME_LEN];struct notifier_block nb;// 用于监控负载情况的 delayed workstruct delayed_work work;unsigned long previous_freq;struct devfreq_dev_status last_status;void *data; /* private data for governors */// 限制用户请求的最小频率unsigned long min_freq;// 限制用户请求的最大频率unsigned long max_freq;bool stop_polling;/* information for device frequency transition */// 记录 devfreq 中 frequency 的转移信息unsigned int total_trans;unsigned int *trans_table;unsigned long *time_in_state;unsigned long last_stat_updated;struct srcu_notifier_head transition_notifier_list;
};

工作流程

devFreq framework 初始化

逻辑非常简单,主要完成下面的任务:

  • 创建 devfreq_class 设备类
  • 创建 delayed work,是用于监控负载的工作队列
  • 加入到 subsys_initcall,系统启动时进行初始化
static int __init devfreq_init(void)
{devfreq_class = class_create(THIS_MODULE, "devfreq");devfreq_wq = create_freezable_workqueue("devfreq_wq");devfreq_class->dev_groups = devfreq_groups;return 0;
}
subsys_initcall(devfreq_init);
governor 初始化

系统中可以支持多个 governor,在系统启动时就会进行初始化,并注册到 devFreq framework 中,后续的 OPP device 创建 devFreq 设备,
会根据 governor name 从已经初始化的 governor 列表中,查找对应的 governor 实例

// driver/devfreq 目录下 governor_performance.c  
// driver/devfreq 目录下 governor_simpleondemand.cstatic struct devfreq_governor devfreq_performance = {.name = "performance",.get_target_freq = devfreq_performance_func,.event_handler = devfreq_performance_handler,
};static int __init devfreq_performance_init(void)
{return devfreq_add_governor(&devfreq_performance);
}
subsys_initcall(devfreq_performance_init);

主要流程:

  1. 填充 devfreq_governor 结构体,不同类型的结构体,对 get_target_freqevent_handler 会有不同的实现
  2. 调用 devfreq_add_governor 加入到 devfreq frameworkgovernor 列表中
  3. 加入到 subsys_initcall,系统启动时进行初始化

目前系统支持下面几种 governor

  • Simple_ondemand: 按需调整模式,根据负载动态频率,平衡性能和功耗
  • Performance: 性能优先模式,调整到最大频率
  • Powersave: 功耗优先模式,调整到最小频率
  • Userspace: 用户指定模式,根据用于 sysfs 节点写入进行调整
  • Passive: 被动模式,使用设备指定方法做调整或者跟随father devfreq 设备的governor
devfreq Device 注册

这里以开源的 mali gpu midgard 内核为例

  1. 配置正常的OPP table,确定正常的 OPP 电压和频率
  2. 获取 OPP device 的频率信息,完善正确的回调函数,最后填充 devfreq profile 结构体
  3. 调用 devfreq_add_device 函数,将 devfreq profile 结构,governor name 添加到 devfreq 框架
int kbase_devfreq_init(struct kbase_device *kbdev)
{struct devfreq_dev_profile *dp;dp->initial_freq = kbdev->current_freqs[0];dp->polling_ms = 100;dp->target = kbase_devfreq_target;dp->get_dev_status = kbase_devfreq_status;dp->get_cur_freq = kbase_devfreq_cur_freq;dp->exit = kbase_devfreq_exit;kbdev->devfreq = devfreq_add_device(kbdev->dev, dp, "simple_ondemand", NULL);
}
动态变频的实现

devfreq framework 负责监控程序的运行,governor 提供算法,OPP device 提供自身负载状态和频率设置放的实现,系统中有不同的 governor,不同的 governor 有不同的管理算法

  1. devfreq_add_device 时发送 DEVFEQ_GOV_START 事件
struct devfreq *devfreq_add_device(struct device *dev,struct devfreq_dev_profile *profile,const char *governor_name,void *data) {......devfreq->governor = governor;err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START,NULL);goto err_init;
}
  1. governorevent_handler 收到 DEVFREQ_GOV_START事件,调度工作队列,运行负载监控程序

Note: 这里以 simple_ondemand governor 为例

static int devfreq_simple_ondemand_handler(struct devfreq *devfreq,unsigned int event, void *data) {switch (event) {case DEVFREQ_GOV_START:devfreq_monitor_start(devfreq);break;......
}
  1. 负载监控程序
  • 调用 governorget_target_freq 方法,获取下一次的调频目标值
  • 调用 OPP device 注册到 devfreq_frameworktarget 函数,设置新的频率信息
  • 调度延迟工作队列,延迟 OPP device 设置的轮询间隔,再次运行
static void devfreq_monitor(struct work_struct *work)
{int err;struct devfreq *devfreq = container_of(work,struct devfreq, work.work);mutex_lock(&devfreq->lock);// monitor 程序的核心函数err = update_devfreq(devfreq);/* 以 poolling_ms 为周期进行周期监控 */queue_delayed_work(devfreq_wq, &devfreq->work,msecs_to_jiffies(devfreq->profile->polling_ms));mutex_unlock(&devfreq->lock);
}int update_devfreq(struct devfreq *devfreq)
{/*获取要调频到的结果频率*/devfreq->governor->get_target_freq(devfreq, &freq);/*在调频前后都有通知发出来*/devfreq_notify_transition(devfreq, &freqs, DEVFREQ_PRECHANGE);/*调用 OPP devices的 target 函数设置目标频率*/devfreq->profile->target(devfreq->dev.parent, &freq, flags);devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE);
}
device_unregister 流程

device_unregister 注销过程中会调用 devfreq_dev_release 函数,完成下面的事务:

  1. 发送 DEVFREQ_GOV_STOP eventgovernor停止运行
  2. 回调 OPP device 注册到 devfreq framework 的exit函数
  3. 释放 devfreq device 申请的资源
static void devfreq_dev_release(struct device *dev)
{struct devfreq *devfreq = to_devfreq(dev);......if (devfreq->governor)devfreq->governor->event_handler(devfreq,DEVFREQ_GOV_STOP, NULL);

用户空间节点

devfreq framework 初始化时,会创建下面的节点:

static struct attribute *devfreq_attrs[] = {&dev_attr_governor.attr, &dev_attr_available_governors.attr, // 可用的 governor&dev_attr_cur_freq.attr, //当前频率&dev_attr_available_frequencies.attr,// 可用频率列表&dev_attr_target_freq.attr, // 目标频率&dev_attr_polling_interval.attr, // 调度间隔&dev_attr_min_freq.attr, // 最小频率&dev_attr_max_freq.attr, // 最大频率&dev_attr_trans_stat.attr, // 状态调整记录表NULL,
};
ATTRIBUTE_GROUPS(devfreq);

available_frequencies: 可用的频率列表
available_governors:可用的governor
cur_freq:当前频率
governor: 当前governor
max_freq:最大频率
min_freq :最小频率
polling_interval:governor调度的时间间隔,单位是ms.
target_freq:目标频率
trans_stat:状态调整表记录

参考文章

https://mp.weixin.qq.com/s/TI3ryUewRgt9LFKr-tDkJQ
https://www.cnblogs.com/hellokitty2/p/13061707.html

http://www.yayakq.cn/news/768841/

相关文章:

  • 杭州教育网站建设科普类网站怎么做
  • 厦门模板建站网站开发工程师培训
  • 好的网站制作wordpress网盘
  • 手机网站怎么开发安顺高端网站建设平台
  • 潍坊专业网站建设价格低秦皇岛海三建设集团
  • 建设银行网站用什么字体wordpress去除 版权信息
  • 上海一 网站建设公司网站建设相关工作
  • 从seo角度做网站流量企业网站建设很有必要
  • flash 如何做游戏下载网站策划公司网站设计
  • 学校网站建设的软件环境网页制作与网站建设作业
  • 做网站和维护网站从用户旅程角度做网站分析
  • 网站建设教程百度云做360手机网站首页
  • 用php做网站需要什么软件东营市报名系统网站设计公司
  • 网站推广塔山双喜开发一个小程序的流程
  • 苏州高端网站建设公司网页视频下载神器哪种最好
  • 邯郸个人做网站google网站推广
  • 网博士自助建站系统学设计的网站都有哪些
  • 谁做网站个人网站模板大全
  • 泰州做企业网站的哪里好做网站是不是就能上传东西
  • 产品包装设计网站网站建设制作设计惠州
  • jsp做网站开发手绘元素素材
  • 为什么会显示危险网站公司网站建设费计入哪个科目
  • 建网站主要工具如何自己做网页
  • 九江网站建设求职简历设计用哪些网站
  • 鹰潭网站开发推广计划与推广单元设置
  • 竞拍网站开发网站建设教育平台
  • 旅游网站管理系统php网站后台有安全狗
  • 网站备案初审千网推软文推广平台
  • 嘉定网站制作给我做网站的人老是给我留点尾巴
  • 企业网站管理系统带授权网站建设完成后期维护