Linux NUMA userland tools development
 help / color / mirror / Atom feed
From: Lee Schermerhorn <lee.schermerhorn@hp.com>
To: linux-numa@vger.kernel.org
Cc: akpm@linux-foundation.org, Mel Gorman <mel@csn.ul.ie>,
	cl@linux-foundation.org, Nick Piggin <npiggin@kernel.dk>,
	Hugh Dickins <hughd@google.com>,
	KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
	andi@firstfloor.org, David Rientjes <rientjes@google.com>,
	Avi Kivity <avi@redhat.com>,
	Andrea Arcangeli <aarcange@redhat.com>
Subject: [PATCH/RFC 13/14] Shared Policy: per cpuset mapped file policy control
Date: Thu, 11 Nov 2010 14:13:39 -0500	[thread overview]
Message-ID: <20101111191339.12370.87740.sendpatchset@zaphod.localdomain> (raw)
In-Reply-To: <20101111191147.12370.66074.sendpatchset@zaphod.localdomain>

Shared Policy Infrastracture - per cpuset mapped file policy control

As for shared hugetlbfs file mappings, add a per cpuset
"shared_file_policy" control file to enable shared file policy
for tasks in the cpuset.  Default is disabled, resulting in
the old behavior--i.e., we continue to ignore mbind() on
address ranges backed by shared file mappings.  The
"shared_file_policy" file depends on CONFIG_NUMA.

Why "per cpuset"?  cpusets are numa-aware task groupings and
memory policy is a numa concept.  Applications that need/want
shared file policy can be grouped in a cpuset with this feature
enabled, while other applications in other cpusets need not see
this feature.

The default may be overridden--e.g., to enabled--on the kernel
command line using the "shared_file_policy_default" parameter.
When cpusets are configured, this policy sets the default value
of "shared_file_policy" for the top cpuset, which is then inherited
by all subsequently created descendant cpusets.  When cpusets are
not configured, this parameter sets the "shared_file_policy_enabled"
flag for the init process, which is then inherited by all descendant
processes.

A subsequent patch will "hook up" generic file .{set|get}_policy
vm_ops to install a shared policy on a memory mapped file
if the capability has been enabled for the caller's cpuset, or
for the system in the case of no cpusets.


Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com>
 
 include/linux/cpuset.h        |    6 ++++++
 include/linux/sched.h         |   19 ++++++++++++++++++-
 include/linux/shared_policy.h |    2 ++
 kernel/cpuset.c               |   42 +++++++++++++++++++++++++++++++++++++++++-
 mm/mempolicy.c                |   20 +++++++++++++++++++-
 5 files changed, 86 insertions(+), 3 deletions(-)

Index: linux-2.6.36-mmotm-101103-1217/include/linux/sched.h
===================================================================
--- linux-2.6.36-mmotm-101103-1217.orig/include/linux/sched.h
+++ linux-2.6.36-mmotm-101103-1217/include/linux/sched.h
@@ -1455,7 +1455,8 @@ struct task_struct {
 #ifdef CONFIG_NUMA
 	struct mempolicy *mempolicy;	/* Protected by alloc_lock */
 	short il_next;
-	short shared_huge_policy_enabled;
+	short shared_huge_policy_enabled:1;
+	short shared_file_policy_enabled:1;
 #endif
 	atomic_t fs_excl;	/* holding fs exclusive resources */
 	struct rcu_head rcu;
@@ -1882,12 +1883,28 @@ static inline int shared_huge_policy_ena
 	return tsk->shared_huge_policy_enabled;
 }
 
+static inline void set_shared_file_policy_enabled(struct task_struct *tsk,
+							int val)
+{
+	tsk->shared_file_policy_enabled = !!val;
+}
+static inline int shared_file_policy_enabled(struct task_struct *tsk)
+{
+	return tsk->shared_file_policy_enabled;
+}
+
 #else
 static void set_shared_huge_policy_enabled(struct task_struct *tsk, int val) { }
 static int shared_huge_policy_enabled(struct task_struct *tsk)
 {
 	return 0;
 }
+
+static void set_shared_file_policy_enabled(struct task_struct *tsk, int val) { }
+static int shared_file_policy_enabled(struct task_struct *tsk)
+{
+	return 0;
+}
 #endif
 
 #ifdef CONFIG_HOTPLUG_CPU
Index: linux-2.6.36-mmotm-101103-1217/kernel/cpuset.c
===================================================================
--- linux-2.6.36-mmotm-101103-1217.orig/kernel/cpuset.c
+++ linux-2.6.36-mmotm-101103-1217/kernel/cpuset.c
@@ -133,6 +133,7 @@ typedef enum {
 	CS_SPREAD_PAGE,
 	CS_SPREAD_SLAB,
 	CS_SHARED_HUGE_POLICY,
+ 	CS_SHARED_FILE_POLICY,
 } cpuset_flagbits_t;
 
 /* convenient tests for these bits */
@@ -176,6 +177,11 @@ static inline int is_shared_huge_policy(
 	return test_bit(CS_SHARED_HUGE_POLICY, &cs->flags);
 }
 
+static inline int is_shared_file_policy(const struct cpuset *cs)
+{
+	return test_bit(CS_SHARED_FILE_POLICY, &cs->flags);
+}
+
 static struct cpuset top_cpuset = {
 	.flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)),
 };
@@ -331,6 +337,10 @@ static void cpuset_update_task_cpuset_fl
 		set_shared_huge_policy_enabled(tsk, 1);
 	else
 		set_shared_huge_policy_enabled(tsk, 0);
+	if (is_shared_file_policy(cs))
+		set_shared_file_policy_enabled(tsk, 1);
+	else
+		set_shared_file_policy_enabled(tsk, 0);
 }
 
 /*
@@ -1270,7 +1280,8 @@ static int update_flag(cpuset_flagbits_t
 
 	cpuset_flags_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs))
 			|| (is_spread_page(cs) != is_spread_page(trialcs))
-			|| (is_shared_huge_policy(cs) != is_shared_huge_policy(trialcs)));
+			|| (is_shared_huge_policy(cs) != is_shared_huge_policy(trialcs))
+			|| (is_shared_file_policy(cs) != is_shared_file_policy(trialcs)));
 
 	mutex_lock(&callback_mutex);
 	cs->flags = trialcs->flags;
@@ -1507,6 +1518,7 @@ typedef enum {
 	FILE_SPREAD_PAGE,
 	FILE_SPREAD_SLAB,
 	FILE_SHARED_HUGE_POLICY,
+	FILE_SHARED_FILE_POLICY,
 } cpuset_filetype_t;
 
 static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val)
@@ -1549,6 +1561,9 @@ static int cpuset_write_u64(struct cgrou
 	case FILE_SHARED_HUGE_POLICY:
 		retval = update_flag(CS_SHARED_HUGE_POLICY, cs, val);
 		break;
+	case FILE_SHARED_FILE_POLICY:
+		retval = update_flag(CS_SHARED_FILE_POLICY, cs, val);
+		break;
 	default:
 		retval = -EINVAL;
 		break;
@@ -1715,6 +1730,8 @@ static u64 cpuset_read_u64(struct cgroup
 		return is_spread_slab(cs);
 	case FILE_SHARED_HUGE_POLICY:
 		return is_shared_huge_policy(cs);
+	case FILE_SHARED_FILE_POLICY:
+		return is_shared_file_policy(cs);
 	default:
 		BUG();
 	}
@@ -1839,6 +1856,13 @@ static struct cftype cft_shared_huge_pol
 	.private = FILE_SHARED_HUGE_POLICY,
 };
 
+static struct cftype cft_shared_file_policy = {
+	.name = "shared_file_policy",
+	.read_u64 = cpuset_read_u64,
+	.write_u64 = cpuset_write_u64,
+	.private = FILE_SHARED_FILE_POLICY,
+};
+
 static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont)
 {
 	int err;
@@ -1852,6 +1876,9 @@ static int cpuset_populate(struct cgroup
 	err = add_shared_xxx_policy_file(cont, ss, &cft_shared_huge_policy);
 	if (err < 0)
 		return err;
+	err = add_shared_xxx_policy_file(cont, ss, &cft_shared_file_policy);
+	if (err < 0)
+		return err;
 	/* memory_pressure_enabled is in root cpuset only */
 	if (!cont->parent)
 		err = cgroup_add_file(cont, ss,
@@ -1928,6 +1955,8 @@ static struct cgroup_subsys_state *cpuse
 		set_bit(CS_SPREAD_SLAB, &cs->flags);
 	if (is_shared_huge_policy(parent))
 		set_bit(CS_SHARED_HUGE_POLICY, &cs->flags);
+	if (is_shared_file_policy(parent))
+		set_bit(CS_SHARED_FILE_POLICY, &cs->flags);
 	set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
 	cpumask_clear(cs->cpus_allowed);
 	nodes_clear(cs->mems_allowed);
@@ -2012,6 +2041,17 @@ void __init cpuset_init_shared_huge_poli
 }
 
 /**
+ * cpuset_init_shared_file_policy - set default value for shared_file_policy
+ * enablement.
+ */
+
+void __init cpuset_init_shared_file_policy(int dflt)
+{
+	if (dflt)
+		set_bit(CS_SHARED_FILE_POLICY, &top_cpuset.flags);
+}
+
+/**
  * cpuset_do_move_task - move a given task to another cpuset
  * @tsk: pointer to task_struct the task to move
  * @scan: struct cgroup_scanner contained in its struct cpuset_hotplug_scanner
Index: linux-2.6.36-mmotm-101103-1217/include/linux/cpuset.h
===================================================================
--- linux-2.6.36-mmotm-101103-1217.orig/include/linux/cpuset.h
+++ linux-2.6.36-mmotm-101103-1217/include/linux/cpuset.h
@@ -149,6 +149,7 @@ static inline int add_shared_xxx_policy_
 #endif
 
 extern void __init cpuset_init_shared_huge_policy(int dflt);
+extern void __init cpuset_init_shared_file_policy(int dflt);
 
 #else /* !CONFIG_CPUSETS */
 
@@ -268,6 +269,11 @@ static inline void cpuset_init_shared_hu
 {
 	current->shared_file_policy_enabled = dflt;
 }
+
+static inline void cpuset_init_shared_file_policy(int dflt)
+{
+	current->shared_file_policy_enabled = dflt;
+}
 
 #endif /* !CONFIG_CPUSETS */
 
Index: linux-2.6.36-mmotm-101103-1217/mm/mempolicy.c
===================================================================
--- linux-2.6.36-mmotm-101103-1217.orig/mm/mempolicy.c
+++ linux-2.6.36-mmotm-101103-1217/mm/mempolicy.c
@@ -2131,6 +2131,23 @@ static int __init setup_shared_huge_poli
 __setup("shared_huge_policy_default=", setup_shared_huge_policy_default);
 
 /*
+ * default state of per cpuset shared_file_policy_enablement
+ */
+int shared_file_policy_default;
+
+static int __init setup_shared_file_policy_default(char *str)
+{
+	int ret, val;
+	ret = get_option(&str, &val);
+	if (!ret)
+		return 0;
+	shared_file_policy_default = !!val;
+	return 1;
+}
+__setup("shared_file_policy_default=", setup_shared_file_policy_default);
+
+
+/*
  * Remember policies even when nobody has shared memory mapped.
  * The policies are kept in Red-Black tree linked from the inode.
  * They are protected by the sp->lock spinlock, which should be held
@@ -2510,10 +2527,11 @@ void __init numa_policy_init(void)
 		printk("numa_policy_init: interleaving failed\n");
 
 	/*
-	 * initialize per cpuset shared huge policy enablement
+	 * initialize per cpuset shared [huge] file policy enablement
 	 * from default.
 	 */
 	cpuset_init_shared_huge_policy(shared_huge_policy_default);
+	cpuset_init_shared_file_policy(shared_file_policy_default);
 }
 
 /* Reset policy of current process to default */
Index: linux-2.6.36-mmotm-101103-1217/include/linux/shared_policy.h
===================================================================
--- linux-2.6.36-mmotm-101103-1217.orig/include/linux/shared_policy.h
+++ linux-2.6.36-mmotm-101103-1217/include/linux/shared_policy.h
@@ -36,6 +36,7 @@ struct shared_policy {
 #define SPOL_F_PERSIST	0x01		/* for shmem use */
 
 extern int shared_file_policy_default;
+extern int shared_file_policy_default;
 
 extern struct shared_policy *mpol_shared_policy_new(
 					struct address_space *mapping,
@@ -51,6 +52,7 @@ extern struct mempolicy *mpol_shared_pol
 struct shared_policy {};
 
 #define shared_file_policy_default 0
+#define shared_file_policy_default 0
 
 static inline int mpol_set_shared_policy(struct shared_policy *info,
 					pgoff_t pgoff, unsigned long sz,

  parent reply	other threads:[~2010-11-11 19:13 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-11 19:11 [PATCH/RFC 0/14] Shared Policy Overview Lee Schermerhorn
2010-11-11 19:11 ` [PATCH/RFC 1/14] Shared Policy: Miscellaneous Cleanup Lee Schermerhorn
2010-11-11 19:12 ` [PATCH/RFC 2/14] Shared Policy: move shared policy to inode/mapping Lee Schermerhorn
2010-11-11 19:12 ` [PATCH/RFC 3/14] Shared Policy: allocate shared policies as needed Lee Schermerhorn
2010-11-11 19:12 ` [PATCH/RFC 4/14] Shared Policy: let vma policy ops handle sub-vma policies Lee Schermerhorn
2010-11-11 19:12 ` [PATCH/RFC 5/14] Shared Policy: fix show_numa_maps() Lee Schermerhorn
2010-11-11 19:12 ` [PATCH/RFC 6/14] Shared Policy: Factor alloc_page_pol routine Lee Schermerhorn
2010-11-11 19:12 ` [PATCH/RFC 7/14] Shared Policy: use shared policy for page cache allocations Lee Schermerhorn
2010-11-11 19:12 ` [PATCH/RFC 8/14] Shared Policy: use alloc_page_pol for swap and shmempages Lee Schermerhorn
2010-11-11 19:13 ` [PATCH/RFC 9/14] Shared Policy: per cpuset huge file policy control Lee Schermerhorn
2010-11-11 19:13 ` [PATCH/RFC 10/14] Shared Policy: Add hugepage shmem policy vm_ops Lee Schermerhorn
2010-11-11 19:13 ` [PATCH/RFC 11/14] Shared Policy: fix migration of private mappings Lee Schermerhorn
2010-11-11 19:13 ` [PATCH/RFC 12/14] Shared Policy: mapped file policy persistence model Lee Schermerhorn
2010-11-11 19:13 ` Lee Schermerhorn [this message]
2010-11-11 19:13 ` [PATCH/RFC 14/14] Shared Policy: add generic file set/get policy vm ops Lee Schermerhorn
2010-11-11 19:54 ` [PATCH/RFC 0/14] Shared Policy Overview Andi Kleen
2010-11-11 19:59   ` Lee Schermerhorn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20101111191339.12370.87740.sendpatchset@zaphod.localdomain \
    --to=lee.schermerhorn@hp.com \
    --cc=aarcange@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=avi@redhat.com \
    --cc=cl@linux-foundation.org \
    --cc=hughd@google.com \
    --cc=kosaki.motohiro@jp.fujitsu.com \
    --cc=linux-numa@vger.kernel.org \
    --cc=mel@csn.ul.ie \
    --cc=npiggin@kernel.dk \
    --cc=rientjes@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox