summaryrefslogtreecommitdiffstats
path: root/mm/hugetlb.c
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@engr.sgi.com>2006-01-06 00:10:45 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 08:33:23 -0800
commit96df9333c94d7d5aeceb21f6c5e7ae8ff34753cf (patch)
treea4ac0486af418df0194ed0038b87459652d61945 /mm/hugetlb.c
parent1e8f889b10d8d2223105719e36ce45688fedbd59 (diff)
downloadlinux-96df9333c94d7d5aeceb21f6c5e7ae8ff34753cf.tar.gz
linux-96df9333c94d7d5aeceb21f6c5e7ae8ff34753cf.tar.bz2
linux-96df9333c94d7d5aeceb21f6c5e7ae8ff34753cf.zip
[PATCH] mm: dequeue a huge page near to this node
This was discussed at http://marc.theaimsgroup.com/?l=linux-kernel&m=113166526217117&w=2 This patch changes the dequeueing to select a huge page near the node executing instead of always beginning to check for free nodes from node 0. This will result in a placement of the huge pages near the executing processor improving performance. The existing implementation can place the huge pages far away from the executing processor causing significant degradation of performance. The search starting from zero also means that the lower zones quickly run out of memory. Selecting a huge page near the process distributed the huge pages better. Signed-off-by: Christoph Lameter <clameter@sgi.com> Cc: 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>
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r--mm/hugetlb.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index da8a211414c9..e93bd63462f0 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -40,14 +40,16 @@ static struct page *dequeue_huge_page(void)
{
int nid = numa_node_id();
struct page *page = NULL;
+ struct zonelist *zonelist = NODE_DATA(nid)->node_zonelists;
+ struct zone **z;
- if (list_empty(&hugepage_freelists[nid])) {
- for (nid = 0; nid < MAX_NUMNODES; ++nid)
- if (!list_empty(&hugepage_freelists[nid]))
- break;
+ for (z = zonelist->zones; *z; z++) {
+ nid = (*z)->zone_pgdat->node_id;
+ if (!list_empty(&hugepage_freelists[nid]))
+ break;
}
- if (nid >= 0 && nid < MAX_NUMNODES &&
- !list_empty(&hugepage_freelists[nid])) {
+
+ if (*z) {
page = list_entry(hugepage_freelists[nid].next,
struct page, lru);
list_del(&page->lru);