From: Mel Gorman <mgorman@suse.de>
To: Jiri Slaby <jslaby@suse.cz>
Cc: Linux-Stable <stable@vger.kernel.org>,
LKML <linux-kernel@vger.kernel.org>, Mel Gorman <mgorman@suse.de>
Subject: [PATCH 02/97] mm: thp: khugepaged: add policy for finding target node
Date: Thu, 28 Aug 2014 19:34:10 +0100 [thread overview]
Message-ID: <1409250945-30874-3-git-send-email-mgorman@suse.de> (raw)
In-Reply-To: <1409250945-30874-1-git-send-email-mgorman@suse.de>
From: Bob Liu <lliubbo@gmail.com>
commit 9f1b868a13ac36bd207a571f5ea1193d823ab18d upstream.
Khugepaged will scan/free HPAGE_PMD_NR normal pages and replace with a
hugepage which is allocated from the node of the first scanned normal
page, but this policy is too rough and may end with unexpected result to
upper users.
The problem is the original page-balancing among all nodes will be
broken after hugepaged started. Thinking about the case if the first
scanned normal page is allocated from node A, most of other scanned
normal pages are allocated from node B or C.. But hugepaged will always
allocate hugepage from node A which will cause extra memory pressure on
node A which is not the situation before khugepaged started.
This patch try to fix this problem by making khugepaged allocate
hugepage from the node which have max record of scaned normal pages hit,
so that the effect to original page-balancing can be minimized.
The other problem is if normal scanned pages are equally allocated from
Node A,B and C, after khugepaged started Node A will still suffer extra
memory pressure.
Andrew Davidoff reported a related issue several days ago. He wanted
his application interleaving among all nodes and "numactl
--interleave=all ./test" was used to run the testcase, but the result
wasn't not as expected.
cat /proc/2814/numa_maps:
7f50bd440000 interleave:0-3 anon=51403 dirty=51403 N0=435 N1=435 N2=435 N3=50098
The end result showed that most pages are from Node3 instead of
interleave among node0-3 which was unreasonable.
This patch also fix this issue by allocating hugepage round robin from
all nodes have the same record, after this patch the result was as
expected:
7f78399c0000 interleave:0-3 anon=51403 dirty=51403 N0=12723 N1=12723 N2=13235 N3=12722
The simple testcase is like this:
int main() {
char *p;
int i;
int j;
for (i=0; i < 200; i++) {
p = (char *)malloc(1048576);
printf("malloc done\n");
if (p == 0) {
printf("Out of memory\n");
return 1;
}
for (j=0; j < 1048576; j++) {
p[j] = 'A';
}
printf("touched memory\n");
sleep(1);
}
printf("enter sleep\n");
while(1) {
sleep(100);
}
}
[akpm@linux-foundation.org: make last_khugepaged_target_node local to khugepaged_find_target_node()]
Reported-by: Andrew Davidoff <davidoff@qedmf.net>
Tested-by: Andrew Davidoff <davidoff@qedmf.net>
Signed-off-by: Bob Liu <bob.liu@oracle.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Wanpeng Li <liwanp@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Mel Gorman <mgorman@suse.de>
---
mm/huge_memory.c | 53 ++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 44 insertions(+), 9 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 738a57e..515e589 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2189,7 +2189,34 @@ static void khugepaged_alloc_sleep(void)
msecs_to_jiffies(khugepaged_alloc_sleep_millisecs));
}
+static int khugepaged_node_load[MAX_NUMNODES];
+
#ifdef CONFIG_NUMA
+static int khugepaged_find_target_node(void)
+{
+ static int last_khugepaged_target_node = NUMA_NO_NODE;
+ int nid, target_node = 0, max_value = 0;
+
+ /* find first node with max normal pages hit */
+ for (nid = 0; nid < MAX_NUMNODES; nid++)
+ if (khugepaged_node_load[nid] > max_value) {
+ max_value = khugepaged_node_load[nid];
+ target_node = nid;
+ }
+
+ /* do some balance if several nodes have the same hit record */
+ if (target_node <= last_khugepaged_target_node)
+ for (nid = last_khugepaged_target_node + 1; nid < MAX_NUMNODES;
+ nid++)
+ if (max_value == khugepaged_node_load[nid]) {
+ target_node = nid;
+ break;
+ }
+
+ last_khugepaged_target_node = target_node;
+ return target_node;
+}
+
static bool khugepaged_prealloc_page(struct page **hpage, bool *wait)
{
if (IS_ERR(*hpage)) {
@@ -2223,9 +2250,8 @@ static struct page
* mmap_sem in read mode is good idea also to allow greater
* scalability.
*/
- *hpage = alloc_hugepage_vma(khugepaged_defrag(), vma, address,
- node, __GFP_OTHER_NODE);
-
+ *hpage = alloc_pages_exact_node(node, alloc_hugepage_gfpmask(
+ khugepaged_defrag(), __GFP_OTHER_NODE), HPAGE_PMD_ORDER);
/*
* After allocating the hugepage, release the mmap_sem read lock in
* preparation for taking it in write mode.
@@ -2241,6 +2267,11 @@ static struct page
return *hpage;
}
#else
+static int khugepaged_find_target_node(void)
+{
+ return 0;
+}
+
static inline struct page *alloc_hugepage(int defrag)
{
return alloc_pages(alloc_hugepage_gfpmask(defrag, 0),
@@ -2453,6 +2484,7 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
if (pmd_trans_huge(*pmd))
goto out;
+ memset(khugepaged_node_load, 0, sizeof(khugepaged_node_load));
pte = pte_offset_map_lock(mm, pmd, address, &ptl);
for (_address = address, _pte = pte; _pte < pte+HPAGE_PMD_NR;
_pte++, _address += PAGE_SIZE) {
@@ -2469,12 +2501,13 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
if (unlikely(!page))
goto out_unmap;
/*
- * Chose the node of the first page. This could
- * be more sophisticated and look at more pages,
- * but isn't for now.
+ * Record which node the original page is from and save this
+ * information to khugepaged_node_load[].
+ * Khupaged will allocate hugepage from the node has the max
+ * hit record.
*/
- if (node == NUMA_NO_NODE)
- node = page_to_nid(page);
+ node = page_to_nid(page);
+ khugepaged_node_load[node]++;
VM_BUG_ON(PageCompound(page));
if (!PageLRU(page) || PageLocked(page) || !PageAnon(page))
goto out_unmap;
@@ -2489,9 +2522,11 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
ret = 1;
out_unmap:
pte_unmap_unlock(pte, ptl);
- if (ret)
+ if (ret) {
+ node = khugepaged_find_target_node();
/* collapse_huge_page will return with the mmap_sem released */
collapse_huge_page(mm, address, hpage, vma, node);
+ }
out:
return ret;
}
--
1.8.4.5
next prev parent reply other threads:[~2014-08-28 19:10 UTC|newest]
Thread overview: 101+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-28 18:34 [PATCH 00/97] Misc series of functional/performance fixes for 3.12-stable Mel Gorman
2014-08-28 18:34 ` [PATCH 01/97] mm: thp: cleanup: mv alloc_hugepage to better place Mel Gorman
2014-08-28 18:34 ` Mel Gorman [this message]
2014-08-28 18:34 ` [PATCH 03/97] slab: correct pfmemalloc check Mel Gorman
2014-08-28 18:34 ` [PATCH 04/97] mm: prevent setting of a value less than 0 to min_free_kbytes Mel Gorman
2014-08-28 18:34 ` [PATCH 05/97] mm: fix bad rss-counter if remap_file_pages raced migration Mel Gorman
2014-08-28 18:34 ` [PATCH 06/97] hugetlb: ensure hugepage access is denied if hugepages are not supported Mel Gorman
2014-08-28 18:34 ` [PATCH 07/97] mm: exclude memoryless nodes from zone_reclaim Mel Gorman
2014-08-28 18:34 ` [PATCH 08/97] mm, thp: do not allow thp faults to avoid cpuset restrictions Mel Gorman
2014-09-26 9:53 ` Jiri Slaby
2014-10-13 15:17 ` Mel Gorman
2014-08-28 18:34 ` [PATCH 09/97] swap: change swap_info singly-linked list to list_head Mel Gorman
2014-08-28 18:34 ` [PATCH 10/97] lib/plist: add helper functions Mel Gorman
2014-08-28 18:34 ` [PATCH 11/97] lib/plist: add plist_requeue Mel Gorman
2014-08-28 18:34 ` [PATCH 12/97] swap: change swap_list_head to plist, add swap_avail_head Mel Gorman
2014-08-28 18:34 ` [PATCH 13/97] readahead: fix sequential read cache miss detection Mel Gorman
2014-08-28 18:34 ` [PATCH 14/97] mm: get rid of unnecessary overhead of trace_mm_page_alloc_extfrag() Mel Gorman
2014-08-28 18:34 ` [PATCH 15/97] mm: __rmqueue_fallback() should respect pageblock type Mel Gorman
2014-08-28 18:34 ` [PATCH 16/97] mm, x86: Account for TLB flushes only when debugging Mel Gorman
2014-08-28 18:34 ` [PATCH 17/97] x86/mm: Clean up inconsistencies when flushing TLB ranges Mel Gorman
2014-08-28 18:34 ` [PATCH 18/97] x86/mm: Eliminate redundant page table walk during TLB range flushing Mel Gorman
2014-08-28 18:34 ` [PATCH 19/97] mm: compaction: trace compaction begin and end Mel Gorman
2014-08-28 18:34 ` [PATCH 20/97] mm: compaction: encapsulate defer reset logic Mel Gorman
2014-08-28 18:34 ` [PATCH 21/97] mm: compaction: do not mark unmovable pageblocks as skipped in async compaction Mel Gorman
2014-08-28 18:34 ` [PATCH 22/97] mm: compaction: reset scanner positions immediately when they meet Mel Gorman
2014-08-28 18:34 ` [PATCH 23/97] swap: add a simple detector for inappropriate swapin readahead Mel Gorman
2014-08-28 18:34 ` [PATCH 24/97] mm: vmscan: shrink all slab objects if tight on memory Mel Gorman
2014-08-28 18:34 ` [PATCH 25/97] mm: vmscan: call NUMA-unaware shrinkers irrespective of nodemask Mel Gorman
2014-08-28 18:34 ` [PATCH 26/97] mm: get rid of unnecessary pageblock scanning in setup_zone_migrate_reserve Mel Gorman
2014-08-28 18:34 ` [PATCH 27/97] mm, compaction: avoid isolating pinned pages Mel Gorman
2014-08-28 18:34 ` [PATCH 28/97] mm/compaction: disallow high-order page for migration target Mel Gorman
2014-08-28 18:34 ` [PATCH 29/97] mm/compaction: do not call suitable_migration_target() on every page Mel Gorman
2014-08-28 18:34 ` [PATCH 30/97] mm/compaction: change the timing to check to drop the spinlock Mel Gorman
2014-08-28 18:34 ` [PATCH 31/97] mm/compaction: check pageblock suitability once per pageblock Mel Gorman
2014-08-28 18:34 ` [PATCH 32/97] mm/compaction: clean-up code on success of ballon isolation Mel Gorman
2014-08-28 18:34 ` [PATCH 33/97] mm, compaction: determine isolation mode only once Mel Gorman
2014-08-28 18:34 ` [PATCH 34/97] mm, compaction: ignore pageblock skip when manually invoking compaction Mel Gorman
2014-08-28 18:34 ` [PATCH 35/97] mm/readahead.c: fix readahead failure for memoryless NUMA nodes and limit readahead pages Mel Gorman
2014-08-28 18:34 ` [PATCH 36/97] mm: optimize put_mems_allowed() usage Mel Gorman
2014-08-28 18:34 ` [PATCH 37/97] mm/filemap.c: avoid always dirtying mapping->flags on O_DIRECT Mel Gorman
2014-08-28 18:34 ` [PATCH 38/97] mm: vmscan: respect NUMA policy mask when shrinking slab on direct reclaim Mel Gorman
2014-08-28 18:34 ` [PATCH 39/97] mm: vmscan: shrink_slab: rename max_pass -> freeable Mel Gorman
2014-08-28 18:34 ` [PATCH 40/97] vmscan: reclaim_clean_pages_from_list() must use mod_zone_page_state() Mel Gorman
2014-08-28 18:34 ` [PATCH 41/97] mm: per-thread vma caching Mel Gorman
2014-08-28 18:34 ` [PATCH 42/97] mm: don't pointlessly use BUG_ON() for sanity check Mel Gorman
2014-08-28 18:34 ` [PATCH 43/97] lib: radix-tree: add radix_tree_delete_item() Mel Gorman
2014-08-28 18:34 ` [PATCH 44/97] mm: shmem: save one radix tree lookup when truncating swapped pages Mel Gorman
2014-08-28 18:34 ` [PATCH 45/97] mm: filemap: move radix tree hole searching here Mel Gorman
2014-08-28 18:34 ` [PATCH 46/97] mm + fs: prepare for non-page entries in page cache radix trees Mel Gorman
2014-08-28 18:34 ` [PATCH 47/97] mm: madvise: fix MADV_WILLNEED on shmem swapouts Mel Gorman
2014-08-28 18:34 ` [PATCH 48/97] mm: remove read_cache_page_async() Mel Gorman
2014-08-28 18:34 ` [PATCH 49/97] callers of iov_copy_from_user_atomic() don't need pagecache_disable() Mel Gorman
2014-08-28 18:34 ` [PATCH 50/97] mm/readahead.c: inline ra_submit Mel Gorman
2014-08-28 18:34 ` [PATCH 51/97] mm/compaction: clean up unused code lines Mel Gorman
2014-08-28 18:35 ` [PATCH 52/97] mm/compaction: cleanup isolate_freepages() Mel Gorman
2014-08-28 18:35 ` [PATCH 53/97] mm, migration: add destination page freeing callback Mel Gorman
2014-08-28 18:35 ` [PATCH 54/97] mm, compaction: return failed migration target pages back to freelist Mel Gorman
2014-08-28 18:35 ` [PATCH 55/97] mm, compaction: add per-zone migration pfn cache for async compaction Mel Gorman
2014-08-28 18:35 ` [PATCH 56/97] mm, compaction: embed migration mode in compact_control Mel Gorman
2014-08-28 18:35 ` [PATCH 57/97] mm, compaction: terminate async compaction when rescheduling Mel Gorman
2014-08-28 18:35 ` [PATCH 58/97] mm/compaction: do not count migratepages when unnecessary Mel Gorman
2014-08-28 18:35 ` [PATCH 59/97] mm/compaction: avoid rescanning pageblocks in isolate_freepages Mel Gorman
2014-08-28 18:35 ` [PATCH 60/97] mm, compaction: properly signal and act upon lock and need_sched() contention Mel Gorman
2014-08-28 18:35 ` [PATCH 61/97] x86/mm: In the PTE swapout page reclaim case clear the accessed bit instead of flushing the TLB Mel Gorman
2014-08-28 18:35 ` [PATCH 62/97] mm: fix direct reclaim writeback regression Mel Gorman
2014-08-28 18:35 ` [PATCH 63/97] fs/superblock: unregister sb shrinker before ->kill_sb() Mel Gorman
2014-08-28 18:35 ` [PATCH 64/97] fs/superblock: avoid locking counting inodes and dentries before reclaiming them Mel Gorman
2014-08-28 18:35 ` [PATCH 65/97] mm: vmscan: use proportional scanning during direct reclaim and full scan at DEF_PRIORITY Mel Gorman
2014-08-28 18:35 ` [PATCH 66/97] mm/page_alloc: prevent MIGRATE_RESERVE pages from being misplaced Mel Gorman
2014-08-28 18:35 ` [PATCH 67/97] mm/swap.c: clean up *lru_cache_add* functions Mel Gorman
2014-08-28 18:35 ` [PATCH 68/97] mm: page_alloc: do not update zlc unless the zlc is active Mel Gorman
2014-08-28 18:35 ` [PATCH 69/97] mm: page_alloc: do not treat a zone that cannot be used for dirty pages as "full" Mel Gorman
2014-08-28 18:35 ` [PATCH 70/97] include/linux/jump_label.h: expose the reference count Mel Gorman
2014-08-28 18:35 ` [PATCH 71/97] mm: page_alloc: use jump labels to avoid checking number_of_cpusets Mel Gorman
2014-08-28 18:35 ` [PATCH 72/97] mm: page_alloc: calculate classzone_idx once from the zonelist ref Mel Gorman
2014-08-28 18:35 ` [PATCH 73/97] mm: page_alloc: only check the zone id check if pages are buddies Mel Gorman
2014-08-28 18:35 ` [PATCH 74/97] mm: page_alloc: only check the alloc flags and gfp_mask for dirty once Mel Gorman
2014-08-28 18:35 ` [PATCH 75/97] mm: page_alloc: take the ALLOC_NO_WATERMARK check out of the fast path Mel Gorman
2014-08-28 18:35 ` [PATCH 76/97] mm: page_alloc: use unsigned int for order in more places Mel Gorman
2014-08-28 18:35 ` [PATCH 77/97] mm: page_alloc: reduce number of times page_to_pfn is called Mel Gorman
2014-08-28 18:35 ` [PATCH 78/97] mm: page_alloc: convert hot/cold parameter and immediate callers to bool Mel Gorman
2014-08-28 18:35 ` [PATCH 79/97] mm: page_alloc: lookup pageblock migratetype with IRQs enabled during free Mel Gorman
2014-08-28 18:35 ` [PATCH 80/97] mm: shmem: avoid atomic operation during shmem_getpage_gfp Mel Gorman
2014-08-28 18:35 ` [PATCH 81/97] mm: do not use atomic operations when releasing pages Mel Gorman
2014-08-28 18:35 ` [PATCH 82/97] mm: do not use unnecessary atomic operations when adding pages to the LRU Mel Gorman
2014-08-28 18:35 ` [PATCH 83/97] fs: buffer: do not use unnecessary atomic operations when discarding buffers Mel Gorman
2014-08-28 18:35 ` [PATCH 84/97] mm: non-atomically mark page accessed during page cache allocation where possible Mel Gorman
2014-08-28 18:35 ` [PATCH 85/97] mm: avoid unnecessary atomic operations during end_page_writeback() Mel Gorman
2014-08-28 18:35 ` [PATCH 86/97] shmem: fix init_page_accessed use to stop !PageLRU bug Mel Gorman
2014-08-28 18:35 ` [PATCH 87/97] mm/memory.c: use entry = ACCESS_ONCE(*pte) in handle_pte_fault() Mel Gorman
2014-08-28 18:35 ` [PATCH 88/97] mm, thp: only collapse hugepages to nodes with affinity for zone_reclaim_mode Mel Gorman
2014-08-28 18:35 ` [PATCH 89/97] mm: make copy_pte_range static again Mel Gorman
2014-08-28 18:35 ` [PATCH 90/97] vmalloc: use rcu list iterator to reduce vmap_area_lock contention Mel Gorman
2014-08-28 18:35 ` [PATCH 91/97] memcg, vmscan: Fix forced scan of anonymous pages Mel Gorman
2014-08-28 18:35 ` [PATCH 92/97] mm: pagemap: avoid unnecessary overhead when tracepoints are deactivated Mel Gorman
2014-08-28 18:35 ` [PATCH 93/97] mm: rearrange zone fields into read-only, page alloc, statistics and page reclaim lines Mel Gorman
2014-08-28 18:35 ` [PATCH 94/97] mm: move zone->pages_scanned into a vmstat counter Mel Gorman
2014-08-28 18:35 ` [PATCH 95/97] mm: vmscan: only update per-cpu thresholds for online CPU Mel Gorman
2014-08-28 18:35 ` [PATCH 96/97] mm: page_alloc: abort fair zone allocation policy when remotes nodes are encountered Mel Gorman
2014-08-28 18:35 ` [PATCH 97/97] mm: page_alloc: reduce cost of the fair zone allocation policy Mel Gorman
2015-01-28 1:13 ` [PATCH 00/97] Misc series of functional/performance fixes for 3.12-stable Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1409250945-30874-3-git-send-email-mgorman@suse.de \
--to=mgorman@suse.de \
--cc=jslaby@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®