diff options
author | David Rientjes <rientjes@google.com> | 2008-04-28 02:12:25 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 08:58:19 -0700 |
commit | 028fec414d803117eb4b2ed12acb4dd5da65b32d (patch) | |
tree | 427f37ea0331369c1babc55c424c4fd2ac3b39f5 /include | |
parent | a3b51e0142d1be156ac697eaadadd6cfbb7ba32b (diff) |
mempolicy: support optional mode flags
With the evolution of mempolicies, it is necessary to support mempolicy mode
flags that specify how the policy shall behave in certain circumstances. The
most immediate need for mode flag support is to suppress remapping the
nodemask of a policy at the time of rebind.
Both the mempolicy mode and flags are passed by the user in the 'int policy'
formal of either the set_mempolicy() or mbind() syscall. A new constant,
MPOL_MODE_FLAGS, represents the union of legal optional flags that may be
passed as part of this int. Mempolicies that include illegal flags as part of
their policy are rejected as invalid.
An additional member to struct mempolicy is added to support the mode flags:
struct mempolicy {
...
unsigned short policy;
unsigned short flags;
}
The splitting of the 'int' actual passed by the user is done in
sys_set_mempolicy() and sys_mbind() for their respective syscalls. This is
done by intersecting the actual with MPOL_MODE_FLAGS, rejecting the syscall of
there are additional flags, and storing it in the new 'flags' member of struct
mempolicy. The intersection of the actual with ~MPOL_MODE_FLAGS is stored in
the 'policy' member of the struct and all current users of pol->policy remain
unchanged.
The union of the policy mode and optional mode flags is passed back to the
user in get_mempolicy().
This combination of mode and flags within the same actual does not break
userspace code that relies on get_mempolicy(&policy, ...) and either
switch (policy) {
case MPOL_BIND:
...
case MPOL_INTERLEAVE:
...
};
statements or
if (policy == MPOL_INTERLEAVE) {
...
}
statements. Such applications would need to use optional mode flags when
calling set_mempolicy() or mbind() for these previously implemented statements
to stop working. If an application does start using optional mode flags, it
will need to mask the optional flags off the policy in switch and conditional
statements that only test mode.
An additional member is also added to struct shmem_sb_info to store the
optional mode flags.
[hugh@veritas.com: shmem mpol: fix build warning]
Cc: Paul Jackson <pj@sgi.com>
Cc: Christoph Lameter <clameter@sgi.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mempolicy.h | 20 | ||||
-rw-r--r-- | include/linux/shmem_fs.h | 1 |
2 files changed, 18 insertions, 3 deletions
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 389a06e8ee2..f2bab4d2fc4 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -8,6 +8,12 @@ * Copyright 2003,2004 Andi Kleen SuSE Labs */ +/* + * Both the MPOL_* mempolicy mode and the MPOL_F_* optional mode flags are + * passed by the user to either set_mempolicy() or mbind() in an 'int' actual. + * The MPOL_MODE_FLAGS macro determines the legal set of optional mode flags. + */ + /* Policies */ enum { MPOL_DEFAULT, @@ -17,7 +23,14 @@ enum { MPOL_MAX, /* always last member of enum */ }; -/* Flags for get_mem_policy */ +/* Flags for set_mempolicy */ +/* + * MPOL_MODE_FLAGS is the union of all possible optional mode flags passed to + * either set_mempolicy() or mbind(). + */ +#define MPOL_MODE_FLAGS (0) + +/* Flags for get_mempolicy */ #define MPOL_F_NODE (1<<0) /* return next IL mode instead of node mask */ #define MPOL_F_ADDR (1<<1) /* look up vma using address */ #define MPOL_F_MEMS_ALLOWED (1<<2) /* return allowed memories */ @@ -66,6 +79,7 @@ struct mm_struct; struct mempolicy { atomic_t refcnt; unsigned short policy; /* See MPOL_* above */ + unsigned short flags; /* See set_mempolicy() MPOL_F_* above */ union { short preferred_node; /* preferred */ nodemask_t nodes; /* interleave/bind */ @@ -136,7 +150,7 @@ struct shared_policy { }; void mpol_shared_policy_init(struct shared_policy *info, unsigned short policy, - nodemask_t *nodes); + unsigned short flags, nodemask_t *nodes); int mpol_set_shared_policy(struct shared_policy *info, struct vm_area_struct *vma, struct mempolicy *new); @@ -203,7 +217,7 @@ static inline int mpol_set_shared_policy(struct shared_policy *info, } static inline void mpol_shared_policy_init(struct shared_policy *info, - unsigned short policy, nodemask_t *nodes) + unsigned short policy, unsigned short flags, nodemask_t *nodes) { } diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 639a4070708..d7699a628d7 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -35,6 +35,7 @@ struct shmem_sb_info { gid_t gid; /* Mount gid for root directory */ mode_t mode; /* Mount mode for root directory */ unsigned short policy; /* Default NUMA memory alloc policy */ + unsigned short flags; /* Optional mempolicy flags */ nodemask_t policy_nodes; /* nodemask for preferred and bind */ }; |