mm: rename alloc_pages_exact_node() to __alloc_pages_node()

alloc_pages_exact_node() was introduced in commit 6484eb3e2a ("page
allocator: do not check NUMA node ID when the caller knows the node is
valid") as an optimized variant of alloc_pages_node(), that doesn't
fallback to current node for nid == NUMA_NO_NODE.  Unfortunately the
name of the function can easily suggest that the allocation is
restricted to the given node and fails otherwise.  In truth, the node is
only preferred, unless __GFP_THISNODE is passed among the gfp flags.

The misleading name has lead to mistakes in the past, see for example
commits 5265047ac3 ("mm, thp: really limit transparent hugepage
allocation to local node") and b360edb43f ("mm, mempolicy:
migrate_to_node should only migrate to node").

Another issue with the name is that there's a family of
alloc_pages_exact*() functions where 'exact' means exact size (instead
of page order), which leads to more confusion.

To prevent further mistakes, this patch effectively renames
alloc_pages_exact_node() to __alloc_pages_node() to better convey that
it's an optimized variant of alloc_pages_node() not intended for general
usage.  Both functions get described in comments.

It has been also considered to really provide a convenience function for
allocations restricted to a node, but the major opinion seems to be that
__GFP_THISNODE already provides that functionality and we shouldn't
duplicate the API needlessly.  The number of users would be small
anyway.

Existing callers of alloc_pages_exact_node() are simply converted to
call __alloc_pages_node(), with the exception of sba_alloc_coherent()
which open-codes the check for NUMA_NO_NODE, so it is converted to use
alloc_pages_node() instead.  This means it no longer performs some
VM_BUG_ON checks, and since the current check for nid in
alloc_pages_node() uses a 'nid < 0' comparison (which includes
NUMA_NO_NODE), it may hide wrong values which would be previously
exposed.

Both differences will be rectified by the next patch.

To sum up, this patch makes no functional changes, except temporarily
hiding potentially buggy callers.  Restricting the checks in
alloc_pages_node() is left for the next patch which can in turn expose
more existing buggy callers.

Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Robin Holt <robinmholt@gmail.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Christoph Lameter <cl@linux.com>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Cc: Mel Gorman <mgorman@suse.de>
Cc: David Rientjes <rientjes@google.com>
Cc: Greg Thelen <gthelen@google.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Cliff Whickman <cpw@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Vlastimil Babka 2015-09-08 15:03:50 -07:00 committed by Linus Torvalds
parent 7fadc82022
commit 96db800f5d
18 changed files with 39 additions and 38 deletions

View File

@ -1140,13 +1140,9 @@ sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
{ {
int node = ioc->node;
struct page *page; struct page *page;
if (node == NUMA_NO_NODE) page = alloc_pages_node(ioc->node, flags, get_order(size));
node = numa_node_id();
page = alloc_pages_exact_node(node, flags, get_order(size));
if (unlikely(!page)) if (unlikely(!page))
return NULL; return NULL;

View File

@ -97,7 +97,7 @@ static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid)
/* attempt to allocate a granule's worth of cached memory pages */ /* attempt to allocate a granule's worth of cached memory pages */
page = alloc_pages_exact_node(nid, page = __alloc_pages_node(nid,
GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
IA64_GRANULE_SHIFT-PAGE_SHIFT); IA64_GRANULE_SHIFT-PAGE_SHIFT);
if (!page) { if (!page) {

View File

@ -92,7 +92,7 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size,
*/ */
node = pcibus_to_node(pdev->bus); node = pcibus_to_node(pdev->bus);
if (likely(node >=0)) { if (likely(node >=0)) {
struct page *p = alloc_pages_exact_node(node, struct page *p = __alloc_pages_node(node,
flags, get_order(size)); flags, get_order(size));
if (likely(p)) if (likely(p))

View File

@ -123,7 +123,7 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order)
area->nid = nid; area->nid = nid;
area->order = order; area->order = order;
area->pages = alloc_pages_exact_node(area->nid, area->pages = __alloc_pages_node(area->nid,
GFP_KERNEL|__GFP_THISNODE, GFP_KERNEL|__GFP_THISNODE,
area->order); area->order);

View File

@ -3150,7 +3150,7 @@ static struct vmcs *alloc_vmcs_cpu(int cpu)
struct page *pages; struct page *pages;
struct vmcs *vmcs; struct vmcs *vmcs;
pages = alloc_pages_exact_node(node, GFP_KERNEL, vmcs_config.order); pages = __alloc_pages_node(node, GFP_KERNEL, vmcs_config.order);
if (!pages) if (!pages)
return NULL; return NULL;
vmcs = page_address(pages); vmcs = page_address(pages);

View File

@ -239,7 +239,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
mq->mmr_blade = uv_cpu_to_blade_id(cpu); mq->mmr_blade = uv_cpu_to_blade_id(cpu);
nid = cpu_to_node(cpu); nid = cpu_to_node(cpu);
page = alloc_pages_exact_node(nid, page = __alloc_pages_node(nid,
GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
pg_order); pg_order);
if (page == NULL) { if (page == NULL) {

View File

@ -303,6 +303,22 @@ __alloc_pages(gfp_t gfp_mask, unsigned int order,
return __alloc_pages_nodemask(gfp_mask, order, zonelist, NULL); return __alloc_pages_nodemask(gfp_mask, order, zonelist, NULL);
} }
/*
* Allocate pages, preferring the node given as nid. The node must be valid and
* online. For more general interface, see alloc_pages_node().
*/
static inline struct page *
__alloc_pages_node(int nid, gfp_t gfp_mask, unsigned int order)
{
VM_BUG_ON(nid < 0 || nid >= MAX_NUMNODES || !node_online(nid));
return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask));
}
/*
* Allocate pages, preferring the node given as nid. When nid == NUMA_NO_NODE,
* prefer the current CPU's node.
*/
static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask,
unsigned int order) unsigned int order)
{ {
@ -313,14 +329,6 @@ static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask,
return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask));
} }
static inline struct page *alloc_pages_exact_node(int nid, gfp_t gfp_mask,
unsigned int order)
{
VM_BUG_ON(nid < 0 || nid >= MAX_NUMNODES || !node_online(nid));
return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask));
}
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order); extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order);
@ -357,7 +365,6 @@ extern unsigned long get_zeroed_page(gfp_t gfp_mask);
void *alloc_pages_exact(size_t size, gfp_t gfp_mask); void *alloc_pages_exact(size_t size, gfp_t gfp_mask);
void free_pages_exact(void *virt, size_t size); void free_pages_exact(void *virt, size_t size);
/* This is different from alloc_pages_exact_node !!! */
void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask); void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask);
#define __get_free_page(gfp_mask) \ #define __get_free_page(gfp_mask) \

View File

@ -339,7 +339,7 @@ static int profile_cpu_callback(struct notifier_block *info,
node = cpu_to_mem(cpu); node = cpu_to_mem(cpu);
per_cpu(cpu_profile_flip, cpu) = 0; per_cpu(cpu_profile_flip, cpu) = 0;
if (!per_cpu(cpu_profile_hits, cpu)[1]) { if (!per_cpu(cpu_profile_hits, cpu)[1]) {
page = alloc_pages_exact_node(node, page = __alloc_pages_node(node,
GFP_KERNEL | __GFP_ZERO, GFP_KERNEL | __GFP_ZERO,
0); 0);
if (!page) if (!page)
@ -347,7 +347,7 @@ static int profile_cpu_callback(struct notifier_block *info,
per_cpu(cpu_profile_hits, cpu)[1] = page_address(page); per_cpu(cpu_profile_hits, cpu)[1] = page_address(page);
} }
if (!per_cpu(cpu_profile_hits, cpu)[0]) { if (!per_cpu(cpu_profile_hits, cpu)[0]) {
page = alloc_pages_exact_node(node, page = __alloc_pages_node(node,
GFP_KERNEL | __GFP_ZERO, GFP_KERNEL | __GFP_ZERO,
0); 0);
if (!page) if (!page)
@ -543,14 +543,14 @@ static int create_hash_tables(void)
int node = cpu_to_mem(cpu); int node = cpu_to_mem(cpu);
struct page *page; struct page *page;
page = alloc_pages_exact_node(node, page = __alloc_pages_node(node,
GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
0); 0);
if (!page) if (!page)
goto out_cleanup; goto out_cleanup;
per_cpu(cpu_profile_hits, cpu)[1] per_cpu(cpu_profile_hits, cpu)[1]
= (struct profile_hit *)page_address(page); = (struct profile_hit *)page_address(page);
page = alloc_pages_exact_node(node, page = __alloc_pages_node(node,
GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
0); 0);
if (!page) if (!page)

View File

@ -674,7 +674,7 @@ struct page *__page_cache_alloc(gfp_t gfp)
do { do {
cpuset_mems_cookie = read_mems_allowed_begin(); cpuset_mems_cookie = read_mems_allowed_begin();
n = cpuset_mem_spread_node(); n = cpuset_mem_spread_node();
page = alloc_pages_exact_node(n, gfp, 0); page = __alloc_pages_node(n, gfp, 0);
} while (!page && read_mems_allowed_retry(cpuset_mems_cookie)); } while (!page && read_mems_allowed_retry(cpuset_mems_cookie));
return page; return page;

View File

@ -2414,7 +2414,7 @@ khugepaged_alloc_page(struct page **hpage, gfp_t gfp, struct mm_struct *mm,
*/ */
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
*hpage = alloc_pages_exact_node(node, gfp, HPAGE_PMD_ORDER); *hpage = __alloc_pages_node(node, gfp, HPAGE_PMD_ORDER);
if (unlikely(!*hpage)) { if (unlikely(!*hpage)) {
count_vm_event(THP_COLLAPSE_ALLOC_FAILED); count_vm_event(THP_COLLAPSE_ALLOC_FAILED);
*hpage = ERR_PTR(-ENOMEM); *hpage = ERR_PTR(-ENOMEM);

View File

@ -1331,7 +1331,7 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid)
{ {
struct page *page; struct page *page;
page = alloc_pages_exact_node(nid, page = __alloc_pages_node(nid,
htlb_alloc_mask(h)|__GFP_COMP|__GFP_THISNODE| htlb_alloc_mask(h)|__GFP_COMP|__GFP_THISNODE|
__GFP_REPEAT|__GFP_NOWARN, __GFP_REPEAT|__GFP_NOWARN,
huge_page_order(h)); huge_page_order(h));
@ -1483,7 +1483,7 @@ static struct page *alloc_buddy_huge_page(struct hstate *h, int nid)
__GFP_REPEAT|__GFP_NOWARN, __GFP_REPEAT|__GFP_NOWARN,
huge_page_order(h)); huge_page_order(h));
else else
page = alloc_pages_exact_node(nid, page = __alloc_pages_node(nid,
htlb_alloc_mask(h)|__GFP_COMP|__GFP_THISNODE| htlb_alloc_mask(h)|__GFP_COMP|__GFP_THISNODE|
__GFP_REPEAT|__GFP_NOWARN, huge_page_order(h)); __GFP_REPEAT|__GFP_NOWARN, huge_page_order(h));

View File

@ -1521,7 +1521,7 @@ static struct page *new_page(struct page *p, unsigned long private, int **x)
return alloc_huge_page_node(page_hstate(compound_head(p)), return alloc_huge_page_node(page_hstate(compound_head(p)),
nid); nid);
else else
return alloc_pages_exact_node(nid, GFP_HIGHUSER_MOVABLE, 0); return __alloc_pages_node(nid, GFP_HIGHUSER_MOVABLE, 0);
} }
/* /*

View File

@ -942,7 +942,7 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x
return alloc_huge_page_node(page_hstate(compound_head(page)), return alloc_huge_page_node(page_hstate(compound_head(page)),
node); node);
else else
return alloc_pages_exact_node(node, GFP_HIGHUSER_MOVABLE | return __alloc_pages_node(node, GFP_HIGHUSER_MOVABLE |
__GFP_THISNODE, 0); __GFP_THISNODE, 0);
} }
@ -1998,7 +1998,7 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
nmask = policy_nodemask(gfp, pol); nmask = policy_nodemask(gfp, pol);
if (!nmask || node_isset(hpage_node, *nmask)) { if (!nmask || node_isset(hpage_node, *nmask)) {
mpol_cond_put(pol); mpol_cond_put(pol);
page = alloc_pages_exact_node(hpage_node, page = __alloc_pages_node(hpage_node,
gfp | __GFP_THISNODE, order); gfp | __GFP_THISNODE, order);
goto out; goto out;
} }

View File

@ -1195,7 +1195,7 @@ static struct page *new_page_node(struct page *p, unsigned long private,
return alloc_huge_page_node(page_hstate(compound_head(p)), return alloc_huge_page_node(page_hstate(compound_head(p)),
pm->node); pm->node);
else else
return alloc_pages_exact_node(pm->node, return __alloc_pages_node(pm->node,
GFP_HIGHUSER_MOVABLE | __GFP_THISNODE, 0); GFP_HIGHUSER_MOVABLE | __GFP_THISNODE, 0);
} }
@ -1555,7 +1555,7 @@ static struct page *alloc_misplaced_dst_page(struct page *page,
int nid = (int) data; int nid = (int) data;
struct page *newpage; struct page *newpage;
newpage = alloc_pages_exact_node(nid, newpage = __alloc_pages_node(nid,
(GFP_HIGHUSER_MOVABLE | (GFP_HIGHUSER_MOVABLE |
__GFP_THISNODE | __GFP_NOMEMALLOC | __GFP_THISNODE | __GFP_NOMEMALLOC |
__GFP_NORETRY | __GFP_NOWARN) & __GFP_NORETRY | __GFP_NOWARN) &

View File

@ -3511,8 +3511,6 @@ EXPORT_SYMBOL(alloc_pages_exact);
* *
* Like alloc_pages_exact(), but try to allocate on node nid first before falling * Like alloc_pages_exact(), but try to allocate on node nid first before falling
* back. * back.
* Note this is not alloc_pages_exact_node() which allocates on a specific node,
* but is not exact.
*/ */
void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask) void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask)
{ {

View File

@ -1595,7 +1595,7 @@ static struct page *kmem_getpages(struct kmem_cache *cachep, gfp_t flags,
if (memcg_charge_slab(cachep, flags, cachep->gfporder)) if (memcg_charge_slab(cachep, flags, cachep->gfporder))
return NULL; return NULL;
page = alloc_pages_exact_node(nodeid, flags | __GFP_NOTRACK, cachep->gfporder); page = __alloc_pages_node(nodeid, flags | __GFP_NOTRACK, cachep->gfporder);
if (!page) { if (!page) {
memcg_uncharge_slab(cachep, cachep->gfporder); memcg_uncharge_slab(cachep, cachep->gfporder);
slab_out_of_memory(cachep, flags, nodeid); slab_out_of_memory(cachep, flags, nodeid);

View File

@ -45,7 +45,7 @@
* NUMA support in SLOB is fairly simplistic, pushing most of the real * NUMA support in SLOB is fairly simplistic, pushing most of the real
* logic down to the page allocator, and simply doing the node accounting * logic down to the page allocator, and simply doing the node accounting
* on the upper levels. In the event that a node id is explicitly * on the upper levels. In the event that a node id is explicitly
* provided, alloc_pages_exact_node() with the specified node id is used * provided, __alloc_pages_node() with the specified node id is used
* instead. The common case (or when the node id isn't explicitly provided) * instead. The common case (or when the node id isn't explicitly provided)
* will default to the current node, as per numa_node_id(). * will default to the current node, as per numa_node_id().
* *
@ -193,7 +193,7 @@ static void *slob_new_pages(gfp_t gfp, int order, int node)
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
if (node != NUMA_NO_NODE) if (node != NUMA_NO_NODE)
page = alloc_pages_exact_node(node, gfp, order); page = __alloc_pages_node(node, gfp, order);
else else
#endif #endif
page = alloc_pages(gfp, order); page = alloc_pages(gfp, order);

View File

@ -1334,7 +1334,7 @@ static inline struct page *alloc_slab_page(struct kmem_cache *s,
if (node == NUMA_NO_NODE) if (node == NUMA_NO_NODE)
page = alloc_pages(flags, order); page = alloc_pages(flags, order);
else else
page = alloc_pages_exact_node(node, flags, order); page = __alloc_pages_node(node, flags, order);
if (!page) if (!page)
memcg_uncharge_slab(s, order); memcg_uncharge_slab(s, order);