日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

宋宝华: kvmalloc ——倚天剑屠龙刀两大神器合体?

發布時間:2023/12/20 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 宋宝华: kvmalloc ——倚天剑屠龙刀两大神器合体? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

你應該曾經糾結過是用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);elseout = 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的內存是不合適的。

可觀看我今天的技術分享小視頻:

凡事都沒有絕對的,當咱們還在糾結是kmalloc()還是vmalloc()的時候,人家已經造出了kvmalloc()。咱的糾結,相對于人家的創造,是不是有一種要鉆進去地洞的感覺?思考是最重要的,腦洞要開地大一點,被動地學習永遠只是追著別人的腦子跑。?

(END)

更多精彩,盡在"Linux閱碼場",掃描下方二維碼關注

您的鼓勵是我們前行的動力

總結

以上是生活随笔為你收集整理的宋宝华: kvmalloc ——倚天剑屠龙刀两大神器合体?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。