• linux-cma&ion


    cma

    Linux 内存管理之CMA - 腾讯云开发者社区-腾讯云

    Linux内核最新的连续内存分配器(CMA)——避免预留大块内存【转】 - 腾讯云开发者社区-腾讯云

    CMA区域添加到Buddy System

    kernel-4.19/mm/cma.c 


    103  static int __init cma_activate_area(struct cma *cma)
    104  {

                ####表示需要多少位来表示页面数
    105      int bitmap_size = BITS_TO_LONGS(cma_bitmap_maxno(cma)) * sizeof(long);
    106      unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;

                ####表示多少个块
    107      unsigned i = cma->count >> pageblock_order;
    108      struct zone *zone;
    109  
    110      cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
    111  
    112      if (!cma->bitmap) {
    113          cma->count = 0;
    114          return -ENOMEM;
    115      }
    116  
    117      WARN_ON_ONCE(!pfn_valid(pfn));
    118      zone = page_zone(pfn_to_page(pfn));
    119  
    120      do {
    121          unsigned j;
    122  
    123          base_pfn = pfn;
    124          for (j = pageblock_nr_pages; j; --j, pfn++) {
    125              WARN_ON_ONCE(!pfn_valid(pfn));
    126              /*
    127               * alloc_contig_range requires the pfn range
    128               * specified to be in the same zone. Make this
    129               * simple by forcing the entire CMA resv range
    130               * to be in the same zone.
    131               */
    132              if (page_zone(pfn_to_page(pfn)) != zone)
    133                  goto not_in_zone;
    134          }
    135          init_cma_reserved_pageblock(pfn_to_page(base_pfn));
    136      } while (--i);
    137  
    138      mutex_init(&cma->lock);
    139  
    140  #ifdef CONFIG_CMA_DEBUGFS
    141      INIT_HLIST_HEAD(&cma->mem_head);
    142      spin_lock_init(&cma->mem_head_lock);
    143  #endif
    144  
    145      return 0;
    146  
    147  not_in_zone:
    148      pr_err("CMA area %s could not be activated\n", cma->name);
    149      kfree(cma->bitmap);
    150      cma->count = 0;
    151      return -EINVAL;
    152  }
    153  

    ION

    【内存管理】ION内存管理器浅析(system heap)(基于linux 4.14) - yibuyibu01 - 博客园


      #if TARGET_ION_ABI_VERSION >= 2
                  mIonDeviceFd = ion_open();
      #else
                  mIonDeviceFd = open("/dev/ion", O_RDONLY);
      #endif
      
      
            int32_t ret = 0;
    289          unsigned char *v_addr;
    290          int32_t map_fd = -1;
    291          struct dma_buf_sync buf_sync;
    292          uint32_t len = PAGE_ALIGN(size);
    293          uint32_t align = 0;
    294          uint32_t flags = 0;
    295          unsigned int heap_id = ION_QSECOM_HEAP_ID;
    296          ret = ion_alloc_fd(mIonDeviceFd, len, align, ION_HEAP(heap_id), flags, &map_fd);
    297  
    298          if (ret) {
    299              LOG_E(LOG_TAG,
    300                    "[%s] Error::ion_alloc_fd for heap %u size %u len %u failed ret = %d, errno = %d\n",
    301                    __func__, heap_id, size, len, ret, errno);
    302              err = GF_ERROR_GENERIC;
    303              goto alloc_fail;
    304          }
    305  
    306          v_addr = (unsigned char *)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
    307                                         map_fd, 0);
    308  
    309          if (v_addr == MAP_FAILED) {
    310              LOG_E(LOG_TAG, "[%s] Error::mmap failed", __func__);
    311              err = GF_ERROR_GENERIC;
    312              goto map_fail;
    313          }
    314  
    315          pExtInfo->base.bufferFd = map_fd;  // map fd
    316          pExtInfo->base.buffer = v_addr;  // mmap virtual addr
    317          pExtInfo->bufferSize = len;  // mmap virtual buffer size
    318          buf_sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
    319          ret = ioctl(map_fd, DMA_BUF_IOCTL_SYNC, &buf_sync);
    320  
    321          if (ret) {
    322              LOG_E(LOG_TAG,
    323                    "[%s] Error:: DMA_BUF_IOCTL_SYNC start failed, ret = %d, errno = %d\n",
    324                    __func__, ret, errno);
    325              err = GF_ERROR_GENERIC;
    326              goto sync_fail;
    327          }
    328  
    329          return err;
    330  sync_fail:
    331  
    332          if (v_addr) {
    333              munmap(v_addr, len);
    334          }
    335  
    336  map_fail:
    337  
    338          if (map_fd > 0) {
    339              ion_close(map_fd);
    340          }
    341  
    342  alloc_fail:
    343  
    344          if (mIonDeviceFd > 0) {
    345              ion_close(mIonDeviceFd);
    346              mIonDeviceFd = 0;
    347          }
    348  

    system/memory/libion/ion.c

    160  int ion_alloc_fd(int fd, size_t len, size_t align, unsigned int heap_mask, unsigned int flags,
    161                   int* handle_fd) {
    162      ion_user_handle_t handle;
    163      int ret;
    164  
    165      if (!handle_fd) return -EINVAL;
    166  
    167      if (!ion_is_legacy(fd)) {
    168          struct ion_new_allocation_data data = {
    169              .len = len,
    170              .heap_id_mask = heap_mask,
    171              .flags = flags,
    172          };
    173  
    174          ret = ion_ioctl(fd, ION_IOC_NEW_ALLOC, &data);
    175          if (ret < 0) return ret;
    176          *handle_fd = data.fd;
    177      } else {
    178          ret = ion_alloc(fd, len, align, heap_mask, flags, &handle);
    179          if (ret < 0) return ret;
    180          ret = ion_share(fd, handle, handle_fd);
    181          ion_free(fd, handle);
    182      }
    183      return ret;
    184  }

    kernel-4.19/drivers/staging/android/aosp_ion/

  • 相关阅读:
    从零开始搭建仿抖音短视频APP-构建后端项目
    小程序学习
    asp.net core session的使用
    【STM32学习(1)】详解STM32时钟体系
    函数栈简述
    IBM websphere通道联通搭建和测试
    反射、枚举、lambda表达式
    Win11系统提示backgroundtaskhost.exe系统错误解决方法
    京东云开发者|探寻软件架构的本质,到底什么是架构?
    字符串去掉()以及()中的文字
  • 原文地址:https://blog.csdn.net/lei7143/article/details/126118111