summaryrefslogtreecommitdiffstats
path: root/mm/hugetlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r--mm/hugetlb.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 2f901a6e13d2..a81f2a8556c8 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2288,7 +2288,7 @@ found:
2288} 2288}
2289 2289
2290#define persistent_huge_pages(h) (h->nr_huge_pages - h->surplus_huge_pages) 2290#define persistent_huge_pages(h) (h->nr_huge_pages - h->surplus_huge_pages)
2291static int set_max_huge_pages(struct hstate *h, unsigned long count, 2291static int set_max_huge_pages(struct hstate *h, unsigned long count, int nid,
2292 nodemask_t *nodes_allowed) 2292 nodemask_t *nodes_allowed)
2293{ 2293{
2294 unsigned long min_count, ret; 2294 unsigned long min_count, ret;
@@ -2296,6 +2296,26 @@ static int set_max_huge_pages(struct hstate *h, unsigned long count,
2296 spin_lock(&hugetlb_lock); 2296 spin_lock(&hugetlb_lock);
2297 2297
2298 /* 2298 /*
2299 * Check for a node specific request.
2300 * Changing node specific huge page count may require a corresponding
2301 * change to the global count. In any case, the passed node mask
2302 * (nodes_allowed) will restrict alloc/free to the specified node.
2303 */
2304 if (nid != NUMA_NO_NODE) {
2305 unsigned long old_count = count;
2306
2307 count += h->nr_huge_pages - h->nr_huge_pages_node[nid];
2308 /*
2309 * User may have specified a large count value which caused the
2310 * above calculation to overflow. In this case, they wanted
2311 * to allocate as many huge pages as possible. Set count to
2312 * largest possible value to align with their intention.
2313 */
2314 if (count < old_count)
2315 count = ULONG_MAX;
2316 }
2317
2318 /*
2299 * Gigantic pages runtime allocation depend on the capability for large 2319 * Gigantic pages runtime allocation depend on the capability for large
2300 * page range allocation. 2320 * page range allocation.
2301 * If the system does not provide this feature, return an error when 2321 * If the system does not provide this feature, return an error when
@@ -2446,15 +2466,22 @@ static ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
2446 } 2466 }
2447 } else if (nodes_allowed) { 2467 } else if (nodes_allowed) {
2448 /* 2468 /*
2449 * per node hstate attribute: adjust count to global, 2469 * Node specific request. count adjustment happens in
2450 * but restrict alloc/free to the specified node. 2470 * set_max_huge_pages() after acquiring hugetlb_lock.
2451 */ 2471 */
2452 count += h->nr_huge_pages - h->nr_huge_pages_node[nid];
2453 init_nodemask_of_node(nodes_allowed, nid); 2472 init_nodemask_of_node(nodes_allowed, nid);
2454 } else 2473 } else {
2455 nodes_allowed = &node_states[N_MEMORY]; 2474 /*
2475 * Node specific request, but we could not allocate the few
2476 * words required for a node mask. We are unlikely to hit
2477 * this condition. Since we can not pass down the appropriate
2478 * node mask, just return ENOMEM.
2479 */
2480 err = -ENOMEM;
2481 goto out;
2482 }
2456 2483
2457 err = set_max_huge_pages(h, count, nodes_allowed); 2484 err = set_max_huge_pages(h, count, nid, nodes_allowed);
2458 2485
2459out: 2486out:
2460 if (nodes_allowed != &node_states[N_MEMORY]) 2487 if (nodes_allowed != &node_states[N_MEMORY])