|
@@ -1850,18 +1850,24 @@ struct page *
|
|
|
alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
|
|
|
unsigned long addr, int node)
|
|
|
{
|
|
|
- struct mempolicy *pol = get_vma_policy(current, vma, addr);
|
|
|
+ struct mempolicy *pol;
|
|
|
struct zonelist *zl;
|
|
|
struct page *page;
|
|
|
+ unsigned int cpuset_mems_cookie;
|
|
|
+
|
|
|
+retry_cpuset:
|
|
|
+ pol = get_vma_policy(current, vma, addr);
|
|
|
+ cpuset_mems_cookie = get_mems_allowed();
|
|
|
|
|
|
- get_mems_allowed();
|
|
|
if (unlikely(pol->mode == MPOL_INTERLEAVE)) {
|
|
|
unsigned nid;
|
|
|
|
|
|
nid = interleave_nid(pol, vma, addr, PAGE_SHIFT + order);
|
|
|
mpol_cond_put(pol);
|
|
|
page = alloc_page_interleave(gfp, order, nid);
|
|
|
- put_mems_allowed();
|
|
|
+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))
|
|
|
+ goto retry_cpuset;
|
|
|
+
|
|
|
return page;
|
|
|
}
|
|
|
zl = policy_zonelist(gfp, pol, node);
|
|
@@ -1872,7 +1878,8 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
|
|
|
struct page *page = __alloc_pages_nodemask(gfp, order,
|
|
|
zl, policy_nodemask(gfp, pol));
|
|
|
__mpol_put(pol);
|
|
|
- put_mems_allowed();
|
|
|
+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))
|
|
|
+ goto retry_cpuset;
|
|
|
return page;
|
|
|
}
|
|
|
/*
|
|
@@ -1880,7 +1887,8 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
|
|
|
*/
|
|
|
page = __alloc_pages_nodemask(gfp, order, zl,
|
|
|
policy_nodemask(gfp, pol));
|
|
|
- put_mems_allowed();
|
|
|
+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))
|
|
|
+ goto retry_cpuset;
|
|
|
return page;
|
|
|
}
|
|
|
|
|
@@ -1907,11 +1915,14 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order)
|
|
|
{
|
|
|
struct mempolicy *pol = current->mempolicy;
|
|
|
struct page *page;
|
|
|
+ unsigned int cpuset_mems_cookie;
|
|
|
|
|
|
if (!pol || in_interrupt() || (gfp & __GFP_THISNODE))
|
|
|
pol = &default_policy;
|
|
|
|
|
|
- get_mems_allowed();
|
|
|
+retry_cpuset:
|
|
|
+ cpuset_mems_cookie = get_mems_allowed();
|
|
|
+
|
|
|
/*
|
|
|
* No reference counting needed for current->mempolicy
|
|
|
* nor system default_policy
|
|
@@ -1922,7 +1933,10 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order)
|
|
|
page = __alloc_pages_nodemask(gfp, order,
|
|
|
policy_zonelist(gfp, pol, numa_node_id()),
|
|
|
policy_nodemask(gfp, pol));
|
|
|
- put_mems_allowed();
|
|
|
+
|
|
|
+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))
|
|
|
+ goto retry_cpuset;
|
|
|
+
|
|
|
return page;
|
|
|
}
|
|
|
EXPORT_SYMBOL(alloc_pages_current);
|