[PATCH] Add NUMA policy support for huge pages.
The huge_zonelist() function in the memory policy layer provides an list of zones ordered by NUMA distance. The hugetlb layer will walk that list looking for a zone that has available huge pages but is also in the nodeset of the current cpuset. This patch does not contain the folding of find_or_alloc_huge_page() that was controversial in the earlier discussion. Signed-off-by: Christoph Lameter <clameter@sgi.com> Cc: Andi Kleen <ak@muc.de> Acked-by: William Lee Irwin III <wli@holomorphy.com> Cc: Adam Litke <agl@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:

کامیت شده توسط
Linus Torvalds

والد
96df9333c9
کامیت
5da7ca8607
@@ -785,6 +785,34 @@ static unsigned offset_il_node(struct mempolicy *pol,
|
||||
return nid;
|
||||
}
|
||||
|
||||
/* Determine a node number for interleave */
|
||||
static inline unsigned interleave_nid(struct mempolicy *pol,
|
||||
struct vm_area_struct *vma, unsigned long addr, int shift)
|
||||
{
|
||||
if (vma) {
|
||||
unsigned long off;
|
||||
|
||||
off = vma->vm_pgoff;
|
||||
off += (addr - vma->vm_start) >> shift;
|
||||
return offset_il_node(pol, vma, off);
|
||||
} else
|
||||
return interleave_nodes(pol);
|
||||
}
|
||||
|
||||
/* Return a zonelist suitable for a huge page allocation. */
|
||||
struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr)
|
||||
{
|
||||
struct mempolicy *pol = get_vma_policy(current, vma, addr);
|
||||
|
||||
if (pol->policy == MPOL_INTERLEAVE) {
|
||||
unsigned nid;
|
||||
|
||||
nid = interleave_nid(pol, vma, addr, HPAGE_SHIFT);
|
||||
return NODE_DATA(nid)->node_zonelists + gfp_zone(GFP_HIGHUSER);
|
||||
}
|
||||
return zonelist_policy(GFP_HIGHUSER, pol);
|
||||
}
|
||||
|
||||
/* Allocate a page in interleaved policy.
|
||||
Own path because it needs to do special accounting. */
|
||||
static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
|
||||
@@ -833,15 +861,8 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
|
||||
|
||||
if (unlikely(pol->policy == MPOL_INTERLEAVE)) {
|
||||
unsigned nid;
|
||||
if (vma) {
|
||||
unsigned long off;
|
||||
off = vma->vm_pgoff;
|
||||
off += (addr - vma->vm_start) >> PAGE_SHIFT;
|
||||
nid = offset_il_node(pol, vma, off);
|
||||
} else {
|
||||
/* fall back to process interleaving */
|
||||
nid = interleave_nodes(pol);
|
||||
}
|
||||
|
||||
nid = interleave_nid(pol, vma, addr, PAGE_SHIFT);
|
||||
return alloc_page_interleave(gfp, 0, nid);
|
||||
}
|
||||
return __alloc_pages(gfp, 0, zonelist_policy(gfp, pol));
|
||||
|
مرجع در شماره جدید
Block a user