【原創】(十六)Linux記憶體管理之CMA

来源:https://www.cnblogs.com/LoyenWang/archive/2020/01/12/12182594.html
-Advertisement-
Play Games

背景 By 魯迅 By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器,Contex A53,雙核 3. 使用工具:Source Insight 3.5, Visio 1. 概述 ,連續記憶體分配器,用於分配連續的大塊記憶體。 ,會Reserve一片物理記憶體區域: 1. 設備驅 ...


背景

  • Read the fucking source code! --By 魯迅
  • A picture is worth a thousand words. --By 高爾基

說明:

  1. Kernel版本:4.14
  2. ARM64處理器,Contex-A53,雙核
  3. 使用工具:Source Insight 3.5, Visio

1. 概述

Contiguous Memory Allocator, CMA,連續記憶體分配器,用於分配連續的大塊記憶體。
CMA分配器,會Reserve一片物理記憶體區域:

  1. 設備驅動不用時,記憶體管理系統將該區域用於分配和管理可移動類型頁面;
  2. 設備驅動使用時,用於連續記憶體分配,此時已經分配的頁面需要進行遷移;

此外,CMA分配器還可以與DMA子系統集成在一起,使用DMA的設備驅動程式無需使用單獨的CMA API

2. 數據結構

內核定義了struct cma結構,用於管理一個CMA區域,此外還定義了全局的cma數組,如下:

struct cma {
    unsigned long   base_pfn;
    unsigned long   count;
    unsigned long   *bitmap;
    unsigned int order_per_bit; /* Order of pages represented by one bit */
    struct mutex    lock;
#ifdef CONFIG_CMA_DEBUGFS
    struct hlist_head mem_head;
    spinlock_t mem_head_lock;
#endif
    const char *name;
};

extern struct cma cma_areas[MAX_CMA_AREAS];
extern unsigned cma_area_count;
  • base_pfn:CMA區域物理地址的起始頁幀號;
  • count:CMA區域總體的頁數;
  • *bitmap:點陣圖,用於描述頁的分配情況;
  • order_per_bit:點陣圖中每個bit描述的物理頁面的order值,其中頁面數為2^order值;

來一張圖就會清晰明瞭:

3. 流程分析

3.1 CMA區域創建

3.1.1 方式一 根據dts來配置

之前的文章也都分析過,物理記憶體的描述放置在dts中,最終會在系統啟動過程中,對dtb文件進行解析,從而完成記憶體信息註冊。

CMA的記憶體在dts中的描述示例如下圖:

dtb解析過程中,會調用到rmem_cma_setup函數:

RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);

3.1.2 方式二 根據參數或巨集配置

可以通過內核參數或配置巨集,來進行CMA區域的創建,最終會調用到cma_declare_contiguous函數,如下圖:

3.2 CMA添加到Buddy System

在創建完CMA區域後,該記憶體區域成了保留區域,如果單純給驅動使用,顯然會造成記憶體的浪費,因此記憶體管理模塊會將CMA區域添加到Buddy System中,用於可移動頁面的分配和管理。CMA區域是通過cma_init_reserved_areas介面來添加到Buddy System中的。

core_initcall(cma_init_reserved_areas);

core_initcall巨集將cma_init_reserved_areas函數放置到特定的段中,在系統啟動的時候會調用到該函數。

3.3 CMA分配/釋放

  • CMA分配,入口函數為cma_alloc

  • CMA釋放,入口函數為cma_release
    函數比較簡單,直接貼上代碼
/**
 * cma_release() - release allocated pages
 * @cma:   Contiguous memory region for which the allocation is performed.
 * @pages: Allocated pages.
 * @count: Number of allocated pages.
 *
 * This function releases memory allocated by alloc_cma().
 * It returns false when provided pages do not belong to contiguous area and
 * true otherwise.
 */
bool cma_release(struct cma *cma, const struct page *pages, unsigned int count)
{
    unsigned long pfn;

    if (!cma || !pages)
        return false;

    pr_debug("%s(page %p)\n", __func__, (void *)pages);

    pfn = page_to_pfn(pages);

    if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
        return false;

    VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);

    free_contig_range(pfn, count);
    cma_clear_bitmap(cma, pfn, count);
    trace_cma_release(pfn, pages, count);

    return true;
}

3.4 DMA使用

代碼參考driver/base/dma-contiguous.c,主要包括的介面有:

/**
 * dma_alloc_from_contiguous() - allocate pages from contiguous area
 * @dev:   Pointer to device for which the allocation is performed.
 * @count: Requested number of pages.
 * @align: Requested alignment of pages (in PAGE_SIZE order).
 * @gfp_mask: GFP flags to use for this allocation.
 *
 * This function allocates memory buffer for specified device. It uses
 * device specific contiguous memory area if available or the default
 * global one. Requires architecture specific dev_get_cma_area() helper
 * function.
 */
struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
                       unsigned int align, gfp_t gfp_mask);
 
 /**
 * dma_release_from_contiguous() - release allocated pages
 * @dev:   Pointer to device for which the pages were allocated.
 * @pages: Allocated pages.
 * @count: Number of allocated pages.
 *
 * This function releases memory allocated by dma_alloc_from_contiguous().
 * It returns false when provided pages do not belong to contiguous area and
 * true otherwise.
 */
bool dma_release_from_contiguous(struct device *dev, struct page *pages,
                 int count);

在上述的介面中,實際調用的就是cma_alloc/cma_release介面來實現的。

整體來看,CMA分配器還是比較簡單易懂,也不再深入分析。

4.後記

記憶體管理的分析先告一段落,後續可能還會針對某些模塊進一步的研究與完善。
記憶體管理子系統,極其複雜,盤根錯節,很容易就懵圈了,儘管費了不少心力,也只能說略知皮毛。
學習就像是爬山,面對一座高山,可能會有心理障礙,但是當你跨越之後,再看到同樣高的山,心理上你將不再畏懼。

接下來將研究進程管理子系統,將任督二脈打通。

未來會持續分析內核中的各類框架,併發機制等,敬請關註,一起探討。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言:當WPF項目後臺完成到一定程度的時候,就可以對XAML前端進行美化啦,個人認為XAML前端還是挺有意思的。 下麵舉一個Button加過小圖標後的例子: 是不是比生硬的文字看來更人性化了呢? 不多bb下麵開始講如何實現: 首先把你的圖標圖片文件放入項目,我的存放的是項目的根目錄的Images文件 ...
  • 之前多次安裝MongoDB失敗,今天終於配置安裝成功了!!! 首先,介紹一下:MongoDB是一個基於分散式文件存儲的NoSQL資料庫。由 C++ 語言編寫。旨在為 WEB 應用提供可擴展的高性能數據存儲解決方案。 MongoDB的主要目標是在鍵/值存儲方式(提供了高性能和高度伸縮性)以及傳統的RD ...
  • 前提 cat命令是用於連接文件並輸出到標準輸出設備或指定文件中。 EOF為標誌,可以替換為其他字元串 代碼塊 將文件內容作為標準輸出也就是將文件內容輸出到屏幕中,也可寫作 cat filename cat filename 創建文件,將2個EOF中的字元串作為標準輸入輸出到filename文件中 c ...
  • 前提 AWK是一種處理文本文件的語言,是一個強大的文本分析工具。 本文將使用命令awk將具有某個關鍵字的段落提取出來。 準備數據 段落提取 假設我們需要的關鍵字為 nid=0x63ef ...
  • 部署圖書管理系統項目 部署準備 部署圖書管理項目你將使用以下軟體 nginx uWSGI CentOS7 部署圖書管理項目文件 virtualenv supervisor WSGI、uWSGI python web伺服器開發使用WSGI協議(Web Server Gateway Interface) ...
  • ArchLinux下electronssr無法啟動的解決措施 今天重新配置electron ssr時發現閃退(無法啟動)。 於是開始查錯 首先是找到了目錄位置 /usr/electron ssr/electron ssr 並且嘗試在終端里啟動它。 發現缺少 python2 , 安裝 python2 ...
  • 最近在滴滴雲上看到伺服器很便宜,1核2G,1年只需要68塊錢。下麵是我基於Docker部署Javaweb服務的過程。目前我見過的最便宜的伺服器,阿裡雲打折的時候都沒有這麼便宜啊,果斷入手。有需要的話可以通過下麵鏈接購買。 滴滴雲全線標準型雲伺服器限時特惠,新購雲服務包1個月5折,包3個月4折,包6個 ...
  • 部署gitlab 1、配置倉庫源 # vim /etc/apt/sources.listdeb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src http://mirrors.al ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...