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

DRM中render-node编号的分配

DRM系统

DRM是direct rendering manager的简称。DRM是linux kernel中与负责video cards功能的GPU打交道的子系统。DRM给出了一组API,可以供用户程序来发送命令和数据给GPU设备从而来控制比如display、render等功能。

render-node由来

在以前,DRM子系统中给每个DRM device注册的device-node就是:/dev/dri/cardX ,通过该节点来作mode-setting和rendering的控制。后来发现这么做有问题:

  • mode-setting和rendering是通过同一个文件节点node来控制的

  • 单卡的mode-setting资源不能在多个graphics-servers之间切分使用

  • 在多cards之间共享display-controller实现过于复杂

然后就有了一些改进来解决这些问题。最终是mode-setting 和 render节点分家

render node

render-node架构大概是2009年左右提出来的。站在用户程序角度来看,render node的作用是用来加速computing和rendering,render node可以通过 /dev/dri/renderDX 被访问,并且提供了基本的DRM rendering interface。与 /dev/dri/cardX 节点相比,/dev/dri/renderDX 少了一些特性:

  • 没有mode-setting(KMS)ioctls功能

  • 用dma-buf替换掉gem-flink(非安全的)

  • 不再需要DRM-auth认证

  • 不再支持pre-KMS DRM-API

这样一来,当应用程序需要hardware-acclerated rendering、访问GPGPU、offscreen rendering等时,就不需要通过DRI或者wl_drm来访问graphics-server,而是直接打开某个render node就开始使用即可。对于render node的访问权限控制则通过标注的file-system modes来控制了。

render-node并没有提供新的API,它们只是将原有的DRM-API分出了一部分到一个新的device-node,原来的node也保留了下来用于如mode-setting等控制。

render-node也没有和任何一个card进行绑定,它是由原有node的同一个driver创建的,所以尝试在原有node和render-node之间进行connect连接通信没有意义。当应用程序需要和graphics-server进行通信时,可以通过dma-buf

mode-setting node

虽然从原有的node中分离出一个render-node,简化了应用程序的访问,但对于mode-setting程序的访问没有简化。当一个graphics-server想要编程一个display-controller时,它需要是给定card的DRM-Master,可以通过drmSetMaster()接口来获得身份,但同时只能有一个DRM-Master,而且必须是由CAP_SYS_ADMIN特权的程序才能成为DRM-Master,这会带来问题:

  • 不能以非root权限运行XServer

  • 不能在同一个card上使用两个不同的XServer来控制两个不同的独立的显示器

首先想到的解决办法就是分离出mode-setting node,类似render-node的方式,/dev/dri/modesetD1 和 /dev/dri/modesetD2 节点,来分割KMS CRTC和Connector资源。

另一种方法是将所有的mode-setting资源绑定到一个DRM-Master对象,然后谁要访问mode-setting资源就可以通过访问该DRM-Master对象来实现。

DRM infrastructure

不管是render-node还是mode-setting-node,在kernel角度是如何体现的?

如果hardware没有display-controller,则可以不设置DRIVER_MODESET flag只设置DRIVER_RENDER flag,这样内核DRM只会创建render-node。如果一个hardware只有display-controller而没有rendering hardware,可以设置DRIVER_MODESET而不设置DRIVER_RENDER

大概回顾了下render node的由来。那么render node由kernel来负责创建,其编号为何从128开始,答案估计还要到kernel中寻找。

drm_dev_init

linux kernel中 drivers/gpu/drm/drm_drv.c中定义了drm_dev_init()函数,其中创建drm设备编号的代码如下

	if (drm_core_check_feature(dev, DRIVER_COMPUTE_ACCEL)) {ret = drm_minor_alloc(dev, DRM_MINOR_ACCEL);if (ret)goto err;} else {if (drm_core_check_feature(dev, DRIVER_RENDER)) {ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);if (ret)goto err;}ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);if (ret)goto err;}

涉及到两个枚举类型结构体

enum drm_driver_feature {DRIVER_GEM			= BIT(0),DRIVER_MODESET			= BIT(1),DRIVER_RENDER			= BIT(3),DRIVER_ATOMIC			= BIT(4),DRIVER_SYNCOBJ                  = BIT(5),DRIVER_SYNCOBJ_TIMELINE         = BIT(6),DRIVER_COMPUTE_ACCEL            = BIT(7),DRIVER_USE_AGP			= BIT(25),DRIVER_LEGACY			= BIT(26),DRIVER_PCI_DMA			= BIT(27),DRIVER_SG			= BIT(28),DRIVER_HAVE_DMA			= BIT(29),DRIVER_HAVE_IRQ			= BIT(30),
};enum drm_minor_type {DRM_MINOR_PRIMARY,DRM_MINOR_CONTROL,DRM_MINOR_RENDER,DRM_MINOR_ACCEL = 32,
};

当drm core检查到device设置了DRIVER_RENDER标签时,就通过drm_minor_alloc(dev, DRM_MINOR_RENDER)来分配ID,而drm_minor_alloc()函数中最终分配ID是通过idr_alloc()函数来实现,这里的type传入的就是DRM_MINOR_RENDER,也就是2。

r = idr_alloc(&drm_minors_idr,NULL,64 * type,64 * (type + 1),GFP_NOWAIT);//idr_alloc又是调用idr_alloc_u32来实现		
int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp)
{u32 id = start;int ret;if (WARN_ON_ONCE(start < 0))return -EINVAL;ret = idr_alloc_u32(idr, ptr, &id, end > 0 ? end - 1 : INT_MAX, gfp);if (ret)return ret;return id;
}
EXPORT_SYMBOL_GPL(idr_alloc);
 * idr_alloc() - Allocate an ID.* @idr: IDR handle.* @ptr: Pointer to be associated with the new ID.* @start: The minimum ID (inclusive).* @end: The maximum ID (exclusive).* @gfp: Memory allocation flags.

idr_alloc()的底3个参数就是ID的start,第4个参数是ID范围的end。所以,对于DRIVER_RENDER属性的device来说,其ID范围是

DRM_MINOR_RENDER * 64 = 128 至 (DRM_MINOR_RENDER + 1) * 64 = 192 之间。

所以才有renderD128、renderD129。

内核如何管理render-node的编号

问题:DRM中如何做到一个已经分配了的ID比如128,下一个device来分配时就不使用128而是129呢?换句话说kernel中如何记忆ID的分配结果的?

int idr_alloc_u32(struct idr *idr, void *ptr, u32 *nextid,unsigned long max, gfp_t gfp)
{struct radix_tree_iter iter;void __rcu **slot;unsigned int base = idr->idr_base;unsigned int id = *nextid;if (WARN_ON_ONCE(!(idr->idr_rt.xa_flags & ROOT_IS_IDR)))idr->idr_rt.xa_flags |= IDR_RT_MARKER;id = (id < base) ? 0 : id - base;radix_tree_iter_init(&iter, id);slot = idr_get_free(&idr->idr_rt, &iter, gfp, max - base);if (IS_ERR(slot))return PTR_ERR(slot);*nextid = iter.index + base;/* there is a memory barrier inside radix_tree_iter_replace() */radix_tree_iter_replace(&idr->idr_rt, &iter, slot, ptr);radix_tree_iter_tag_clear(&idr->idr_rt, &iter, IDR_FREE);return 0;
}
EXPORT_SYMBOL_GPL(idr_alloc_u32);

这里使用了基数树(radix-tree)。

两个显卡其分配render-node的顺序

比如我这个pc上有两个显卡intel UHD Graphics 630和Nvidia GTX 1050 Ti,然后/dev/dri/下也有两个render-node,renderD128和renderD129,内核分配它们的顺序是如何确定的?

应该是扫描PCI设备的时候就确定顺序了。

ubuntu上查看哪个card和哪个GPU绑定:

drm_info    #该命令可以查看/dev/dri/card0对应的GPU驱动

比如我这里两个显卡,card0对应intel 630, card1对应nvidia GTX 1050Ti。

那么如何确定render node和GPU对应关系?

ls /sys/class/drm/card0/device/drm/
#可以看到card0中有card0, controlD64, renderD128
ls /sys/class/drm/card1/device/drm/
#可以看到card1中有card1, controlD65, renderD129

参考:
DRM render node number

相关文章:

DRM中render-node编号的分配

DRM系统 DRM是direct rendering manager的简称。DRM是linux kernel中与负责video cards功能的GPU打交道的子系统。DRM给出了一组API&#xff0c;可以供用户程序来发送命令和数据给GPU设备从而来控制比如display、render等功能。 render-node由来 在以前&#xff0c;DRM子系统…...

将输入对象转换为数组数组的维度大于等于1numpy.atleast_1d()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将输入对象转换为数组 数组的维度大于等于1 numpy.atleast_1d() 选择题 使用numpy.atleast_1d()函数,下列正确的是&#xff1f; import numpy as np a1 1 a2 ((1,2,3),(4,5,6)) print("…...

js 删除树状图无用数据,如果子级没有数据则删除

有一个需求&#xff0c;当你从后端拿到一个树状图的时候&#xff0c;有些子级没数据&#xff0c;这时就需要我们处理一下数据&#xff0c;当然了&#xff0c;如果第一层底下的第二层没数据&#xff0c;第二层底下的所有都没数据&#xff0c;那这一层都不需要。 我的写法&#x…...

Docker 容器化(初学者的分享)

目录 一、什么是docker 二、docker的缺陷 三、简单的操作 一、首先配置一台虚拟机 二、安装Docker-CE 一、安装utils 二、 将 Docker 的软件源添加到 CentOS 的 yum 仓库中。这样可以通过 yum 命令来安装、更新和管理 Docker 相关的软件包。 三、将 download.docker.co…...

LCS 01.下载插件

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;写文章-CSDN创作中心 解题思路&#xff1a; 假设需要 n 分钟下载插件&#xff0c;前 n-1 分钟将带宽加倍&#xff0c;最后一分钟下载时总时间最少。 解题代码&#xff1a; class Solution { public:int l…...

架构-设计原则

1、面向对象的SOLID 1.1 概述 SOLID是5个设计原则开头字母的缩写&#xff0c;其本身就有“稳定的”的意思&#xff0c;寓意是“遵从SOLID原则可以建立稳定、灵活、健壮的系统”。5个原则分别如下&#xff1a; Single Responsibility Principle&#xff08;SRP&#xff09;&am…...

在 Python 3 中释放 LightGBM 的力量:您的机器学习大师之路

机器学习是 Python 占据主导地位的领域,它一直在给全球各行各业带来革命性的变化。要在这个不断变化的环境中脱颖而出,掌握正确的工具是关键。LightGBM 就是这样一个工具,它是一个强大且快速的梯度提升框架。在这份综合指南中,我们将通过实际示例和示例数据集从基础知识到高…...

Spring学习笔记(2)

Spring学习笔记&#xff08;2&#xff09; 一、Spring配置非定义Bean1.1 DruidDataSource1.2、Connection1.3、Date1.4、SqlSessionFactory 二、Bean实例化的基本流程2.1 BeanDefinition2.2 单例池和流程总结 三、Spring的bean工厂后处理器3.1 bean工厂后处理器入门3.2、注册Be…...

cmd使用ssh连接Linux脚本

前言 在开发过程中&#xff0c;由于MobaXterm&#xff0c;我不知道怎么分页&#xff08;不是屏内分页&#xff09;&#xff0c;用crtlTab&#xff0c;用起来不习惯&#xff0c;主要是MobaXterm连接了多个服务器&#xff0c;切换起来很麻烦。我是比较习惯使用altTab&#xff0c…...

Python万圣节蝙蝠

目录 系列文章 前言 蝙蝠 程序设计 程序分析 运行结果 尾声 系列文章 序号文章目录直达链接1浪漫520表白代码https://want595.blog.csdn.net/article/details/1306668812满屏表白代码https://want595.blog.csdn.net/article/details/1297945183跳动的爱心https://want5…...

TCP流套接字编程

文章目录 前言TCP 和 UDP 的特点对比TcpEchoServer 服务端实现1. 创建 ServerSocket 类实现通信双方建立连接2. 取出建立的连接实现双方通信3. 服务端业务逻辑实现关闭资源服务端整体代码 TcpEchoClient 客户端实现1. 创建出 Socket 对象来与服务端实现通信2. 实现客户端的主要…...

Python迭代器创建与使用:从入门到精通

一、可迭代对象 1、 什么是可迭代对象&#xff1f; 表示可以逐一迭代或者遍历的对象&#xff0c;序列&#xff1a;列表、元组、集合、字符串。非序列&#xff1a;字典、文件。自定义对象&#xff1a;实现了__iter__()方法的对象&#xff1b;实现了使用整数索引的 getitem()方…...

mac虚拟机安装homebrew时的问题

安装了mac虚拟机&#xff0c;结果在需要通过“brew install svn”安装svn时&#xff0c;才注意到没有下载安装homebrew。 于是便想着先安装homebrew&#xff0c;网上查的教程大多是通过类似以下命令 “ruby <(curl -fsSkL raw.github.com/mxcl/homebrew/go)” 但是都会出现…...

学信息系统项目管理师第4版系列32_信息技术发展

1. 大型信息系统 1.1. 大型信息系统是指以信息技术和通信技术为支撑&#xff0c;规模庞大&#xff0c;分布广阔&#xff0c;采用多级 网络结构&#xff0c;跨越多个安全域&#xff1b;处理海量的&#xff0c;复杂且形式多样的数据&#xff0c;提供多种类型应用 的大系统 1.1.…...

Vue3 + Nodejs 实战 ,文件上传项目--大文件分片上传+断点续传

目录 1.大文件上传的场景 2.前端实现 2.1 对文件进行分片 2.2 生成hash值&#xff08;唯一标识&#xff09; 2.3 发送上传文件请求 3.后端实现 3.1 接收分片数据临时存储 3.2 合并分片 4.完成段点续传 4.1修改后端 4.2 修改前端 5.测试 博客主页&#xff1a;専心_前端…...

宏(预编译)详解

目录 一、程序的编译环境 二、运行环境 三、预编译详解 3.1预定义符号 3.2.1 #define 定义标识符 3.2.2 #define 定义宏 3.2.3#define替换规则 3.2.4 #和## 2)##的作用&#xff1a; 3.2.5宏和函数的对比 3.2.6宏的命名约定和#undef指令 一、命名约定&#xff1a; …...

hue实现对hiveserver2 的负载均衡

如果你使用的是CDH集群那就很是方便的 在Cloudera Manager中&#xff0c;进入HDFS Service 进入Instances标签页面&#xff0c;点击Add Role Instances按钮&#xff0c;如下图所示 点击Continue按钮&#xff0c;如下图所示 返回Instances页面&#xff0c;选择HttpFS角色…...

SkyWalking 告警规则配置说明

Skywalking告警功能是在6.x版本新增的,其核心由一组规则驱动,这些规则定义在config/alarm-settings.yml 文件中。告警规则定义分为两部分: 1、告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件 2、webhook(网络钩子):定义当告警触发时,哪些服务终端需要被…...

HTML 表单笔记/练习

表单 概述 表单用于收集用户信息&#xff0c;用户填写表单提交到服务器 一般传参方式&#xff1a; GETPOSTCookie 传参要素 传参方式 GETPOST 参数的名字目标页面内容的数据类型&#xff08;只有在上传文件的时候&#xff09; 提示信息 一个表单中通常还包含一些说明性的文…...

关于Java Integer和Long使用equals直接比较

Integer和Long不能直接equals比较会返回False Long.class源码 public boolean equals(Object obj) {if (obj instanceof Long) {return this.value (Long)obj;} else {return false;} }Integer.class源码 public boolean equals(Object obj) {if (obj instanceof Integer) {…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?

FTP&#xff08;File Transfer Protocol&#xff09;本身是一个基于 TCP 的协议&#xff0c;理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况&#xff0c;主要原因包括&#xff1a; ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...

算法刷题-回溯

今天给大家分享的还是一道关于dfs回溯的问题&#xff0c;对于这类问题大家还是要多刷和总结&#xff0c;总体难度还是偏大。 对于回溯问题有几个关键点&#xff1a; 1.首先对于这类回溯可以节点可以随机选择的问题&#xff0c;要做mian函数中循环调用dfs&#xff08;i&#x…...

python读取SQLite表个并生成pdf文件

代码用于创建含50列的SQLite数据库并插入500行随机浮点数据&#xff0c;随后读取数据&#xff0c;通过ReportLab生成横向PDF表格&#xff0c;包含格式化&#xff08;两位小数&#xff09;及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...

使用homeassistant 插件将tasmota 接入到米家

我写一个一个 将本地tasmoat的的设备同通过ha集成到小爱同学的功能&#xff0c;利用了巴法接入小爱的功能&#xff0c;将本地mqtt转发给巴法以实现小爱控制的功能&#xff0c;前提条件。1需要tasmota 设备&#xff0c; 2.在本地搭建了mqtt服务可&#xff0c; 3.搭建了ha 4.在h…...