Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 93998
b: refs/heads/master
c: 3e1f064
h: refs/heads/master
v: v3
  • Loading branch information
David Rientjes authored and Linus Torvalds committed Apr 28, 2008
1 parent 0b27195 commit fdcb632
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3842b46de626d1a3c44ad280d67ab0a4dc047d13
refs/heads/master: 3e1f064562fcff7bf3856bc1d00dfa84d4f121cc
16 changes: 14 additions & 2 deletions trunk/Documentation/vm/numa_memory_policy.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ Components of Memory Policies
local allocation for a specific range of addresses--i.e. for
VMA policies.

It is possible for the user to specify that local allocation is
always preferred by passing an empty nodemask with this mode.
If an empty nodemask is passed, the policy cannot use the
MPOL_F_STATIC_NODES or MPOL_F_RELATIVE_NODES flags described
below.

MPOL_INTERLEAVED: This mode specifies that page allocations be
interleaved, on a page granularity, across the nodes specified in
the policy. This mode also behaves slightly differently, based on
Expand Down Expand Up @@ -254,7 +260,10 @@ Components of Memory Policies
occurs over that node. If no nodes from the user's nodemask are
now allowed, the Default behavior is used.

MPOL_F_STATIC_NODES cannot be used with MPOL_F_RELATIVE_NODES.
MPOL_F_STATIC_NODES cannot be combined with the
MPOL_F_RELATIVE_NODES flag. It also cannot be used for
MPOL_PREFERRED policies that were created with an empty nodemask
(local allocation).

MPOL_F_RELATIVE_NODES: This flag specifies that the nodemask passed
by the user will be mapped relative to the set of the task or VMA's
Expand Down Expand Up @@ -301,7 +310,10 @@ Components of Memory Policies
set of memory nodes allowed by the task's cpuset, as that may
change over time.

MPOL_F_RELATIVE_NODES cannot be used with MPOL_F_STATIC_NODES.
MPOL_F_RELATIVE_NODES cannot be combined with the
MPOL_F_STATIC_NODES flag. It also cannot be used for
MPOL_PREFERRED policies that were created with an empty nodemask
(local allocation).

MEMORY POLICY APIs

Expand Down
42 changes: 26 additions & 16 deletions trunk/mm/mempolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,27 +181,43 @@ static struct mempolicy *mpol_new(unsigned short mode, unsigned short flags,
{
struct mempolicy *policy;
nodemask_t cpuset_context_nmask;
int localalloc = 0;
int ret;

pr_debug("setting mode %d flags %d nodes[0] %lx\n",
mode, flags, nodes ? nodes_addr(*nodes)[0] : -1);

if (mode == MPOL_DEFAULT)
return NULL;
if (!nodes || nodes_empty(*nodes)) {
if (mode != MPOL_PREFERRED)
if (mode == MPOL_DEFAULT) {
if (nodes && !nodes_empty(*nodes))
return ERR_PTR(-EINVAL);
localalloc = 1; /* special case: no mode flags */
return NULL;
}
VM_BUG_ON(!nodes);

/*
* MPOL_PREFERRED cannot be used with MPOL_F_STATIC_NODES or
* MPOL_F_RELATIVE_NODES if the nodemask is empty (local allocation).
* All other modes require a valid pointer to a non-empty nodemask.
*/
if (mode == MPOL_PREFERRED) {
if (nodes_empty(*nodes)) {
if (((flags & MPOL_F_STATIC_NODES) ||
(flags & MPOL_F_RELATIVE_NODES)))
return ERR_PTR(-EINVAL);
nodes = NULL; /* flag local alloc */
}
} else if (nodes_empty(*nodes))
return ERR_PTR(-EINVAL);
policy = kmem_cache_alloc(policy_cache, GFP_KERNEL);
if (!policy)
return ERR_PTR(-ENOMEM);
atomic_set(&policy->refcnt, 1);
policy->policy = mode;
policy->flags = flags;

if (!localalloc) {
policy->flags = flags;
if (nodes) {
/*
* cpuset related setup doesn't apply to local allocation
*/
cpuset_update_task_memory_state();
if (flags & MPOL_F_RELATIVE_NODES)
mpol_relative_nodemask(&cpuset_context_nmask, nodes,
Expand All @@ -217,7 +233,7 @@ static struct mempolicy *mpol_new(unsigned short mode, unsigned short flags,
}

ret = mpol_ops[mode].create(policy,
localalloc ? NULL : &cpuset_context_nmask);
nodes ? &cpuset_context_nmask : NULL);
if (ret < 0) {
kmem_cache_free(policy_cache, policy);
return ERR_PTR(ret);
Expand Down Expand Up @@ -259,23 +275,17 @@ static void mpol_rebind_preferred(struct mempolicy *pol,
{
nodemask_t tmp;

/*
* check 'STATIC_NODES first, as preferred_node == -1 may be
* a temporary, "fallback" state for this policy.
*/
if (pol->flags & MPOL_F_STATIC_NODES) {
int node = first_node(pol->w.user_nodemask);

if (node_isset(node, *nodes))
pol->v.preferred_node = node;
else
pol->v.preferred_node = -1;
} else if (pol->v.preferred_node == -1) {
return; /* no remap required for explicit local alloc */
} else if (pol->flags & MPOL_F_RELATIVE_NODES) {
mpol_relative_nodemask(&tmp, &pol->w.user_nodemask, nodes);
pol->v.preferred_node = first_node(tmp);
} else {
} else if (pol->v.preferred_node != -1) {
pol->v.preferred_node = node_remap(pol->v.preferred_node,
pol->w.cpuset_mems_allowed,
*nodes);
Expand Down

0 comments on commit fdcb632

Please sign in to comment.