diff options
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r-- | mm/huge_memory.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 24e354c2b59e..3630d577e987 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -2233,6 +2233,30 @@ static void khugepaged_alloc_sleep(void) | |||
2233 | 2233 | ||
2234 | static int khugepaged_node_load[MAX_NUMNODES]; | 2234 | static int khugepaged_node_load[MAX_NUMNODES]; |
2235 | 2235 | ||
2236 | static bool khugepaged_scan_abort(int nid) | ||
2237 | { | ||
2238 | int i; | ||
2239 | |||
2240 | /* | ||
2241 | * If zone_reclaim_mode is disabled, then no extra effort is made to | ||
2242 | * allocate memory locally. | ||
2243 | */ | ||
2244 | if (!zone_reclaim_mode) | ||
2245 | return false; | ||
2246 | |||
2247 | /* If there is a count for this node already, it must be acceptable */ | ||
2248 | if (khugepaged_node_load[nid]) | ||
2249 | return false; | ||
2250 | |||
2251 | for (i = 0; i < MAX_NUMNODES; i++) { | ||
2252 | if (!khugepaged_node_load[i]) | ||
2253 | continue; | ||
2254 | if (node_distance(nid, i) > RECLAIM_DISTANCE) | ||
2255 | return true; | ||
2256 | } | ||
2257 | return false; | ||
2258 | } | ||
2259 | |||
2236 | #ifdef CONFIG_NUMA | 2260 | #ifdef CONFIG_NUMA |
2237 | static int khugepaged_find_target_node(void) | 2261 | static int khugepaged_find_target_node(void) |
2238 | { | 2262 | { |
@@ -2545,6 +2569,8 @@ static int khugepaged_scan_pmd(struct mm_struct *mm, | |||
2545 | * hit record. | 2569 | * hit record. |
2546 | */ | 2570 | */ |
2547 | node = page_to_nid(page); | 2571 | node = page_to_nid(page); |
2572 | if (khugepaged_scan_abort(node)) | ||
2573 | goto out_unmap; | ||
2548 | khugepaged_node_load[node]++; | 2574 | khugepaged_node_load[node]++; |
2549 | VM_BUG_ON_PAGE(PageCompound(page), page); | 2575 | VM_BUG_ON_PAGE(PageCompound(page), page); |
2550 | if (!PageLRU(page) || PageLocked(page) || !PageAnon(page)) | 2576 | if (!PageLRU(page) || PageLocked(page) || !PageAnon(page)) |