|
@@ -1116,8 +1116,8 @@ static struct page *new_page(struct page *page, unsigned long start)
|
|
} else if (PageTransHuge(page)) {
|
|
} else if (PageTransHuge(page)) {
|
|
struct page *thp;
|
|
struct page *thp;
|
|
|
|
|
|
- thp = alloc_hugepage_vma(GFP_TRANSHUGE, vma, address,
|
|
|
|
- HPAGE_PMD_ORDER);
|
|
|
|
|
|
+ thp = alloc_pages_vma(GFP_TRANSHUGE, HPAGE_PMD_ORDER, vma,
|
|
|
|
+ address, numa_node_id());
|
|
if (!thp)
|
|
if (!thp)
|
|
return NULL;
|
|
return NULL;
|
|
prep_transhuge_page(thp);
|
|
prep_transhuge_page(thp);
|
|
@@ -1662,7 +1662,7 @@ struct mempolicy *__get_vma_policy(struct vm_area_struct *vma,
|
|
* freeing by another task. It is the caller's responsibility to free the
|
|
* freeing by another task. It is the caller's responsibility to free the
|
|
* extra reference for shared policies.
|
|
* extra reference for shared policies.
|
|
*/
|
|
*/
|
|
-static struct mempolicy *get_vma_policy(struct vm_area_struct *vma,
|
|
|
|
|
|
+struct mempolicy *get_vma_policy(struct vm_area_struct *vma,
|
|
unsigned long addr)
|
|
unsigned long addr)
|
|
{
|
|
{
|
|
struct mempolicy *pol = __get_vma_policy(vma, addr);
|
|
struct mempolicy *pol = __get_vma_policy(vma, addr);
|
|
@@ -2011,7 +2011,6 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
|
|
* @vma: Pointer to VMA or NULL if not available.
|
|
* @vma: Pointer to VMA or NULL if not available.
|
|
* @addr: Virtual Address of the allocation. Must be inside the VMA.
|
|
* @addr: Virtual Address of the allocation. Must be inside the VMA.
|
|
* @node: Which node to prefer for allocation (modulo policy).
|
|
* @node: Which node to prefer for allocation (modulo policy).
|
|
- * @hugepage: for hugepages try only the preferred node if possible
|
|
|
|
*
|
|
*
|
|
* This function allocates a page from the kernel page pool and applies
|
|
* This function allocates a page from the kernel page pool and applies
|
|
* a NUMA policy associated with the VMA or the current process.
|
|
* a NUMA policy associated with the VMA or the current process.
|
|
@@ -2022,7 +2021,7 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
|
|
*/
|
|
*/
|
|
struct page *
|
|
struct page *
|
|
alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
|
|
alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
|
|
- unsigned long addr, int node, bool hugepage)
|
|
|
|
|
|
+ unsigned long addr, int node)
|
|
{
|
|
{
|
|
struct mempolicy *pol;
|
|
struct mempolicy *pol;
|
|
struct page *page;
|
|
struct page *page;
|
|
@@ -2040,60 +2039,6 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- if (unlikely(IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && hugepage)) {
|
|
|
|
- int hpage_node = node;
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * For hugepage allocation and non-interleave policy which
|
|
|
|
- * allows the current node (or other explicitly preferred
|
|
|
|
- * node) we only try to allocate from the current/preferred
|
|
|
|
- * node and don't fall back to other nodes, as the cost of
|
|
|
|
- * remote accesses would likely offset THP benefits.
|
|
|
|
- *
|
|
|
|
- * If the policy is interleave, or does not allow the current
|
|
|
|
- * node in its nodemask, we allocate the standard way.
|
|
|
|
- */
|
|
|
|
- if (pol->mode == MPOL_PREFERRED &&
|
|
|
|
- !(pol->flags & MPOL_F_LOCAL))
|
|
|
|
- hpage_node = pol->v.preferred_node;
|
|
|
|
-
|
|
|
|
- nmask = policy_nodemask(gfp, pol);
|
|
|
|
- if (!nmask || node_isset(hpage_node, *nmask)) {
|
|
|
|
- mpol_cond_put(pol);
|
|
|
|
- /*
|
|
|
|
- * 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;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
nmask = policy_nodemask(gfp, pol);
|
|
nmask = policy_nodemask(gfp, pol);
|
|
preferred_nid = policy_node(gfp, pol, node);
|
|
preferred_nid = policy_node(gfp, pol, node);
|
|
page = __alloc_pages_nodemask(gfp, order, preferred_nid, nmask);
|
|
page = __alloc_pages_nodemask(gfp, order, preferred_nid, nmask);
|