内存申请标记注意区分___GFP_HIGH和___GFP_HIGHMEM

背景

经常在看内存管理这块的代码时会看到这两个标记,有时候稍微不注意就会把他们搞混了,本篇博客就来聊聊他们的区别。

定义

首先这两个标记的定义如下,由此可见他们两个是不同的两个标记,表示的当然也是不同的意义:

#define ___GFP_HIGH     0x20u
#define ___GFP_HIGHMEM      0x02u

对于___GFP_HIGHMEM 标记来说,它是用来在内存申请时确定要从哪个目标zone中申请内存的。具体可以参考我的博文:
《如何从GFP确定最后申请的内存来自哪个zone?》

那么对于___GFP_HIGH 这个标记来说,申请内存时传入该标记的意义在于申请内存时,选择更加激进的策略来申请。

使用原理

我们看下它的原理,内存申请时需要传递alloc_flags,这个标志alloc_flags是从gfp_mask转换而来的:

2826 static inline int
2827 gfp_to_alloc_flags(gfp_t gfp_mask)
2828 {
2829     int alloc_flags = ALLOC_WMARK_MIN | ALLOC_CPUSET;
2830     const bool atomic = !(gfp_mask & (__GFP_WAIT | __GFP_NO_KSWAPD));
2831 
2832     /* __GFP_HIGH is assumed to be the same as ALLOC_HIGH to save a branch. */
2833     BUILD_BUG_ON(__GFP_HIGH != (__force gfp_t) ALLOC_HIGH);
2834 
2835     /*
2836      * The caller may dip into page reserves a bit more if the caller
2837      * cannot run direct reclaim, or if the caller has realtime scheduling
2838      * policy or is asking for __GFP_HIGH memory.  GFP_ATOMIC requests will
2839      * set both ALLOC_HARDER (atomic == true) and ALLOC_HIGH (__GFP_HIGH).
2840      */
2841     alloc_flags |= (__force int) (gfp_mask & __GFP_HIGH);
2842 
...

可以看到alloc_flags |= (__force int) (gfp_mask & __GFP_HIGH); 这一条就是设置ALLOC_HIGH申请标志的,因为ALLOC_HIGH和__GFP_HIGH的定义值是相等的:

#define ALLOC_HIGH      0x20 /* __GFP_HIGH set */   

设置了这个alloc_flags,在哪里生效呢?也就是在申请内存时选择了特定的zone,在判断该zone的剩余空闲内存是否允许被申请时做判断使用的:

*/
2079 static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,                                                                                                                  
2080               int classzone_idx, int alloc_flags, long free_pages)
2081 {
2082     /* free_pages my go negative - that's OK */
2083     long min = mark;
2084     long lowmem_reserve = z->lowmem_reserve[classzone_idx];
2085     int o;
2086     long free_cma = 0;
2087 
2088     free_pages -= (1 << order) - 1;
2089     if (alloc_flags & ALLOC_HIGH)
2090         min -= min / 2;
2091     if (alloc_flags & ALLOC_HARDER)
2092         min -= min / 4;
2093  #ifdef CONFIG_CMA
2094     /* If allocation can't use CMA areas don't use free CMA pages */
2095     if (!(alloc_flags & ALLOC_CMA))
2096         free_cma = zone_page_state(z, NR_FREE_CMA_PAGES);
2097 #endif
2098 
2099     if (free_pages - free_cma <= min + lowmem_reserve)
2100         return false;

截取部分关键代码,这里在判断zone中是否有足够空闲内存时,在计算预留内存水位时会根据此申请标记为来做修改,当标记位存在时,水位值会修改为当前的一半再去判断,也就是说预留内存更少了,那么只要free大于预留内存(min + lowmem_reserve)就可以申请到内存。因而简单的换一种说法就是,当使用___GFP_HIGH申请内存时,将会更加容易申请到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值