diff options
author | Mel Gorman <mel@csn.ul.ie> | 2009-06-16 18:31:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 22:47:32 -0400 |
commit | 6484eb3e2a81807722c5f28efef94d8338b7b996 (patch) | |
tree | 10ce36f412c2ff0c7eb399af1a189f8e354f56db | |
parent | b3c466ce512923298ae8c0121d3e9f397a3f1210 (diff) |
page allocator: do not check NUMA node ID when the caller knows the node is valid
Callers of alloc_pages_node() can optionally specify -1 as a node to mean
"allocate from the current node". However, a number of the callers in
fast paths know for a fact their node is valid. To avoid a comparison and
branch, this patch adds alloc_pages_exact_node() that only checks the nid
with VM_BUG_ON(). Callers that know their node is valid are then
converted.
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
Reviewed-by: Christoph Lameter <cl@linux-foundation.org>
Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Reviewed-by: Pekka Enberg <penberg@cs.helsinki.fi>
Acked-by: Paul Mundt <lethal@linux-sh.org> [for the SLOB NUMA bits]
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Dave Hansen <dave@linux.vnet.ibm.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/ia64/hp/common/sba_iommu.c | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/mca.c | 3 | ||||
-rw-r--r-- | arch/ia64/kernel/uncached.c | 3 | ||||
-rw-r--r-- | arch/ia64/sn/pci/pci_dma.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/ras.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 2 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/grufile.c | 2 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_uv.c | 2 | ||||
-rw-r--r-- | include/linux/gfp.h | 9 | ||||
-rw-r--r-- | include/linux/mm.h | 1 | ||||
-rw-r--r-- | kernel/profile.c | 8 | ||||
-rw-r--r-- | mm/filemap.c | 2 | ||||
-rw-r--r-- | mm/hugetlb.c | 4 | ||||
-rw-r--r-- | mm/mempolicy.c | 2 | ||||
-rw-r--r-- | mm/migrate.c | 2 | ||||
-rw-r--r-- | mm/slab.c | 4 | ||||
-rw-r--r-- | mm/slob.c | 4 |
17 files changed, 33 insertions, 24 deletions
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 56ceb68eb99d..fe63b2dc9d07 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c | |||
@@ -1131,7 +1131,7 @@ sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp | |||
1131 | #ifdef CONFIG_NUMA | 1131 | #ifdef CONFIG_NUMA |
1132 | { | 1132 | { |
1133 | struct page *page; | 1133 | struct page *page; |
1134 | page = alloc_pages_node(ioc->node == MAX_NUMNODES ? | 1134 | page = alloc_pages_exact_node(ioc->node == MAX_NUMNODES ? |
1135 | numa_node_id() : ioc->node, flags, | 1135 | numa_node_id() : ioc->node, flags, |
1136 | get_order(size)); | 1136 | get_order(size)); |
1137 | 1137 | ||
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 8f33a8840422..5b17bd402275 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -1829,8 +1829,7 @@ ia64_mca_cpu_init(void *cpu_data) | |||
1829 | data = mca_bootmem(); | 1829 | data = mca_bootmem(); |
1830 | first_time = 0; | 1830 | first_time = 0; |
1831 | } else | 1831 | } else |
1832 | data = page_address(alloc_pages_node(numa_node_id(), | 1832 | data = __get_free_pages(GFP_KERNEL, get_order(sz)); |
1833 | GFP_KERNEL, get_order(sz))); | ||
1834 | if (!data) | 1833 | if (!data) |
1835 | panic("Could not allocate MCA memory for cpu %d\n", | 1834 | panic("Could not allocate MCA memory for cpu %d\n", |
1836 | cpu); | 1835 | cpu); |
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index 8eff8c1d40a6..6ba72ab42fcc 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c | |||
@@ -98,7 +98,8 @@ static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid) | |||
98 | 98 | ||
99 | /* attempt to allocate a granule's worth of cached memory pages */ | 99 | /* attempt to allocate a granule's worth of cached memory pages */ |
100 | 100 | ||
101 | page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 101 | page = alloc_pages_exact_node(nid, |
102 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | ||
102 | IA64_GRANULE_SHIFT-PAGE_SHIFT); | 103 | IA64_GRANULE_SHIFT-PAGE_SHIFT); |
103 | if (!page) { | 104 | if (!page) { |
104 | mutex_unlock(&uc_pool->add_chunk_mutex); | 105 | mutex_unlock(&uc_pool->add_chunk_mutex); |
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index d876423e4e75..98b684928e12 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c | |||
@@ -90,7 +90,8 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size, | |||
90 | */ | 90 | */ |
91 | node = pcibus_to_node(pdev->bus); | 91 | node = pcibus_to_node(pdev->bus); |
92 | if (likely(node >=0)) { | 92 | if (likely(node >=0)) { |
93 | struct page *p = alloc_pages_node(node, flags, get_order(size)); | 93 | struct page *p = alloc_pages_exact_node(node, |
94 | flags, get_order(size)); | ||
94 | 95 | ||
95 | if (likely(p)) | 96 | if (likely(p)) |
96 | cpuaddr = page_address(p); | 97 | cpuaddr = page_address(p); |
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 296b5268754e..5e0a191764fc 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c | |||
@@ -122,8 +122,8 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order) | |||
122 | 122 | ||
123 | area->nid = nid; | 123 | area->nid = nid; |
124 | area->order = order; | 124 | area->order = order; |
125 | area->pages = alloc_pages_node(area->nid, GFP_KERNEL | GFP_THISNODE, | 125 | area->pages = alloc_pages_exact_node(area->nid, GFP_KERNEL|GFP_THISNODE, |
126 | area->order); | 126 | area->order); |
127 | 127 | ||
128 | if (!area->pages) { | 128 | if (!area->pages) { |
129 | printk(KERN_WARNING "%s: no page on node %d\n", | 129 | printk(KERN_WARNING "%s: no page on node %d\n", |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 32d6ae8fb60e..e770bf349ec4 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1277,7 +1277,7 @@ static struct vmcs *alloc_vmcs_cpu(int cpu) | |||
1277 | struct page *pages; | 1277 | struct page *pages; |
1278 | struct vmcs *vmcs; | 1278 | struct vmcs *vmcs; |
1279 | 1279 | ||
1280 | pages = alloc_pages_node(node, GFP_KERNEL, vmcs_config.order); | 1280 | pages = alloc_pages_exact_node(node, GFP_KERNEL, vmcs_config.order); |
1281 | if (!pages) | 1281 | if (!pages) |
1282 | return NULL; | 1282 | return NULL; |
1283 | vmcs = page_address(pages); | 1283 | vmcs = page_address(pages); |
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index bbefe77c67a9..3ce2920e2bf3 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
@@ -302,7 +302,7 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr) | |||
302 | pnode = uv_node_to_pnode(nid); | 302 | pnode = uv_node_to_pnode(nid); |
303 | if (bid < 0 || gru_base[bid]) | 303 | if (bid < 0 || gru_base[bid]) |
304 | continue; | 304 | continue; |
305 | page = alloc_pages_node(nid, GFP_KERNEL, order); | 305 | page = alloc_pages_exact_node(nid, GFP_KERNEL, order); |
306 | if (!page) | 306 | if (!page) |
307 | goto fail; | 307 | goto fail; |
308 | gru_base[bid] = page_address(page); | 308 | gru_base[bid] = page_address(page); |
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 9172fcdee4e2..c76677afda1b 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
@@ -232,7 +232,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, | |||
232 | mq->mmr_blade = uv_cpu_to_blade_id(cpu); | 232 | mq->mmr_blade = uv_cpu_to_blade_id(cpu); |
233 | 233 | ||
234 | nid = cpu_to_node(cpu); | 234 | nid = cpu_to_node(cpu); |
235 | page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 235 | page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, |
236 | pg_order); | 236 | pg_order); |
237 | if (page == NULL) { | 237 | if (page == NULL) { |
238 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " | 238 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " |
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index c2d3fe03b5d2..4efa33088a82 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/stddef.h> | 5 | #include <linux/stddef.h> |
6 | #include <linux/linkage.h> | 6 | #include <linux/linkage.h> |
7 | #include <linux/topology.h> | 7 | #include <linux/topology.h> |
8 | #include <linux/mmdebug.h> | ||
8 | 9 | ||
9 | struct vm_area_struct; | 10 | struct vm_area_struct; |
10 | 11 | ||
@@ -192,6 +193,14 @@ static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, | |||
192 | return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); | 193 | return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); |
193 | } | 194 | } |
194 | 195 | ||
196 | static inline struct page *alloc_pages_exact_node(int nid, gfp_t gfp_mask, | ||
197 | unsigned int order) | ||
198 | { | ||
199 | VM_BUG_ON(nid < 0 || nid >= MAX_NUMNODES); | ||
200 | |||
201 | return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); | ||
202 | } | ||
203 | |||
195 | #ifdef CONFIG_NUMA | 204 | #ifdef CONFIG_NUMA |
196 | extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order); | 205 | extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order); |
197 | 206 | ||
diff --git a/include/linux/mm.h b/include/linux/mm.h index a880161a3854..7b548e7cfbd9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -7,7 +7,6 @@ | |||
7 | 7 | ||
8 | #include <linux/gfp.h> | 8 | #include <linux/gfp.h> |
9 | #include <linux/list.h> | 9 | #include <linux/list.h> |
10 | #include <linux/mmdebug.h> | ||
11 | #include <linux/mmzone.h> | 10 | #include <linux/mmzone.h> |
12 | #include <linux/rbtree.h> | 11 | #include <linux/rbtree.h> |
13 | #include <linux/prio_tree.h> | 12 | #include <linux/prio_tree.h> |
diff --git a/kernel/profile.c b/kernel/profile.c index 28cf26ad2d24..69911b5745eb 100644 --- a/kernel/profile.c +++ b/kernel/profile.c | |||
@@ -365,7 +365,7 @@ static int __cpuinit profile_cpu_callback(struct notifier_block *info, | |||
365 | node = cpu_to_node(cpu); | 365 | node = cpu_to_node(cpu); |
366 | per_cpu(cpu_profile_flip, cpu) = 0; | 366 | per_cpu(cpu_profile_flip, cpu) = 0; |
367 | if (!per_cpu(cpu_profile_hits, cpu)[1]) { | 367 | if (!per_cpu(cpu_profile_hits, cpu)[1]) { |
368 | page = alloc_pages_node(node, | 368 | page = alloc_pages_exact_node(node, |
369 | GFP_KERNEL | __GFP_ZERO, | 369 | GFP_KERNEL | __GFP_ZERO, |
370 | 0); | 370 | 0); |
371 | if (!page) | 371 | if (!page) |
@@ -373,7 +373,7 @@ static int __cpuinit profile_cpu_callback(struct notifier_block *info, | |||
373 | per_cpu(cpu_profile_hits, cpu)[1] = page_address(page); | 373 | per_cpu(cpu_profile_hits, cpu)[1] = page_address(page); |
374 | } | 374 | } |
375 | if (!per_cpu(cpu_profile_hits, cpu)[0]) { | 375 | if (!per_cpu(cpu_profile_hits, cpu)[0]) { |
376 | page = alloc_pages_node(node, | 376 | page = alloc_pages_exact_node(node, |
377 | GFP_KERNEL | __GFP_ZERO, | 377 | GFP_KERNEL | __GFP_ZERO, |
378 | 0); | 378 | 0); |
379 | if (!page) | 379 | if (!page) |
@@ -564,14 +564,14 @@ static int create_hash_tables(void) | |||
564 | int node = cpu_to_node(cpu); | 564 | int node = cpu_to_node(cpu); |
565 | struct page *page; | 565 | struct page *page; |
566 | 566 | ||
567 | page = alloc_pages_node(node, | 567 | page = alloc_pages_exact_node(node, |
568 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 568 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, |
569 | 0); | 569 | 0); |
570 | if (!page) | 570 | if (!page) |
571 | goto out_cleanup; | 571 | goto out_cleanup; |
572 | per_cpu(cpu_profile_hits, cpu)[1] | 572 | per_cpu(cpu_profile_hits, cpu)[1] |
573 | = (struct profile_hit *)page_address(page); | 573 | = (struct profile_hit *)page_address(page); |
574 | page = alloc_pages_node(node, | 574 | page = alloc_pages_exact_node(node, |
575 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 575 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, |
576 | 0); | 576 | 0); |
577 | if (!page) | 577 | if (!page) |
diff --git a/mm/filemap.c b/mm/filemap.c index 6846a902f5cf..22396713feb9 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -521,7 +521,7 @@ struct page *__page_cache_alloc(gfp_t gfp) | |||
521 | { | 521 | { |
522 | if (cpuset_do_page_mem_spread()) { | 522 | if (cpuset_do_page_mem_spread()) { |
523 | int n = cpuset_mem_spread_node(); | 523 | int n = cpuset_mem_spread_node(); |
524 | return alloc_pages_node(n, gfp, 0); | 524 | return alloc_pages_exact_node(n, gfp, 0); |
525 | } | 525 | } |
526 | return alloc_pages(gfp, 0); | 526 | return alloc_pages(gfp, 0); |
527 | } | 527 | } |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index e83ad2c9228c..2f8241f300f5 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -630,7 +630,7 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) | |||
630 | if (h->order >= MAX_ORDER) | 630 | if (h->order >= MAX_ORDER) |
631 | return NULL; | 631 | return NULL; |
632 | 632 | ||
633 | page = alloc_pages_node(nid, | 633 | page = alloc_pages_exact_node(nid, |
634 | htlb_alloc_mask|__GFP_COMP|__GFP_THISNODE| | 634 | htlb_alloc_mask|__GFP_COMP|__GFP_THISNODE| |
635 | __GFP_REPEAT|__GFP_NOWARN, | 635 | __GFP_REPEAT|__GFP_NOWARN, |
636 | huge_page_order(h)); | 636 | huge_page_order(h)); |
@@ -649,7 +649,7 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) | |||
649 | * Use a helper variable to find the next node and then | 649 | * Use a helper variable to find the next node and then |
650 | * copy it back to hugetlb_next_nid afterwards: | 650 | * copy it back to hugetlb_next_nid afterwards: |
651 | * otherwise there's a window in which a racer might | 651 | * otherwise there's a window in which a racer might |
652 | * pass invalid nid MAX_NUMNODES to alloc_pages_node. | 652 | * pass invalid nid MAX_NUMNODES to alloc_pages_exact_node. |
653 | * But we don't need to use a spin_lock here: it really | 653 | * But we don't need to use a spin_lock here: it really |
654 | * doesn't matter if occasionally a racer chooses the | 654 | * doesn't matter if occasionally a racer chooses the |
655 | * same nid as we do. Move nid forward in the mask even | 655 | * same nid as we do. Move nid forward in the mask even |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 46bdf9ddf2ba..e08e2c4da63a 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -803,7 +803,7 @@ static void migrate_page_add(struct page *page, struct list_head *pagelist, | |||
803 | 803 | ||
804 | static struct page *new_node_page(struct page *page, unsigned long node, int **x) | 804 | static struct page *new_node_page(struct page *page, unsigned long node, int **x) |
805 | { | 805 | { |
806 | return alloc_pages_node(node, GFP_HIGHUSER_MOVABLE, 0); | 806 | return alloc_pages_exact_node(node, GFP_HIGHUSER_MOVABLE, 0); |
807 | } | 807 | } |
808 | 808 | ||
809 | /* | 809 | /* |
diff --git a/mm/migrate.c b/mm/migrate.c index 068655d8f883..5a24923e7fd7 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -802,7 +802,7 @@ static struct page *new_page_node(struct page *p, unsigned long private, | |||
802 | 802 | ||
803 | *result = &pm->status; | 803 | *result = &pm->status; |
804 | 804 | ||
805 | return alloc_pages_node(pm->node, | 805 | return alloc_pages_exact_node(pm->node, |
806 | GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0); | 806 | GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0); |
807 | } | 807 | } |
808 | 808 | ||
@@ -1707,7 +1707,7 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid) | |||
1707 | if (cachep->flags & SLAB_RECLAIM_ACCOUNT) | 1707 | if (cachep->flags & SLAB_RECLAIM_ACCOUNT) |
1708 | flags |= __GFP_RECLAIMABLE; | 1708 | flags |= __GFP_RECLAIMABLE; |
1709 | 1709 | ||
1710 | page = alloc_pages_node(nodeid, flags, cachep->gfporder); | 1710 | page = alloc_pages_exact_node(nodeid, flags, cachep->gfporder); |
1711 | if (!page) | 1711 | if (!page) |
1712 | return NULL; | 1712 | return NULL; |
1713 | 1713 | ||
@@ -3261,7 +3261,7 @@ retry: | |||
3261 | if (local_flags & __GFP_WAIT) | 3261 | if (local_flags & __GFP_WAIT) |
3262 | local_irq_enable(); | 3262 | local_irq_enable(); |
3263 | kmem_flagcheck(cache, flags); | 3263 | kmem_flagcheck(cache, flags); |
3264 | obj = kmem_getpages(cache, local_flags, -1); | 3264 | obj = kmem_getpages(cache, local_flags, numa_node_id()); |
3265 | if (local_flags & __GFP_WAIT) | 3265 | if (local_flags & __GFP_WAIT) |
3266 | local_irq_disable(); | 3266 | local_irq_disable(); |
3267 | if (obj) { | 3267 | if (obj) { |
@@ -46,7 +46,7 @@ | |||
46 | * NUMA support in SLOB is fairly simplistic, pushing most of the real | 46 | * NUMA support in SLOB is fairly simplistic, pushing most of the real |
47 | * logic down to the page allocator, and simply doing the node accounting | 47 | * logic down to the page allocator, and simply doing the node accounting |
48 | * on the upper levels. In the event that a node id is explicitly | 48 | * on the upper levels. In the event that a node id is explicitly |
49 | * provided, alloc_pages_node() with the specified node id is used | 49 | * provided, alloc_pages_exact_node() with the specified node id is used |
50 | * instead. The common case (or when the node id isn't explicitly provided) | 50 | * instead. The common case (or when the node id isn't explicitly provided) |
51 | * will default to the current node, as per numa_node_id(). | 51 | * will default to the current node, as per numa_node_id(). |
52 | * | 52 | * |
@@ -244,7 +244,7 @@ static void *slob_new_pages(gfp_t gfp, int order, int node) | |||
244 | 244 | ||
245 | #ifdef CONFIG_NUMA | 245 | #ifdef CONFIG_NUMA |
246 | if (node != -1) | 246 | if (node != -1) |
247 | page = alloc_pages_node(node, gfp, order); | 247 | page = alloc_pages_exact_node(node, gfp, order); |
248 | else | 248 | else |
249 | #endif | 249 | #endif |
250 | page = alloc_pages(gfp, order); | 250 | page = alloc_pages(gfp, order); |