Linux内核内存管理:设备管理的资源- Devres

Devres是一个内核设施,通过自动释放驱动程序中分配的资源来帮助开发人员。它简化了init/probe/open函数中的错误处理。使用Devres,每个资源分配器都有自己的托管版本,负责资源的 release 和 free。

本文严重依赖内核源代码树中的Documentation/drivermodel/devres.txt文件,该文件处理devres API,并列出了支持的函数及其描述。

使用资源管理函数分配的内存与设备相关联。Devres由一个与struct设备相关联的任意大小内存区域的链表组成。每个devres资源分配器将已分配的资源插入到列表中。资源一直是可用的,直到代码手动释放它,或当设备从系统中分离,或当驱动程序被卸载。每个devres条目都与一个release函数相关联。释放devres有不同的方法。无论如何,所有devres条目在驱动分离时被释放。在释放时,将调用相关的release函数,然后释放devres条目。

下面是驱动程序可用的资源列表:

  • 用于私有数据结构的内存
  • 中断(IRQs)
  • 内存区域分配(request_mem_region())
  • 内存区域I/O映射(ioremap())
  • 缓冲内存(可能带有DMA映射)
  • 不同的框架数据结构: clocks, GPIOs, PWMs, USB phy, regulators, DMA等等

本文讨论的几乎每个函数都有其托管版本。在大多数情况下,为函数的托管版本指定的名称是通过在原始函数名称前加上devm来获得的。例如,devm_kzalloc()是kzalloc()的托管版本。另外,参数保持不变,但是被移到了右边,因为第一个参数是为其分配资源的结构设备。对于非托管版本已经在其参数中给出了struct device的函数,有一个例外:

void *kmalloc(size_t size, gfp_t flags)
void * devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)

当设备与系统分离或设备驱动程序被卸载时,内存将自动释放。如果不再需要内存,可以使用devm_kfree()释放内存。

这是老方法:

ret = request_irq(irq, my_isr, 0, my_name, my_data);
if (ret) {
    dev_err(dev, "Failed to register IRQ.\n");
    ret = -ENODEV;
    goto failed_register_irq; /* Unroll */
}

这是正确的方法:

ret = devm_request_irq(dev, irq, my_isr, 0, my_name, my_data);
if(ret) {
    dev_err(dev, "Failed to register IRQ.\n");
    return -ENODEV; /* Automatic unroll */
}

 

posted @ 2021-07-22 16:07  闹闹爸爸  阅读(690)  评论(0编辑  收藏  举报