我可以在Linux内核中知道GFP_HARDWALL标志的目的是什么?

时间:2013-10-24 12:38:22

标签: linux-kernel kernel

GFP标志用于内存分配。 Linux内核中GFP_HARDWALL标志的用途是什么?

2 个答案:

答案 0 :(得分:6)

它限制了对当前cpuset的分配,其中cpuset是一个(猜测!)CPU和内存节点集。

基本上,您的用户进程可能被限制在由CPU#1和CPU#2组成的cpuset中,但不包括CPU#3和CPU#4。也许有一些内存MEM#1是CPU#1和#2的本地内存而不是其他内存,所以这个内存是cpuset的一部分。也许在CPU#3和#4本地有一些其他内存MEM#2,所以这个不是cpuset的一部分。

__ GFP_HARDWALL确保您无法从MEM#2分配。

答案 1 :(得分:3)

我无法确定。你可能指的是__GFP_HARDWALL这是一个你不应该看的内部符号。不过,这是我的发现。

来自include/linux/gfp.h

评论#define __GFP_HARDWALL

  

/ *强制执行hardwall cpuset内存分配* /

并不是说我真的明白硬语在那句话中意味着什么,但你可能会这样。 __GFP_HARDWALLGFP_USERGFP_HIGHUSER以及GFP_HIGHUSER_MOVABLE的定义中使用了GFP_CONSTRAINT_MASK。从前三个开始,我猜它与用户空间有关。

来自kernel/cpuset.c

__cpuset_node_allowed_softwall函数的评论(部分省略):

* cpuset_node_allowed_softwall - Can we allocate on a memory node?
* ...
* If we're in interrupt, yes, we can always allocate. If __GFP_THISNODE is
* set, yes, we can always allocate. If node is in our task's mems_allowed,
* yes. If it's not a __GFP_HARDWALL request and this node is in the nearest
* hardwalled cpuset ancestor to this task's cpuset, yes. If the task has been
* OOM killed and has access to memory reserves as specified by the TIF_MEMDIE
* flag, yes.
* Otherwise, no.
*
* If __GFP_HARDWALL is set, cpuset_node_allowed_softwall() reduces to
* cpuset_node_allowed_hardwall(). Otherwise, cpuset_node_allowed_softwall()
* might sleep, and might allow a node from an enclosing cpuset.
*
* cpuset_node_allowed_hardwall() only handles the simpler case of hardwall
* cpusets, and never sleeps.
*
* <OMITTED>
*
* GFP_USER allocations are marked with the __GFP_HARDWALL bit,
* and do not allow allocations outside the current tasks cpuset
* unless the task has been OOM killed as is marked TIF_MEMDIE.
* GFP_KERNEL allocations are not so marked, so can escape to the
* nearest enclosing hardwalled ancestor cpuset.
*
* Scanning up parent cpusets requires callback_mutex. The
* __alloc_pages() routine only calls here with __GFP_HARDWALL bit
* _not_ set if it's a GFP_KERNEL allocation, and all nodes in the
* current tasks mems_allowed came up empty on the first pass over
* the zonelist. So only GFP_KERNEL allocations, if all nodes in the
* cpuset are short of memory, might require taking the callback_mutex
* mutex.
*
* The first call here from mm/page_alloc:get_page_from_freelist()
* has __GFP_HARDWALL set in gfp_mask, enforcing hardwall cpusets,
* so no allocation on a node outside the cpuset is allowed (unless
* in interrupt, of course).
*
* <OMITTED>
*
* Rule:
* Don't call cpuset_node_allowed_softwall if you can't sleep, unless you
* pass in the __GFP_HARDWALL flag set in gfp_flag, which disables
* the code that might scan up ancestor cpusets and sleep.

在同一个文件中,还有对hardwall cpuset和hardwall内存的引用。仍然不确定硬墙到底意味着什么,但让我们按照它进行cpuset。

(在 tile 架构中有很多提到硬墙,但由于这是唯一一个,我相信它与我们在这里谈论的内容无关。)

我中了大奖。 documentation on cpusets说:

  

1.4什么是独家cpusets?

     

如果cpuset是cpu或mem独占,除了以外没有其他cpuset   直接祖先或后代,可以共享任何相同的CPU或   记忆节点。

     

cpuset是cpuset.mem_exclusive cpuset.mem_hardwall是“硬墙”,   即它限制页面,缓冲区和其他数据的内核分配   通常由内核在多个用户之间共享。所有的cpusets,   无论是否硬座,都限制用户的内存分配   空间。这样就可以配置一个独立的系统   作业可以共享公共内核数据,例如文件系统页面   隔离每个作业在其自己的cpuset中的用户分配。去做这个,   构造一个大的mem_exclusive cpuset来保存所有的作业,和   为每个单独的工作构造子,非mem_exclusive cpusets。   只有少量典型的内核内存,比如来自的请求   中断处理程序,甚至允许在外面处理   mem_exclusive cpuset。

我打算离开你,因为我做出的任何结论实际上可能都是错误的。希望在这个特定领域更有知识的人会来到我们身边并启发我们。