AutoPage Migration - add auto_migration enable per cpuset control This patch implements a per cpuset "auto_migration" control. Default is disabled. Earlier versions of this patch used a task flag for this purpose to avoid extra cache misses in the fault path and such. There are currently no task flags available, so this version uses a flag in another variable in another cache line :(. Because AUTO_MIGRATE requires CPUSETS, unconditionally select same in mm/Kconfig. Signed-off-by: Lee Schermerhorn <lee.schermerhorn@xxxxxx> include/linux/cpuset.h | 16 ++++++++++++++++ include/linux/sched.h | 18 ++++++++++++++++++ kernel/cpuset.c | 31 ++++++++++++++++++++++++++++++- mm/Kconfig | 1 + 4 files changed, 65 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 @@ -1458,6 +1458,7 @@ struct task_struct { short shared_huge_policy_enabled:1; short shared_file_policy_enabled:1; short migrate_on_fault_enabled:1; + short auto_migrate_enabled:1; #endif atomic_t fs_excl; /* holding fs exclusive resources */ struct rcu_head rcu; @@ -1926,6 +1927,23 @@ static inline int migrate_on_fault_enabl } #endif +#ifdef CONFIG_AUTO_MIGRATION +static inline void set_auto_migrate_enabled(struct task_struct *tsk, + int val) +{ + tsk->auto_migrate_enabled = !!val; +} +static inline int auto_migrate_enabled(struct task_struct *tsk) +{ + return tsk->auto_migrate_enabled; +} +#else +static inline void set_auto_migrate_enabled(struct task_struct *tsk, + int val) +{ +} +#endif + #ifdef CONFIG_HOTPLUG_CPU extern void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p); extern void idle_task_exit(void); 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 @@ -135,6 +135,7 @@ typedef enum { CS_SHARED_HUGE_POLICY, CS_SHARED_FILE_POLICY, CS_MIGRATE_ON_FAULT, + CS_AUTO_MIGRATE, } cpuset_flagbits_t; /* convenient tests for these bits */ @@ -188,6 +189,11 @@ static inline int is_migrate_on_fault(co return test_bit(CS_MIGRATE_ON_FAULT, &cs->flags); } +static inline int is_auto_migrate(const struct cpuset *cs) +{ + return test_bit(CS_AUTO_MIGRATE, &cs->flags); +} + static struct cpuset top_cpuset = { .flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)), }; @@ -352,6 +358,10 @@ static void cpuset_update_task_cpuset_fl set_migrate_on_fault_enabled(tsk, 1); else set_migrate_on_fault_enabled(tsk, 0); + if (is_auto_migrate(cs)) + set_auto_migrate_enabled(tsk, 1); + else + set_auto_migrate_enabled(tsk, 0); } @@ -1294,7 +1304,8 @@ static int update_flag(cpuset_flagbits_t || (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_migrate_on_fault(cs) != is_migrate_on_fault(trialcs))); + || (is_migrate_on_fault(cs) != is_migrate_on_fault(trialcs)) + || (is_auto_migrate(cs) != is_auto_migrate(trialcs))); mutex_lock(&callback_mutex); cs->flags = trialcs->flags; @@ -1533,6 +1544,7 @@ typedef enum { FILE_SHARED_HUGE_POLICY, FILE_SHARED_FILE_POLICY, FILE_MIGRATE_ON_FAULT, + FILE_AUTO_MIGRATE, } cpuset_filetype_t; static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) @@ -1580,6 +1592,9 @@ static int cpuset_write_u64(struct cgrou break; case FILE_MIGRATE_ON_FAULT: retval = update_flag(CS_MIGRATE_ON_FAULT, cs, val); + break; + case FILE_AUTO_MIGRATE: + retval = update_flag(CS_AUTO_MIGRATE, cs, val); break; default: retval = -EINVAL; @@ -1751,6 +1766,8 @@ static u64 cpuset_read_u64(struct cgroup return is_shared_file_policy(cs); case FILE_MIGRATE_ON_FAULT: return is_migrate_on_fault(cs); + case FILE_AUTO_MIGRATE: + return is_auto_migrate(cs); default: BUG(); } @@ -1889,6 +1906,13 @@ static struct cftype cft_migrate_on_faul .private = FILE_MIGRATE_ON_FAULT, }; +static struct cftype cft_auto_migration = { + .name = "auto_migration", + .read_u64 = cpuset_read_u64, + .write_u64 = cpuset_write_u64, + .private = FILE_AUTO_MIGRATE, +}; + static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont) { int err; @@ -1909,6 +1933,9 @@ static int cpuset_populate(struct cgroup &cft_migrate_on_fault); if (err < 0) return err; + err = add_auto_migration_file(cont, ss, &cft_auto_migration); + if (err < 0) + return err; /* memory_pressure_enabled is in root cpuset only */ if (!cont->parent) err = cgroup_add_file(cont, ss, @@ -1989,6 +2016,8 @@ static struct cgroup_subsys_state *cpuse set_bit(CS_SHARED_FILE_POLICY, &cs->flags); if (is_migrate_on_fault(parent)) set_bit(CS_MIGRATE_ON_FAULT, &cs->flags); + if (is_auto_migrate(parent)) + set_bit(CS_AUTO_MIGRATE, &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 @@ -214,6 +214,7 @@ config MIGRATE_ON_FAULT config AUTO_MIGRATION bool "Auto-migrate task memory" depends on MIGRATION + select CPUSETS help Allows tasks' private memory to follow that task itself across inter-node migrations. 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 @@ -164,6 +164,22 @@ static inline int add_migrate_on_fault_f } #endif +#ifdef CONFIG_AUTO_MIGRATION +static inline int add_auto_migration_file(struct cgroup *cg, + struct cgroup_subsys *ss, + struct cftype *cft) +{ + return cgroup_add_file(cg, ss, cft); +} +#else +static inline int add_auto_migration_file(struct cgroup *cg, + 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