(2020.8.10 ~ 2020.8.16)
DRM
1. 彻底废弃 drm_driver 中的 prime callbacks,全面启用 GEM Object functions
从 kernel 4.19 开始,DRM 框架引入了 shmem GEM 后端,随该 patch 一同合入的还有 drm_gem_object_funcs
结构体。该结构体的引入,极大的统一了 GEM Prime 接口的管理。以前,凡是和 prime 相关的接口都是放在 drm_driver
结构体中的,这使得 drm_driver 结构体变得越来越臃肿,框架调用也显得比较凌乱。而引入 drm_gem_object_funcs 之后,只需要通过 drm gem object 就可以调用相关的回调函数,而无需访问 drm_driver 指针。这才真正体现了 kernel 的面向对象思想,以前 gem object 中只有数据,没有方法(即回调函数),现在的 gem object 成了一个鲜活的对象,它既有数据又有方法,拿到 gem object 就可以完成所有与 GEM 相关的操作,非常方便,且可读性强。
虽然从 2018 年就合入了 drm_gem_object_funcs 的功能,但大部分 drm 驱动仍然保持着原有的 drm_driver prime 接口,drm_gem_object_funcs 的普及率并不高。如今,是时候该对这些驱动进行清理了。Thomas Zimmermann( drm-misc Maintainer, SUSE)为我们做了这件事,他总共提了 20 笔 patch,其中第 1~ 19 笔 patch 是专门用来清理各个 drm 设备驱动的,第 20 笔 patch 则是彻底删除 drm_driver 中 gem prime 相关 callbacks 的。
更多详细内容,请查阅 dri-devel 邮件列表:[PATCH 00/20] Convert all remaining drivers to GEM object functions
2. 为 GEM vmap 添加 I/O memory 的支持
drm prime exporter 中有一个 vmap 接口,专门用于将后端内存映射到一片连续的虚拟地址空间上(kernel 空间),方便在 kernel 空间使用 CPU 去访问这段内存。但如果要访问的物理内存是在 IO 端口上呢?目前的接口对于 ARM 平台来说都没有什么大问题,访问 IO 地址空间和访问普通的内存没有什么区别。但对于 sparc64 或 X86 这种架构的平台来说可能就不那么方便了,众所周知,在这类平台上如果要访问 IO 端口地址空间,需要使用专门的 IO 指令,如 X86 上的 IN 和 OUT。对于这类平台,就需要对 vmap 接口进行 hack 了,否则返回的 IO 地址被拿去当 CPU 地址使用可就麻烦了。
为了解决 bochs drm 驱动中的 sparc64 IO memory 映射问题,Thomas Zimmermann(drm-misc maintainer, SUSE)新增了 drm_gem_membuf
结构体,用于保存 vmap 返回的地址,不过该地址不再是简单的 CPU 指针,而是 CPU 地址和 IO 地址的联合体,通过 is_iomem 变量来进行区分。同时,所有 gem prime vmap 接口返回的地址都被修改成了 drm_gem_membuf 结构体指针,以此来兼容 IO memory 的映射。
更多详细内容,请查阅 dri-devel 邮件列表:[RFC][PATCH v2 0/4] Support GEM object mappings from I/O memory
3. dma-heap:添加 system-uncached HEAP
ION 是 Android 系统下专用于分配 Graphic Buffer 的内存分配器,它是基于 DMA-BUF 实现的,可以在多个设备之间实现 buffer 共享。不过它的代码一直存放在 staging 目录下,再过几年可能就不复存在了,而 dma-heap 则是专门用来取代 ION 的。用过 ION 的同学都知道,ION 在 SYSTEM_HEAP 上分配内存时,既可以分配带 cache 的 buffer,也可以申请不带 cache 的 buffer,这个过程是通过传入 ION_FLAG_CACHED
标志位来实现的。
而现有的 dma-heap 功能还比较单一,只支持 SYSTEM HEAP(物理非连续 buffer) 和 CMA HEAP(物理连续 buffer),而且 SYSTEM HEAP 默认只支持带 Cached 的 buffer,不带 cache 的 buffer 目前还不支持。通常,只有 CPU 需要参与访问的 buffer 才需要带 cached,这样可以加快 CPU 的访问速度,但是在 CPU 和 DMA 设备之间共享内存时,需要来回刷 Cache,这会增加系统开销。不带 cached 的 buffer 则通常只用于 DMA 设备之间的 buffer 共享,因此省去了 Cache 同步所带来的额外开销,提高了设备之间的访问效率。
正是基于以上原因,John Stultz(dma-heap maintainer, Linaro)给 dma-heap 提交了 system-uncached heap 的 patch,这样应用程序就可以申请不带 cache 的 buffer 了(默认为 writecombine),极大的提高了 DMA 设备访问 buffer 的效率。
更多详细内容,请查阅 dri-devel 邮件列表:[RFC][PATCH v2 2/2] dma-heap: Add a system-uncached heap
4. DMA Heap vs GEM
DMA Heap 是用来替代 ION 的内存分配器,主要用于多媒体设备的 Graphic Buffer 分配。而 DRM 下的 GEM 则是专用于 Display 和 GPU 显存相关的 buffer 分配。二者从功能上来讲,都是 buffer 分配,且都能将所分配的 buffer 转换成 dma-buf fd 进行设备间的共享。这就给部分开发者带来了困惑,如 Mikko Perttunen 就在社区表达了自己的疑惑:
他认为,现今的 dma-heap 已经能很好的满足 TegraDRM 内存分配需求,可以完全抛弃传统的 GEM 框架,不用再实现驱动自定义的 GEM IOCTL 内存分配接口,直接使用 dma-heap 来代替就可以了。但是他又觉得头疼的是,dma-heap 相比 GEM 有一个劣势,就是 dma-heap 所分配的 buffer 只能以 fd 的形式导出给上层应用。大家都知道,fd 属于进程资源,每个进程的 fd 总数是有限制的(一般最大 1024 个),一旦应用程序的 fd 被用尽,则无法再获取到 dma-buf fd,即无法通过 dma-heap 分配内存。而 DRM GEM 分配内存时,直接返回给应用程序的是 GEM OBJ ID,而不是 dma-buf fd,所以 GEM 不会有这类风险。因此他的问题是:dma-heap 在 kernel 中到底扮演着什么样的角色?如果 dma-heap 的最终目的是成为一个通用的多媒体 buffer 分配器,那么上面提到的 fd 限制问题是否应该被解决掉?还是说将该问题留给应用程序自己去处理?
对于该问题,Daniel Vetter(drm-misc Maintainer, Intel) 的回答是:目前没人知道答案。不过他认为,dma-heap 只是个可以跨设备共享的内存分配器,分配出来的 dma-buf 主要用于在多个设备之间共享,因此它更侧重于“共享”二字。而 GEM 则是专用于分配具有硬件加速功能的 buffer(如 GPU 显存、或特殊地址的 memory),该 buffer 可以给其他设备共享,也可以自己私有访问,因此它更侧重于“专用”二字。因此他并不认为 dma-heap 可以替代 GEM,而且对于 TegraDRM,明明有现成的 GEM IOCTL 接口,为什么非要用 dma-heap 呢?
而 John Stultz (dma-heap maintainer, Linaro)的回答似乎有点偏题,他并没有直接回答该问题,而是提到了另一个问题:我们是否需要给 dma-heap 添加 in-kernel use 的接口?因为他发现,有的驱动想直接把 dma-heap 作为自己 buffer 分配的后端分配器,但是 dma-heap 又没有提供以 dma-buf 指针作为返回值的接口,使得它们不得不重写一套和 dma-heap 重复的 exporter 代码。他在想 Mikko 是不是也是有类似的需求,如果是的话,他们可以进一步探讨 dma-heap 新增 in-kernel use 接口的可能性。但是站在框架层的角度考虑,他认为 buffer 分配还是应该由应用层来发起,而不应该由 kernel 层发起,因为只有应用程序才最清楚它所需要的 buffer 将传递给哪个设备,因此才能将更为准确的 buffer 属性传给 dma-heap 驱动。
更多详细内容,请查阅 dri-devel 邮件列表:Role of DMA Heaps vs GEM in allocation
5. dma-buf: 为每个进程添加 buffer 使用状态的 ftrace 信息
Kalesh Singh(Google)为 dma-buf 添加了 ftrace 跟踪信息,可用于跟踪每个进程对 dma-buf 的分配/释放/mmap/munmap操作。这对于系统面临大量内存使用压力的情况,能提供有效的性能分析方法。
更多详细内容,请查阅 dri-devel 邮件列表:[PATCH 0/2] Per process tracking of dma buffers
6. backlight: 代码优化,新增宏定义及操作接口
Sam Ravnborg(drm-misc maintainer)为简化 backlight 驱动编写,新增了 4 个宏定义和 5 个 set/get 辅助接口:
宏定义:
BACKLIGHT_PROPS
DECLARE_BACKLIGHT_INIT_RAW
DECLARE_BACKLIGHT_INIT_PLATFORM
DECLARE_BACKLIGHT_INIT_FIRMWARE
通过上面的宏定义,我们可以在 backlight 驱动中简化背光初始化的参数。
set/get helper:
backlight_get_actual_brightness
backlight_get_max_brightness
backlight_set_brightness
backlight_set_power_on
backlight_set_power_off
如果没有这些接口,我们只能通过 bd->props.xxx 来访问,每次还要做空指针判断,代码繁琐。现在有了这些 helper 接口,我们的代码就会干净许多。
更多详细内容,请查阅 dri-devel 邮件列表:[RFC PATCH v1 0/22] backlight: add init macros and accessors
7. Huawei Hikey970 DRM/KMS 驱动 Upstreaming
Hikey970 是华为 2018 年推出的一款开源 96Board,基于海思麒麟970 SoC,CPU 为 4 核 A73 + 4 核 A53,GPU 采用 ARM Mali-G72 MP12,性能强劲,主要用于 AI 高性能计算。
前不久 Mauro Carvalho Chehab(华为?)向社区提交了 Hikey970 的 DRM/KMS 驱动,该驱动来源于 Linaro Hikey 官方 kernel 仓库,目前该驱动显示功能还存在一定 bug (如休眠唤醒后显示器将无法恢复到之前的时钟频率),不过这并不影响 Mauro 的 upstreaming 计划。目前主要是接受社区人员的 comment,好做进一步调整,预计离真正 merge 还有很长一段路要走。
更多详细内容,请查阅 dri-devel 邮件列表:DRM/KMS experimental drivers for HiKey 970
以下内容因为工作太忙,没来得及详细介绍,大家就直接访问原链接吧。
Mesa
AMD R600 骨灰级显卡 Gallium3D 驱动新增 Computer Shader 功能
详情:R600 Gallium3D Now Has Compute Shaders Working With NIR
Wayland
3. RFC: libei - emulated input in Wayland compositors
其他
1. Fedora’s FESCo Approves Using DXVK As Their Default Wine Direct3D Back-End