|
@@ -2060,8 +2060,36 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
|
|
|
nmask = policy_nodemask(gfp, pol);
|
|
|
if (!nmask || node_isset(hpage_node, *nmask)) {
|
|
|
mpol_cond_put(pol);
|
|
|
- page = __alloc_pages_node(hpage_node,
|
|
|
- gfp | __GFP_THISNODE, order);
|
|
|
+ /*
|
|
|
+ * We cannot invoke reclaim if __GFP_THISNODE
|
|
|
+ * is set. Invoking reclaim with
|
|
|
+ * __GFP_THISNODE set, would cause THP
|
|
|
+ * allocations to trigger heavy swapping
|
|
|
+ * despite there may be tons of free memory
|
|
|
+ * (including potentially plenty of THP
|
|
|
+ * already available in the buddy) on all the
|
|
|
+ * other NUMA nodes.
|
|
|
+ *
|
|
|
+ * At most we could invoke compaction when
|
|
|
+ * __GFP_THISNODE is set (but we would need to
|
|
|
+ * refrain from invoking reclaim even if
|
|
|
+ * compaction returned COMPACT_SKIPPED because
|
|
|
+ * there wasn't not enough memory to succeed
|
|
|
+ * compaction). For now just avoid
|
|
|
+ * __GFP_THISNODE instead of limiting the
|
|
|
+ * allocation path to a strict and single
|
|
|
+ * compaction invocation.
|
|
|
+ *
|
|
|
+ * Supposedly if direct reclaim was enabled by
|
|
|
+ * the caller, the app prefers THP regardless
|
|
|
+ * of the node it comes from so this would be
|
|
|
+ * more desiderable behavior than only
|
|
|
+ * providing THP originated from the local
|
|
|
+ * node in such case.
|
|
|
+ */
|
|
|
+ if (!(gfp & __GFP_DIRECT_RECLAIM))
|
|
|
+ gfp |= __GFP_THISNODE;
|
|
|
+ page = __alloc_pages_node(hpage_node, gfp, order);
|
|
|
goto out;
|
|
|
}
|
|
|
}
|