kvmalloc函數

来源:https://www.cnblogs.com/linhaostudy/archive/2020/06/10/13088364.html
-Advertisement-
Play Games

你應該曾經糾結過是用kmalloc(),還是vmalloc()?現在你不用那麼糾結了,因為內核裡面現在有個API叫kvmalloc(),可以認為是kmalloc()和vmalloc()的雙劍合一。屠龍刀和倚天劍的合體。 內核裡面有大量的代碼現在都使用了kvmalloc(),譬如: source/ip ...


你應該曾經糾結過是用kmalloc(),還是vmalloc()?現在你不用那麼糾結了,因為內核裡面現在有個API叫kvmalloc(),可以認為是kmalloc()和vmalloc()的雙劍合一。屠龍刀和倚天劍的合體。

內核裡面有大量的代碼現在都使用了kvmalloc(),譬如:

source/ipc/msg.c

static int newque(struct ipc_namespace *ns, struct ipc_params *params)
{
  struct msg_queue *msq;
  int retval;
  key_t key = params->key;
  int msgflg = params->flg;

  msq = kvmalloc(sizeof(*msq), GFP_KERNEL);
  if (unlikely(!msq))
    return -ENOMEM;

  ...
}

這個代碼在早期的內核裡面是(比如v4.0-rc7/source/ipc/msg.c):

static int newque(struct ipc_namespace *ns, struct ipc_params *params)
{
  struct msg_queue *msq;
  int id, retval;
  key_t key = params->key;
  int msgflg = params->flg;

  msq = ipc_rcu_alloc(sizeof(*msq));
  if (!msq)
    return -ENOMEM;

 ...

}

看起來是用的這個函數申請記憶體:

ipc_rcu_alloc(sizeof(*msq))

那麼這個ipc_rc_alloc()是怎麼回事呢?

void *ipc_alloc(int size)
{
  void *out;
  if (size > PAGE_SIZE)
    out = vmalloc(size);
  else
    out = kmalloc(size, GFP_KERNEL);
  return out;
}

邏輯上是,大於一頁的時候用vmalloc(),小於等於1頁用kmalloc()。

而kvmalloc()的實現代碼裡面則對類似邏輯進行了非常智能地處理:

void *kvmalloc_node(size_t size, gfp_t flags, int node)
{
  gfp_t kmalloc_flags = flags;
  void *ret;

  /*
   * vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables)
   * so the given set of flags has to be compatible.
   */
  if ((flags & GFP_KERNEL) != GFP_KERNEL)
    return kmalloc_node(size, flags, node);

  /*
   * We want to attempt a large physically contiguous block first because
   * it is less likely to fragment multiple larger blocks and therefore
   * contribute to a long term fragmentation less than vmalloc fallback.
   * However make sure that larger requests are not too disruptive - no
   * OOM killer and no allocation failure warnings as we have a fallback.
   */
  if (size > PAGE_SIZE) {
    kmalloc_flags |= __GFP_NOWARN;

    if (!(kmalloc_flags & __GFP_RETRY_MAYFAIL))
      kmalloc_flags |= __GFP_NORETRY;
  }

  ret = kmalloc_node(size, kmalloc_flags, node);

  /*
   * It doesn't really make sense to fallback to vmalloc for sub page
   * requests
   */
  if (ret || size <= PAGE_SIZE)
    return ret;

  return __vmalloc_node_flags_caller(size, node, flags,
      __builtin_return_address(0));
}
EXPORT_SYMBOL(kvmalloc_node);

static inline void *kvmalloc(size_t size, gfp_t flags)
{
  return kvmalloc_node(size, flags, NUMA_NO_NODE);
}

大於一個page的時候,會先用kmalloc()進行__GFP_NORETRY的嘗試,如果嘗試失敗就fallback到vmalloc(NORETRY標記避免了kmalloc在申請記憶體失敗地情況下,反覆嘗試甚至做OOM來獲得記憶體)。

當然,kvmalloc()的size如果小於1個page,則沿用老的kmalloc()邏輯,而且也不會設置__GFP_NORETRY,如果反覆嘗試失敗的話,也不會fallback到vmalloc(),因為vmalloc()申請小於1個page的記憶體是不合適的。


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

-Advertisement-
Play Games
更多相關文章
  • 後臺修改前臺不刷新可能的原因: 1.前臺頁面沒有寫Binding 2.後臺數據定義的欄位沒有get和set 3.數據容器沒有使用ObservableCollection 4.欄位內容修改時沒有重置數據源 首先簡單舉例界面代碼如下: <DataGrid Name="DG" ItemsSource="{ ...
  • 隨著微服務的火熱,DDD(領域驅動設計模式)思想風起雲涌,衝擊著整個軟體生態系統。其中,事件匯流排那是必須知道的了,於是我便抱著一個學習DDD的心態搭建了一個博客網站,目前該網站正在建設階段,後續會不斷完善,這裡我只是講一下我裡面所用到的事件匯流排。 事件匯流排,我的理解就是發佈訂閱模式,這裡有一篇文章寫 ...
  • 使用請求頭認證來測試需要授權的 API 介面 Intro 有一些需要認證授權的介面在寫測試用例的時候一般會先獲取一個 token,然後再去調用介面,其實這樣做的話很不靈活,一方面是存在著一定的安全性問題,獲取 token 可能會有一些用戶名密碼之類的測試數據,還有就是獲取 token 的話如果全局使 ...
  • 系列文章 基於 abp vNext 和 .NET Core 開發博客項目 - 使用 abp cli 搭建項目 基於 abp vNext 和 .NET Core 開發博客項目 - 給項目瘦身,讓它跑起來 基於 abp vNext 和 .NET Core 開發博客項目 - 完善與美化,Swagger登場 ...
  • 《C# 敏捷開發實踐》 [作者] (英) Gary McLean Hall[譯者] (中) 許順強[出版] 人民郵電出版社[版次] 2016年07月 第1版[印次] 2016年07月 第1次 印刷[定價] 69.00元 【第一部分】 (P001) 編寫代碼是軟體開發的核心工作,而編寫好用的代碼有很多 ...
  • API是什麼,Linux系統中系統調用可以理解是操作系統為用戶提供的一系列操作的介面(API), 以C語言為例,我們使用fopen()函數可以打開一個文件,感覺非常簡單。文件保存在硬碟上,要經過複雜的處理才能顯示,這些細節對我們來說是透明的,由操作系統完成。也就是說,我們調用fopen()函數來通知 ...
  • Docker簡介;Docker與虛擬機區別;Docker的優點及內部組件說明;如何安裝Docker與鏡像加速配置。 ...
  • 一個有趣的結論,Cortex-M7上將函數鏈接到8位元組對齊的地址有利於指令雙發射,這就是進一步提升代碼執行性能的秘密 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...