From 71fe804b6d56d6a7aed680e096901434cef6a2c3 Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Mon, 28 Apr 2008 02:13:26 -0700 Subject: mempolicy: use struct mempolicy pointer in shmem_sb_info This patch replaces the mempolicy mode, mode_flags, and nodemask in the shmem_sb_info struct with a struct mempolicy pointer, initialized to NULL. This removes dependency on the details of mempolicy from shmem.c and hugetlbfs inode.c and simplifies the interfaces. mpol_parse_str() in mempolicy.c is changed to return, via a pointer to a pointer arg, a struct mempolicy pointer on success. For MPOL_DEFAULT, the returned pointer is NULL. Further, mpol_parse_str() now takes a 'no_context' argument that causes the input nodemask to be stored in the w.user_nodemask of the created mempolicy for use when the mempolicy is installed in a tmpfs inode shared policy tree. At that time, any cpuset contextualization is applied to the original input nodemask. This preserves the previous behavior where the input nodemask was stored in the superblock. We can think of the returned mempolicy as "context free". Because mpol_parse_str() is now calling mpol_new(), we can remove from mpol_to_str() the semantic checks that mpol_new() already performs. Add 'no_context' parameter to mpol_to_str() to specify that it should format the nodemask in w.user_nodemask for 'bind' and 'interleave' policies. Change mpol_shared_policy_init() to take a pointer to a "context free" struct mempolicy and to create a new, "contextualized" mempolicy using the mode, mode_flags and user_nodemask from the input mempolicy. Note: we know that the mempolicy passed to mpol_to_str() or mpol_shared_policy_init() from a tmpfs superblock is "context free". This is currently the only instance thereof. However, if we found more uses for this concept, and introduced any ambiguity as to whether a mempolicy was context free or not, we could add another internal mode flag to identify context free mempolicies. Then, we could remove the 'no_context' argument from mpol_to_str(). Added shmem_get_sbmpol() to return a reference counted superblock mempolicy, if one exists, to pass to mpol_shared_policy_init(). We must add the reference under the sb stat_lock to prevent races with replacement of the mpol by remount. This reference is removed in mpol_shared_policy_init(). [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: another build fix] [akpm@linux-foundation.org: yet another build fix] Signed-off-by: Lee Schermerhorn Cc: Christoph Lameter Cc: David Rientjes Cc: Mel Gorman Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mempolicy.h | 22 +++++++++++----------- include/linux/shmem_fs.h | 4 +--- 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index dcc17378c952..3a39570b81b8 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -182,8 +182,7 @@ struct shared_policy { spinlock_t lock; }; -void mpol_shared_policy_init(struct shared_policy *info, unsigned short mode, - unsigned short flags, nodemask_t *nodes); +void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol); int mpol_set_shared_policy(struct shared_policy *info, struct vm_area_struct *vma, struct mempolicy *new); @@ -216,10 +215,10 @@ int do_migrate_pages(struct mm_struct *mm, #ifdef CONFIG_TMPFS -extern int mpol_parse_str(char *str, unsigned short *mode, - unsigned short *mode_flags, nodemask_t *policy_nodes); +extern int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context); -extern int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol); +extern int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, + int no_context); #endif #else @@ -262,8 +261,8 @@ static inline int mpol_set_shared_policy(struct shared_policy *info, return -EINVAL; } -static inline void mpol_shared_policy_init(struct shared_policy *info, - unsigned short mode, unsigned short flags, nodemask_t *nodes) +static inline void mpol_shared_policy_init(struct shared_policy *sp, + struct mempolicy *mpol) { } @@ -322,13 +321,14 @@ static inline void check_highest_zone(int k) } #ifdef CONFIG_TMPFS -static inline int mpol_parse_str(char *value, unsigned short *policy, - unsigned short flags, nodemask_t *policy_nodes) +static inline int mpol_parse_str(char *str, struct mempolicy **mpol, + int no_context) { - return 1; + return 1; /* error */ } -static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) +static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, + int no_context) { return 0; } diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index d7699a628d78..f2d12d5a21b8 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -34,9 +34,7 @@ struct shmem_sb_info { uid_t uid; /* Mount uid for root directory */ 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 */ + struct mempolicy *mpol; /* default memory policy for mappings */ }; static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) -- cgit v1.2.2