前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >devm_xxx机制

devm_xxx机制

作者头像
233333
发布2019-05-25 18:29:02
1.6K0
发布2019-05-25 18:29:02
举报

前言

devm是内核提供的基础机制,用于方便驱动开发者所分配资源的自动回收。参考内核文档devres.txt。总的来说,就是驱动开发者只需要调用这类接口分配期望的资源,不用关心释放问题。这些资源的释放会在device对象销毁时自动释放。

devres使用

不同的内核模块提供了对应的devm_xxx接口,如下(不仅仅这些):

代码语言:javascript
复制
MEM
  devm_kmalloc()    
  devm_kzalloc()
  devm_kcalloc()
  devm_kmalloc_array()
  devm_kstrdup()
  devm_kfree()

IIO
  devm_iio_device_alloc()
  devm_iio_device_free()
  devm_iio_trigger_alloc()
  devm_iio_trigger_free()
  devm_iio_device_register()
  devm_iio_device_unregister()

IO region
  devm_request_region()
  devm_request_mem_region()
  devm_release_region()
  devm_release_mem_region()

IRQ
  devm_request_irq()
  devm_free_irq()

DMA
  dmam_alloc_coherent()
  dmam_free_coherent()
  dmam_alloc_noncoherent()
  dmam_free_noncoherent()
  dmam_declare_coherent_memory()
  dmam_pool_create()
  dmam_pool_destroy()

PCI
  pcim_enable_device()  : after success, all PCI ops become managed
  pcim_pin_device() : keep PCI device enabled after release

IOMAP
  devm_ioport_map()
  devm_ioport_unmap()
  devm_ioremap()
  devm_ioremap_nocache()
  devm_iounmap()
  devm_ioremap_resource() : checks resource, requests memory region, ioremaps
  devm_request_and_ioremap() : obsoleted by devm_ioremap_resource()
  pcim_iomap()
  pcim_iounmap()
  pcim_iomap_table()    : array of mapped addresses indexed by BAR
  pcim_iomap_regions()  : do request_region() and iomap() on multiple BARs

REGULATOR
  devm_regulator_get()
  devm_regulator_put()
  devm_regulator_bulk_get()
  devm_regulator_register()

CLOCK
  devm_clk_get()
  devm_clk_put()

PINCTRL
  devm_pinctrl_get()
  devm_pinctrl_put()

PWM
  devm_pwm_get()
  devm_pwm_put()

PHY
  devm_usb_get_phy()
  devm_usb_put_phy()

SLAVE DMA ENGINE
  devm_acpi_dma_controller_register()

SPI
  devm_spi_register_master()

内核提供了devres_xxx的机制,并基于devres_xxx又给出了devres group机制。devres group主要用于处理初始化的时候,有多种资源类型需要初始化,每种资源类型的初始化又由多个devres_xxx资源申请组成的情况,将这些devres_xxx按类别组合成group,这样在需要显示释放某一类的资源时,调用devres group的api即可实现。内核给出的例子:

代码语言:javascript
复制
if (!devres_open_group(dev, NULL, GFP_KERNEL))//启动group
    return -ENOMEM;

  acquire A;//申请资源A
  if (failed)
    goto err;

  acquire B;//申请资源B
  if (failed)
    goto err;
  ...

  devres_remove_group(dev, NULL);//如果一切顺利,那么关掉group
  return 0;

 err:
  devres_release_group(dev, NULL);//如果出错,那么释放掉启动group后所有申请的资源
  return err_code;

实现原理

具体的实现很简单,当然我们应该也能猜测到。在分配内存的时候,会分配比我们要求大的空间,空间的前面部分用于存放实现devres机制的数据结构,然后返回的是用户期望的空间的指针(该指针是实际分配的空间指针的devres结构的偏移)。

代码语言:javascript
复制
struct devres_node {
    struct list_head        entry;//通过该成员,挂接到device的devres链表上
    dr_release_t            release;//对应的资源释放回调
};

struct devres {
    struct devres_node      node;
    /* -- 3 pointers */
    unsigned long long      data[]; /* guarantee ull alignment *///实际的数据部分
};

devres采用零长数组的方式实现。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • devres使用
  • 实现原理
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档