diff options
author | Lee Schermerhorn <lee.schermerhorn@hp.com> | 2008-04-28 05:13:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:58:24 -0400 |
commit | 53f2556b6792ed99fde965f5e061749edd455623 (patch) | |
tree | 82a679e33bc8c305297cbe4655be0dac24728907 /mm/mempolicy.c | |
parent | bea904d54d6faa92400f10c8ea3d3828b8e1eb93 (diff) |
mempolicy: mPOL_PREFERRED cleanups for "local allocation"
Here are a couple of "cleanups" for MPOL_PREFERRED behavior when
v.preferred_node < 0 -- i.e., "local allocation":
1) [do_]get_mempolicy() calls the now renamed get_policy_nodemask()
to fetch the nodemask associated with a policy. Currently,
get_policy_nodemask() returns the set of nodes with memory, when
the policy 'mode' is 'PREFERRED, and the preferred_node is < 0.
Change to return an empty nodemask, as this is what was specified
to achieve "local allocation".
2) When a task is moved into a [new] cpuset, mpol_rebind_policy() is
called to adjust any task and vma policy nodes to be valid in the
new cpuset. However, when the policy is MPOL_PREFERRED, and the
preferred_node is <0, no rebind is necessary. The "local allocation"
indication is valid in any cpuset. Existing code will "do the right
thing" because node_remap() will just return the argument node when
it is outside of the valid range of node ids. However, I think it is
clearer and cleaner to skip the remap explicitly in this case.
3) mpol_to_str() produces a printable, "human readable" string from a
struct mempolicy. For MPOL_PREFERRED with preferred_node <0, show
"local", as this indicates local allocation, as the task migrates
among nodes. Note that this matches the usage of "local allocation"
in libnuma() and numactl. Without this change, I believe that node_set()
[via set_bit()] will set bit 31, resulting in a misleading display.
Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com>
Cc: Christoph Lameter <clameter@sgi.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r-- | mm/mempolicy.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index fea4a5da6e44..7b3ae977b158 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -645,11 +645,9 @@ static void get_policy_nodemask(struct mempolicy *p, nodemask_t *nodes) | |||
645 | *nodes = p->v.nodes; | 645 | *nodes = p->v.nodes; |
646 | break; | 646 | break; |
647 | case MPOL_PREFERRED: | 647 | case MPOL_PREFERRED: |
648 | /* or use current node instead of memory_map? */ | 648 | if (p->v.preferred_node >= 0) |
649 | if (p->v.preferred_node < 0) | ||
650 | *nodes = node_states[N_HIGH_MEMORY]; | ||
651 | else | ||
652 | node_set(p->v.preferred_node, *nodes); | 649 | node_set(p->v.preferred_node, *nodes); |
650 | /* else return empty node mask for local allocation */ | ||
653 | break; | 651 | break; |
654 | default: | 652 | default: |
655 | BUG(); | 653 | BUG(); |
@@ -804,7 +802,7 @@ int do_migrate_pages(struct mm_struct *mm, | |||
804 | int err = 0; | 802 | int err = 0; |
805 | nodemask_t tmp; | 803 | nodemask_t tmp; |
806 | 804 | ||
807 | down_read(&mm->mmap_sem); | 805 | down_read(&mm->mmap_sem); |
808 | 806 | ||
809 | err = migrate_vmas(mm, from_nodes, to_nodes, flags); | 807 | err = migrate_vmas(mm, from_nodes, to_nodes, flags); |
810 | if (err) | 808 | if (err) |
@@ -1948,10 +1946,12 @@ void numa_default_policy(void) | |||
1948 | } | 1946 | } |
1949 | 1947 | ||
1950 | /* | 1948 | /* |
1951 | * Display pages allocated per node and memory policy via /proc. | 1949 | * "local" is pseudo-policy: MPOL_PREFERRED with preferred_node == -1 |
1950 | * Used only for mpol_to_str() | ||
1952 | */ | 1951 | */ |
1952 | #define MPOL_LOCAL (MPOL_INTERLEAVE + 1) | ||
1953 | static const char * const policy_types[] = | 1953 | static const char * const policy_types[] = |
1954 | { "default", "prefer", "bind", "interleave" }; | 1954 | { "default", "prefer", "bind", "interleave", "local" }; |
1955 | 1955 | ||
1956 | /* | 1956 | /* |
1957 | * Convert a mempolicy into a string. | 1957 | * Convert a mempolicy into a string. |
@@ -1962,6 +1962,7 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) | |||
1962 | { | 1962 | { |
1963 | char *p = buffer; | 1963 | char *p = buffer; |
1964 | int l; | 1964 | int l; |
1965 | int nid; | ||
1965 | nodemask_t nodes; | 1966 | nodemask_t nodes; |
1966 | unsigned short mode; | 1967 | unsigned short mode; |
1967 | unsigned short flags = pol ? pol->flags : 0; | 1968 | unsigned short flags = pol ? pol->flags : 0; |
@@ -1978,7 +1979,11 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) | |||
1978 | 1979 | ||
1979 | case MPOL_PREFERRED: | 1980 | case MPOL_PREFERRED: |
1980 | nodes_clear(nodes); | 1981 | nodes_clear(nodes); |
1981 | node_set(pol->v.preferred_node, nodes); | 1982 | nid = pol->v.preferred_node; |
1983 | if (nid < 0) | ||
1984 | mode = MPOL_LOCAL; /* pseudo-policy */ | ||
1985 | else | ||
1986 | node_set(nid, nodes); | ||
1982 | break; | 1987 | break; |
1983 | 1988 | ||
1984 | case MPOL_BIND: | 1989 | case MPOL_BIND: |
@@ -1993,8 +1998,8 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) | |||
1993 | } | 1998 | } |
1994 | 1999 | ||
1995 | l = strlen(policy_types[mode]); | 2000 | l = strlen(policy_types[mode]); |
1996 | if (buffer + maxlen < p + l + 1) | 2001 | if (buffer + maxlen < p + l + 1) |
1997 | return -ENOSPC; | 2002 | return -ENOSPC; |
1998 | 2003 | ||
1999 | strcpy(p, policy_types[mode]); | 2004 | strcpy(p, policy_types[mode]); |
2000 | p += l; | 2005 | p += l; |
@@ -2093,6 +2098,9 @@ static inline void check_huge_range(struct vm_area_struct *vma, | |||
2093 | } | 2098 | } |
2094 | #endif | 2099 | #endif |
2095 | 2100 | ||
2101 | /* | ||
2102 | * Display pages allocated per node and memory policy via /proc. | ||
2103 | */ | ||
2096 | int show_numa_map(struct seq_file *m, void *v) | 2104 | int show_numa_map(struct seq_file *m, void *v) |
2097 | { | 2105 | { |
2098 | struct proc_maps_private *priv = m->private; | 2106 | struct proc_maps_private *priv = m->private; |