History

Revert "Revert "mm, thp: restore node-local hugepage allocations""

This reverts commit a8282608c88e08b1782141026eab61204c1e533f. The commit references the original intended semantic for MADV_HUGEPAGE which has subsequently taken on three unique purposes: - enables or disables thp for a range of memory depending on the system's config (is thp "enabled" set to "always" or "madvise"), - determines the synchronous compaction behavior for thp allocations at fault (is thp "defrag" set to "always", "defer+madvise", or "madvise"), and - reverts a previous MADV_NOHUGEPAGE (there is no madvise mode to only clear previous hugepage advice). These are the three purposes that currently exist in 5.2 and over the past several years that userspace has been written around. Adding a NUMA locality preference adds a fourth dimension to an already conflated advice mode. Based on the semantic that MADV_HUGEPAGE has provided over the past several years, there exist workloads that use the tunable based on these principles: specifically that the allocation should attempt to defragment a local node before falling back. It is agreed that remote hugepages typically (but not always) have a better access latency than remote native pages, although on Naples this is at parity for intersocket. The revert commit that this patch reverts allows hugepage allocation to immediately allocate remotely when local memory is fragmented. This is contrary to the semantic of MADV_HUGEPAGE over the past several years: that is, memory compaction should be attempted locally before falling back. The performance degradation of remote hugepages over local hugepages on Rome, for example, is 53.5% increased access latency. For this reason, the goal is to revert back to the 5.2 and previous behavior that would attempt local defragmentation before falling back. With the patch that is reverted by this patch, we see performance degradations at the tail because the allocator happily allocates the remote hugepage rather than even attempting to make a local hugepage available. zone_reclaim_mode is not a solution to this problem since it does not only impact hugepage allocations but rather changes the memory allocation strategy for *all* page allocations.

David Rientjes committed 7 years ago

Commit ac79f781 parent 4d856f73 files · +17 −29Browse files

Unified · Split

3 files
  1. include/linux/mempolicy.h +0 −2
  2. mm/huge_memory.c +16 −26
  3. mm/mempolicy.c +1 −1
include/linux/mempolicy.h+0−2
@@ -139,8 +139,6 @@ struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp, · 138 unmodified lines
139struct mempolicy *get_task_policy(struct task_struct *p);139struct mempolicy *get_task_policy(struct task_struct *p);
140struct mempolicy *__get_vma_policy(struct vm_area_struct *vma,140struct mempolicy *__get_vma_policy(struct vm_area_struct *vma,
141 unsigned long addr);141 unsigned long addr);
142struct mempolicy *get_vma_policy(struct vm_area_struct *vma,
143 unsigned long addr);
144bool vma_policy_mof(struct vm_area_struct *vma);142bool vma_policy_mof(struct vm_area_struct *vma);
145 143
146extern void numa_default_policy(void);144extern void numa_default_policy(void);
mm/huge_memory.c+16−26
@@ -648,37 +648,27 @@ release: · 647 unmodified lines
648static inline gfp_t alloc_hugepage_direct_gfpmask(struct vm_area_struct *vma, unsigned long addr)648static inline gfp_t alloc_hugepage_direct_gfpmask(struct vm_area_struct *vma, unsigned long addr)
649{649{
650 const bool vma_madvised = !!(vma->vm_flags & VM_HUGEPAGE);650 const bool vma_madvised = !!(vma->vm_flags & VM_HUGEPAGE);
651 gfp_t this_node = 0;651 const gfp_t gfp_mask = GFP_TRANSHUGE_LIGHT | __GFP_THISNODE;
652
653#ifdef CONFIG_NUMA
654 struct mempolicy *pol;
655 /*
656 * __GFP_THISNODE is used only when __GFP_DIRECT_RECLAIM is not
657 * specified, to express a general desire to stay on the current
658 * node for optimistic allocation attempts. If the defrag mode
659 * and/or madvise hint requires the direct reclaim then we prefer
660 * to fallback to other node rather than node reclaim because that
661 * can lead to excessive reclaim even though there is free memory
662 * on other nodes. We expect that NUMA preferences are specified
663 * by memory policies.
664 */
665 pol = get_vma_policy(vma, addr);
666 if (pol->mode != MPOL_BIND)
667 this_node = __GFP_THISNODE;
668 mpol_cond_put(pol);
669#endif
670 652
653 /* Always do synchronous compaction */
671 if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags))654 if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags))
672 return GFP_TRANSHUGE | (vma_madvised ? 0 : __GFP_NORETRY);655 return GFP_TRANSHUGE | __GFP_THISNODE |
656 (vma_madvised ? 0 : __GFP_NORETRY);
657
658 /* Kick kcompactd and fail quickly */
673 if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags))659 if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags))
674 return GFP_TRANSHUGE_LIGHT | __GFP_KSWAPD_RECLAIM | this_node;660 return gfp_mask | __GFP_KSWAPD_RECLAIM;
661
662 /* Synchronous compaction if madvised, otherwise kick kcompactd */
675 if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags))663 if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags))
676 return GFP_TRANSHUGE_LIGHT | (vma_madvised ? __GFP_DIRECT_RECLAIM :664 return gfp_mask | (vma_madvised ? __GFP_DIRECT_RECLAIM :
677 __GFP_KSWAPD_RECLAIM | this_node);665 __GFP_KSWAPD_RECLAIM);
666
667 /* Only do synchronous compaction if madvised */
678 if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags))668 if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags))
679 return GFP_TRANSHUGE_LIGHT | (vma_madvised ? __GFP_DIRECT_RECLAIM :669 return gfp_mask | (vma_madvised ? __GFP_DIRECT_RECLAIM : 0);
680 this_node);670
681 return GFP_TRANSHUGE_LIGHT | this_node;671 return gfp_mask;
682}672}
683 673
684/* Caller must hold page table lock. */674/* Caller must hold page table lock. */
mm/mempolicy.c+1−1
@@ -1734,7 +1734,7 @@ struct mempolicy *__get_vma_policy(struct vm_area_struct *vma, · 1733 unmodified lines
1734 * freeing by another task. It is the caller's responsibility to free the1734 * freeing by another task. It is the caller's responsibility to free the
1735 * extra reference for shared policies.1735 * extra reference for shared policies.
1736 */1736 */
1737struct mempolicy *get_vma_policy(struct vm_area_struct *vma,1737static struct mempolicy *get_vma_policy(struct vm_area_struct *vma,
1738 unsigned long addr)1738 unsigned long addr)
1739{1739{
1740 struct mempolicy *pol = __get_vma_policy(vma, addr);1740 struct mempolicy *pol = __get_vma_policy(vma, addr);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t