aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLee Schermerhorn <lee.schermerhorn@hp.com>2008-04-28 05:13:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-28 11:58:24 -0400
commitaab0b1029f0843756b68e0ed3ca983685bf43ed6 (patch)
tree95a0546c908a1c7a3bf1353f433ff1464faf68db
parent45c4745af381851b0406d8e4db99e62e265691c2 (diff)
mempolicy: mark shared policies for unref
As part of yet another rework of mempolicy reference counting, we want to be able to identify shared policies efficiently, because they have an extra ref taken on lookup that needs to be removed when we're finished using the policy. Note: the extra ref is required because the policies are shared between tasks/processes and can be changed/freed by one task while another task is using them--e.g., for page allocation. Building on David Rientjes mempolicy "mode flags" enhancement, this patch indicates a "shared" policy by setting a new MPOL_F_SHARED flag in the flags member of the struct mempolicy added by David. MPOL_F_SHARED, and any future "internal mode flags" are reserved from bit zero up, as they will never be passed in the upper bits of the mode argument of a mempolicy API. I set the MPOL_F_SHARED flag when the policy is installed in the shared policy rb-tree. Don't need/want to clear the flag when removing from the tree as the mempolicy is freed [unref'd] internally to the sp_delete() function. However, a task could hold another reference on this mempolicy from a prior lookup. We need the MPOL_F_SHARED flag to stay put so that any tasks holding a ref will unref, eventually freeing, the mempolicy. A later patch in this series will introduce a function to conditionally unref [mpol_free] a policy. The MPOL_F_SHARED flag is one reason [currently the only reason] to unref/free a policy via the conditional free. 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>
-rw-r--r--include/linux/mempolicy.h7
-rw-r--r--mm/mempolicy.c1
2 files changed, 8 insertions, 0 deletions
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 9080fab1426d..017def89e568 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -44,6 +44,13 @@ enum {
44#define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mapping */ 44#define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mapping */
45#define MPOL_MF_INTERNAL (1<<3) /* Internal flags start here */ 45#define MPOL_MF_INTERNAL (1<<3) /* Internal flags start here */
46 46
47/*
48 * Internal flags that share the struct mempolicy flags word with
49 * "mode flags". These flags are allocated from bit 0 up, as they
50 * are never OR'ed into the mode in mempolicy API arguments.
51 */
52#define MPOL_F_SHARED (1 << 0) /* identify shared policies */
53
47#ifdef __KERNEL__ 54#ifdef __KERNEL__
48 55
49#include <linux/mmzone.h> 56#include <linux/mmzone.h>
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 5e7eea2dc8b4..78b18a60b9b2 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1750,6 +1750,7 @@ static struct sp_node *sp_alloc(unsigned long start, unsigned long end,
1750 n->start = start; 1750 n->start = start;
1751 n->end = end; 1751 n->end = end;
1752 mpol_get(pol); 1752 mpol_get(pol);
1753 pol->flags |= MPOL_F_SHARED; /* for unref */
1753 n->policy = pol; 1754 n->policy = pol;
1754 return n; 1755 return n;
1755} 1756}