Migrate-on-fault - add migrate on fault per cpuset control Add a migrate_on_fault control file to cpusets. Default is disabled ['0']. When set '1', enables migrate-on-fault for tasks in the cpuset once they notice the flag: for already running tasks, this means after they update their cpuset memory state. To avoid adding #ifdefs to kernel/cpuset.c [at Paul Jackson's request], most of the migrate-on-fault support is unconditionally included in cpuset.c. However, the control file will only be created if migrate-on-fault is configured. Signed-off-by: Lee Schermerhorn <lee.schermerhorn@xxxxxx> include/linux/cpuset.h | 16 ++++++++++++++++ include/linux/sched.h | 19 +++++++++++++++++++ kernel/cpuset.c | 34 +++++++++++++++++++++++++++++++++- mm/Kconfig | 1 + 4 files changed, 69 insertions(+), 1 deletion(-) 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 @@ -1457,6 +1457,7 @@ struct task_struct { short il_next; short shared_huge_policy_enabled:1; short shared_file_policy_enabled:1; + short migrate_on_fault_enabled:1; #endif atomic_t fs_excl; /* holding fs exclusive resources */ struct rcu_head rcu; @@ -1905,6 +1906,24 @@ static int shared_file_policy_enabled(st { return 0; } +#endif + +#ifdef CONFIG_MIGRATE_ON_FAULT +static inline void set_migrate_on_fault_enabled(struct task_struct *tsk, + int val) +{ + tsk->migrate_on_fault_enabled = !!val; +} +static inline int migrate_on_fault_enabled(struct task_struct *tsk) +{ + return tsk->migrate_on_fault_enabled; +} +#else +static void set_shared_file_policy_enabled(struct task_struct *tsk, int val) { } +static inline int migrate_on_fault_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 @@ -134,6 +134,7 @@ typedef enum { CS_SPREAD_SLAB, CS_SHARED_HUGE_POLICY, CS_SHARED_FILE_POLICY, + CS_MIGRATE_ON_FAULT, } cpuset_flagbits_t; /* convenient tests for these bits */ @@ -182,6 +183,11 @@ static inline int is_shared_file_policy( return test_bit(CS_SHARED_FILE_POLICY, &cs->flags); } +static inline int is_migrate_on_fault(const struct cpuset *cs) +{ + return test_bit(CS_MIGRATE_ON_FAULT, &cs->flags); +} + static struct cpuset top_cpuset = { .flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)), }; @@ -341,6 +347,12 @@ static void cpuset_update_task_cpuset_fl set_shared_file_policy_enabled(tsk, 1); else set_shared_file_policy_enabled(tsk, 0); + + if (is_migrate_on_fault(cs)) + set_migrate_on_fault_enabled(tsk, 1); + else + set_migrate_on_fault_enabled(tsk, 0); + } /* @@ -1281,7 +1293,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_file_policy(cs) != is_shared_file_policy(trialcs))); + || (is_shared_file_policy(cs) != is_shared_file_policy(trialcs)) + || (is_migrate_on_fault(cs) != is_migrate_on_fault(trialcs))); mutex_lock(&callback_mutex); cs->flags = trialcs->flags; @@ -1519,6 +1532,7 @@ typedef enum { FILE_SPREAD_SLAB, FILE_SHARED_HUGE_POLICY, FILE_SHARED_FILE_POLICY, + FILE_MIGRATE_ON_FAULT, } cpuset_filetype_t; static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) @@ -1564,6 +1578,9 @@ static int cpuset_write_u64(struct cgrou case FILE_SHARED_FILE_POLICY: retval = update_flag(CS_SHARED_FILE_POLICY, cs, val); break; + case FILE_MIGRATE_ON_FAULT: + retval = update_flag(CS_MIGRATE_ON_FAULT, cs, val); + break; default: retval = -EINVAL; break; @@ -1732,6 +1749,8 @@ static u64 cpuset_read_u64(struct cgroup return is_shared_huge_policy(cs); case FILE_SHARED_FILE_POLICY: return is_shared_file_policy(cs); + case FILE_MIGRATE_ON_FAULT: + return is_migrate_on_fault(cs); default: BUG(); } @@ -1863,6 +1882,13 @@ static struct cftype cft_shared_file_pol .private = FILE_SHARED_FILE_POLICY, }; +static struct cftype cft_migrate_on_fault = { + .name = "migrate_on_fault", + .read_u64 = cpuset_read_u64, + .write_u64 = cpuset_write_u64, + .private = FILE_MIGRATE_ON_FAULT, +}; + static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont) { int err; @@ -1879,6 +1905,10 @@ static int cpuset_populate(struct cgroup err = add_shared_xxx_policy_file(cont, ss, &cft_shared_file_policy); if (err < 0) return err; + err = add_migrate_on_fault_file(cont, ss, + &cft_migrate_on_fault); + if (err < 0) + return err; /* memory_pressure_enabled is in root cpuset only */ if (!cont->parent) err = cgroup_add_file(cont, ss, @@ -1957,6 +1987,8 @@ static struct cgroup_subsys_state *cpuse set_bit(CS_SHARED_HUGE_POLICY, &cs->flags); if (is_shared_file_policy(parent)) set_bit(CS_SHARED_FILE_POLICY, &cs->flags); + if (is_migrate_on_fault(parent)) + set_bit(CS_MIGRATE_ON_FAULT, &cs->flags); set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); cpumask_clear(cs->cpus_allowed); nodes_clear(cs->mems_allowed); Index: linux-2.6.36-mmotm-101103-1217/mm/Kconfig =================================================================== --- linux-2.6.36-mmotm-101103-1217.orig/mm/Kconfig +++ linux-2.6.36-mmotm-101103-1217/mm/Kconfig @@ -204,6 +204,7 @@ config MIGRATE_ON_FAULT bool "Migrate unmapped page on fault" depends on MIGRATION depends on SWAP + select CPUSETS help Allows "misplaced" pages found in a page cache at fault time to be migrated to the node specified by the applicable policy when the 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 @@ -148,6 +148,22 @@ static inline int add_shared_xxx_policy_ } #endif +#ifdef CONFIG_MIGRATE_ON_FAULT +static inline int add_migrate_on_fault_file(struct cgroup *cg, + struct cgroup_subsys *ss, + struct cftype *cft) +{ + return cgroup_add_file(cg, ss, cft); +} +#else +static inline int add_migrate_on_fault_file(struct cgroup *cont, + struct cgroup_subsys *ss, + struct cftype *cft) +{ + return 0; +} +#endif + extern void __init cpuset_init_shared_huge_policy(int dflt); extern void __init cpuset_init_shared_file_policy(int dflt); -- To unsubscribe from this list: send the line "unsubscribe linux-numa" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html