zoukankan      html  css  js  c++  java
  • devm_xxx机制

    前言

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

    devres使用

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

    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即可实现。内核给出的例子:

      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结构的偏移)。

    
    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采用零长数组的方式实现。

    参考

    完!
    2014年6月

  • 相关阅读:
    最简单方式理解为什么MongoDB索引选择B-树,而 Mysql 选择B+树
    单点登录基本原理
    我是这样理解HTTP和HTTPS区别的
    数据库mvvc的简单理解
    mysql数据库一些知识点
    一条SQL完成跨数据库实例Join查询
    api接口安全性设计
    Redis-Scan命令
    分布式缓存的基本原理
    记录主从延迟造成数据查询不准确的问题
  • 原文地址:https://www.cnblogs.com/rongpmcu/p/7662736.html
Copyright © 2011-2022 走看看