AMD GPU 内核驱动分析(二)-gpu_sched

news2024/11/18 13:56:39

AMDGPU驱动模块的依赖关系如下图,gpu_sched.ko位于GPU驱动架构的中间层,主要负责对应用发送下来的渲染和计算等命令进行调度:

编译gpu_sched.ko

模块源码位于linux-x.x.xx/drivers/gpu/drm/scheduler下,通过CONFIG_DRM_SCHED项配置编译。从Makefile来看,代码量不是很大,只有三个源文件,但子曾经曰过,尿泡虽大无斤两,秤砣虽小挑千斤,这个小小的模块中包含了GPU调度的精髓,这篇文章也是从核心的下手开始分析。

编译一遍:

make drivers/gpu/drm/scheduler/

根据编译过程也可以看到,模块本身对应的源码仅仅有sched_main.c,sched_fence.c,sched_entity.c三个。

接口定义

sched_main.c接口定义

static bool drm_sched_blocked(struct drm_gpu_scheduler *sched);
static __always_inline bool drm_sched_entity_compare_before(struct rb_node *a,
                                                        const struct rb_node *b);
void drm_sched_fault(struct drm_gpu_scheduler *sched);
void drm_sched_fini(struct drm_gpu_scheduler *sched);
static struct drm_sched_job *
drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched);
void drm_sched_increase_karma(struct drm_sched_job *bad);
int drm_sched_init(struct drm_gpu_scheduler *sched,
                onst struct drm_sched_backend_ops *ops,
                unsigned hw_submission, unsigned hang_limit,
                long timeout, struct workqueue_struct *timeout_wq,
                atomic_t *score, const char *name, struct device *dev);
int drm_sched_job_add_dependency(struct drm_sched_job *job,
                struct dma_fence *fence);
int drm_sched_job_add_implicit_dependencies(struct drm_sched_job *job,
                struct drm_gem_object *obj,
                bool write);
int drm_sched_job_add_resv_dependencies(struct drm_sched_job *job,
                struct dma_resv *resv,
                enum dma_resv_usage usage);
int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
                struct drm_file *file,
                u32 handle,
                u32 point);
void drm_sched_job_arm(struct drm_sched_job *job);
static void drm_sched_job_begin(struct drm_sched_job *s_job);
static void drm_sched_job_timedout(struct work_struct *work);
void drm_sched_job_cleanup(struct drm_sched_job *job);
static void drm_sched_job_done(struct drm_sched_job *s_job);
static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb);
int drm_sched_job_init(struct drm_sched_job *job,
                struct drm_sched_entity *entity,void *owner);
static int drm_sched_main(void *param);
struct drm_gpu_scheduler *
       drm_sched_pick_best(struct drm_gpu_scheduler **sched_list,unsigned int num_sched_list);
static bool drm_sched_ready(struct drm_gpu_scheduler *sched);
void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched);
void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,unsigned long remaining);
void drm_sched_rq_add_entity(struct drm_sched_rq *rq,struct drm_sched_entity *entity);
static void drm_sched_rq_init(struct drm_gpu_scheduler *sched,struct drm_sched_rq *rq);
void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,struct drm_sched_entity *entity);
static inline void drm_sched_rq_remove_fifo_locked(struct drm_sched_entity *entity);
static struct drm_sched_entity *
drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq);
static struct drm_sched_entity * drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq);
void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts);
static struct drm_sched_entity *drm_sched_select_entity(struct drm_gpu_scheduler *sched);
void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery);
static void drm_sched_start_timeout(struct drm_gpu_scheduler *sched);
void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad);

sched_fence.c

struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity *entity,
                        void *owner);
void drm_sched_fence_finished(struct drm_sched_fence *fence);
void drm_sched_fence_free(struct drm_sched_fence *fence);
static void drm_sched_fence_free_rcu(struct rcu_head *rcu);
static const char *drm_sched_fence_get_driver_name(struct dma_fence *fence);
static const char *drm_sched_fence_get_timeline_name(struct dma_fence *f);
void drm_sched_fence_init(struct drm_sched_fence *fence,struct drm_sched_entity *entity);
static void drm_sched_fence_release_finished(struct dma_fence *f);
static void drm_sched_fence_release_scheduled(struct dma_fence *f);
void drm_sched_fence_scheduled(struct drm_sched_fence *fence);
static void drm_sched_fence_set_deadline_finished(struct dma_fence *f,ktime_t deadline);
void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence,struct dma_fence *fence);
static void __exit drm_sched_fence_slab_fini(void);
static int __init drm_sched_fence_slab_init(void);
struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f);

sched_entity.c

static bool drm_sched_entity_add_dependency_cb(struct drm_sched_entity *entity);
static void drm_sched_entity_clear_dep(struct dma_fence *f,struct dma_fence_cb *cb);
void drm_sched_entity_destroy(struct drm_sched_entity *entity);
void drm_sched_entity_fini(struct drm_sched_entity *entity);
long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
int drm_sched_entity_init(struct drm_sched_entity *entity,
                            enum drm_sched_priority priority,
                            struct drm_gpu_scheduler **sched_list,
                            unsigned int num_sched_list,atomic_t *guilty);
static bool drm_sched_entity_is_idle(struct drm_sched_entity *entity);
bool drm_sched_entity_is_ready(struct drm_sched_entity *entity);
static void drm_sched_entity_kill(struct drm_sched_entity *entity);
static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,struct dma_fence_cb *cb);
static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk);
void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
                            struct drm_gpu_scheduler **sched_list,
                            unsigned int num_sched_list);
struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity);
void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
                            enum drm_sched_priority priority);
static void drm_sched_entity_wakeup(struct dma_fence *f,struct dma_fence_cb *cb);
static struct dma_fence *drm_sched_job_dependency(struct drm_sched_job *job,
                            struct drm_sched_entity *entity);

主要接口TRACE

drm_sched_entity_push_job接口用于向GPU发送命令包去执行,尝试追踪其调用堆栈,DRM字符设备操作函数和DRM驱动函数之间建立桥接联系,当通过标准的字符设备驱动调用到KMS驱动后,就可以将驱动转化为DRM框架内部的调用,调动DRM驱动框架的资源驱动GPU,为用户渲染应用服务。

GPU命令执行上下文是由amdgpu_job_run驱动的,其调用上下文是gpu_sched.ko中创建的drm_sched_main内核线程。

下图是抓到的一个命令包的调度执行周期,命令包首先由用户应用发起调用,在DRM上下文中调用drm_sched_entity_push_job命令包推入命令队列,完成发射。

之后在gpu_sched模块的内核线程中,完成准备,执行,释放的命令执行周期。


结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1018201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

更新至2021年,互联网相关指标数据

更新至2021年,互联网相关指标数据 1、来源:国家统计J和各省NJ 2、指标:域名数、网站数、网页数、互联网宽带接入端口、互联网宽带接入用户、城市宽带接入用户、移动互联网用户、移动互联网接入流量、联网上网人数 3、范围:31省…

四、日志编写 —— TinyWebServer

日志编写 —— TinyWebServer 一、 前言 上期已经写完lock类的编写。这期是日志的编写。 对于日志需要弄懂几个基本概念才可以更好的理解和编写日志。 什么是日志?常用的日志级别有哪些?日志的基本格式是什么?异步日志类刷新缓冲区的作用同…

虚幻4学习笔记(12)操控导入的角色、动画蓝图、播放蒙太奇和打包、角色重定向

虚幻4学习笔记 操控导入的角色设置鼠标旋转关掉动态模糊 动画蓝图、播放蒙太奇和打包角色走路奔跑动画shift 奔跑F 跳舞移动打断 跳舞 打包角色重定向姿势调整解决跑步 腿分太开隐藏剑 B站UP谌嘉诚课程:https://www.bilibili.com/video/BV164411Y732 操控导入的角色…

FreeSWITCH 1.10.10 简单图形化界面10 - 鼎兴FXO网关SIP注册公网IPPBX落地

FreeSWITCH 1.10.10 简单图形化界面10 - 鼎兴FXO网关SIP注册公网IPPBX落地 0、 界面预览1、创建一个话务台2、创建PBX SIP中继并设置呼入权限3、设置呼出规则4、设置分机呼出权限5、设置FXO 网关相关信息6、设置FXO网关端口组呼入号码7、设置FXO网关呼叫路由(呼入及…

Eclipse搭建struts2框架

新建动态web项目; 输入项目名称; New Runtime后选择如下, 选择tomcat的安装目录; 然后如下,完成; 当前的目录结构如下;之前要配置好java环境; 如果创建项目时没有选中生成web.xml&am…

人工智能学习1

文章目录 人工智能人工智能的诞生人工智能的发展历程人工智能与机器学习的关系 机器学习机器学习的发展历程讨论机器学习的必要性机器学习的定义机器学习的三要素机器学习的基本概念作业 人工智能 人工智能的诞生 人工智能诞生于一群科学家想使用机器模拟人类思维或者人类智能…

黑马JVM总结(十二)

(1)五种引用_强软弱 实线箭头表示强引用,虚心线表示软弱虚终结器引用 在平时我们用的引用,基本都为强引用 ,比如说创建一个对象通过运算符赋值给了一个变量,那么这个变量呢就强引用了刚刚的对象 强引用的…

Linux 磁盘挂载 磁盘卸载

挂载: 虚拟机中本来是没有光盘,但是有复刻的镜像文件,不影响我们挂载,当我们将镜像设备挂载到固定的目录下后,我们就可以通过访问目录,来查看镜像文件中的内容。 1. 创建挂载点: 一般虚拟设备上…

Java进化史:从Java 8到Java 17的语言特性全解析

文章目录 Java 8:引入Lambda表达式和Stream APILambda表达式Stream API Java 9:模块化系统模块Jigsaw项目 Java 10:局部变量类型推断Java 11:引入HTTP客户端HTTP客户端 Java 12:引入Switch表达式Switch表达式 Java 13到…

为什么学鸿蒙HarmonyOS——兴趣使然,HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统

为什么学鸿蒙HarmonyOS 为什么学鸿蒙的诞生鸿蒙的未来鸿蒙OS典型案例鸿蒙是分布式操作系统总结参考学习资料 为什么学 兴趣使然,了解了一下鸿蒙系统的历史,是AIOT系统,是中国的未来的核心系统 鸿蒙:HarmonyOS是一款面向万物互联时…

antd a-list 添加分页

会分为三部分 template <a-list item-layout"horizontal" :data-source"localData" :pagination"{...paginationProps,current:currentPage}"><a-list-item slot"renderItem" slot-scope"item"><a-list-ite…

伪原创工具-好用的伪原创软件有哪些特征

在这个信息爆炸的时代&#xff0c;我们每天都要处理大量的文字信息&#xff0c;不管是在学校里写作业&#xff0c;还是在工作中处理文件。有时候&#xff0c;为了节省时间和精力&#xff0c;我们会考虑使用一些文章伪原创工具。 什么是文章伪原创&#xff1f; 让我们来明确一…

Netty(二)NIO-入门

Netty 入门 1. 概述 1.1 Netty Netty是一个异步的&#xff0c;基于事件驱动的网络应用框架&#xff0c;用于快速开发可维护&#xff0c;高性能的网络服务器和客户端 Cassandra&#xff0c;Spark&#xff0c;Hadoop&#xff0c;RocketMQ&#xff0c;ElasticSearch&#xff0c…

【小沐学写作】程序员必备技能:在线协作文档汇总

文章目录 1、简介2、微软Office在线文档2.1 功能简介2.2 使用费用2.3 用户体验 3、石墨文档3.1 功能简介3.2 使用费用 4、腾讯文档4.1 功能简介4.2 使用费用 5、语雀5.1 功能简介5.2 使用费用 6、飞书6.1 功能简介6.2 使用费用 7、印象笔记7.1 功能简介7.2 使用费用 结语 1、简…

解决xinput1_3.dll丢失的终极方法!快来尝试这4个方法吧!

在计算机系统中&#xff0c;DLL&#xff08;动态链接库&#xff09;是一个重要的组成部分&#xff0c;它们负责在程序和操作系统之间共享代码和数据。然而&#xff0c;当xinput1_3.dll丢失时&#xff0c;可能会导致一系列的问题&#xff0c;如系统运行缓慢、应用程序无法启动等…

当下最好不要碰PCIe 5.0 SSD

为了追求高性能&#xff0c;现在说到SSD&#xff0c;大家基本都想要买NVME PCIE SSD。PCIE SSD在消费端、云市场、数据中心的占比均在继续攀升。 截至目前&#xff0c;虽然PCIe 5.0已经发布已经过去4年&#xff0c;但是整个生态并没有很繁荣。当前主流市场还是PCIe 3.0和PCIe 4…

【算法】二分答案(TODO)

文章目录 相关链接什么时候使用二分答案&#xff1f;题目列表最大化最小化相关题目列表&#x1f4d5;2439. 最小化数组中的最大值解法1——二分答案解法2——分类讨论O(n) 2513. 最小化两个数组中的最大值&#xff08;二分答案lcm容斥原理&#xff09;&#x1f402;好题&#x…

VS code 下 makefile 【缺少分隔符 停下来】 报错解决方法

首先来看报错的makefile源码 再来看报错的信息&#xff1a; 第5行缺少分隔符&#xff0c;其实不止是第5行&#xff0c;只要是前面需要加tab留白的行都会报这个错误&#xff0c;比如说第7行第11行 编译的时候&#xff0c;前面的留白必须是按tab键生成的 但是&#xff01;&…

成为一个优秀的程序员必读书目有哪些?

首推一本刚刚出版的新书&#xff1a; 程序员的制胜技 新手程序员的生存指南&#xff0c;教你如何将理论转化为实践技能&#xff0c;解决编程工作中的挑战&#xff0c;拥有实战智慧&#xff0c;成为开发高手&#xff01; 作者20多年实战经验的结晶&#xff0c;新手程序员的生存…

从HTTP到HTTPS:网站安全通信的演进之路

HTTP协议与TCP/IP协议族内的其他协议相同部分&#xff0c;用于客户端和服务器端的通信。下面来看一下HTTP具体是怎么工作的。 1、HTTP前生今世 在HHTP/0.9版本&#xff0c;主要是通过确立了客户端请求、服务器端响应的通信流程来解决HTML文件传输&#xff0c;只能获取文本资源…