aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpuset.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r--kernel/cpuset.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 7430640f9816..f63383e01ec7 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -87,6 +87,7 @@ struct cpuset {
87typedef enum { 87typedef enum {
88 CS_CPU_EXCLUSIVE, 88 CS_CPU_EXCLUSIVE,
89 CS_MEM_EXCLUSIVE, 89 CS_MEM_EXCLUSIVE,
90 CS_MEMORY_MIGRATE,
90 CS_REMOVED, 91 CS_REMOVED,
91 CS_NOTIFY_ON_RELEASE 92 CS_NOTIFY_ON_RELEASE
92} cpuset_flagbits_t; 93} cpuset_flagbits_t;
@@ -112,6 +113,11 @@ static inline int notify_on_release(const struct cpuset *cs)
112 return !!test_bit(CS_NOTIFY_ON_RELEASE, &cs->flags); 113 return !!test_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
113} 114}
114 115
116static inline int is_memory_migrate(const struct cpuset *cs)
117{
118 return !!test_bit(CS_MEMORY_MIGRATE, &cs->flags);
119}
120
115/* 121/*
116 * Increment this atomic integer everytime any cpuset changes its 122 * Increment this atomic integer everytime any cpuset changes its
117 * mems_allowed value. Users of cpusets can track this generation 123 * mems_allowed value. Users of cpusets can track this generation
@@ -602,16 +608,24 @@ static void refresh_mems(void)
602 if (current->cpuset_mems_generation != my_cpusets_mem_gen) { 608 if (current->cpuset_mems_generation != my_cpusets_mem_gen) {
603 struct cpuset *cs; 609 struct cpuset *cs;
604 nodemask_t oldmem = current->mems_allowed; 610 nodemask_t oldmem = current->mems_allowed;
611 int migrate;
605 612
606 down(&callback_sem); 613 down(&callback_sem);
607 task_lock(current); 614 task_lock(current);
608 cs = current->cpuset; 615 cs = current->cpuset;
616 migrate = is_memory_migrate(cs);
609 guarantee_online_mems(cs, &current->mems_allowed); 617 guarantee_online_mems(cs, &current->mems_allowed);
610 current->cpuset_mems_generation = cs->mems_generation; 618 current->cpuset_mems_generation = cs->mems_generation;
611 task_unlock(current); 619 task_unlock(current);
612 up(&callback_sem); 620 up(&callback_sem);
613 if (!nodes_equal(oldmem, current->mems_allowed)) 621 if (!nodes_equal(oldmem, current->mems_allowed)) {
614 numa_policy_rebind(&oldmem, &current->mems_allowed); 622 numa_policy_rebind(&oldmem, &current->mems_allowed);
623 if (migrate) {
624 do_migrate_pages(current->mm, &oldmem,
625 &current->mems_allowed,
626 MPOL_MF_MOVE_ALL);
627 }
628 }
615 } 629 }
616} 630}
617 631
@@ -795,7 +809,7 @@ static int update_nodemask(struct cpuset *cs, char *buf)
795/* 809/*
796 * update_flag - read a 0 or a 1 in a file and update associated flag 810 * update_flag - read a 0 or a 1 in a file and update associated flag
797 * bit: the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE, 811 * bit: the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE,
798 * CS_NOTIFY_ON_RELEASE) 812 * CS_NOTIFY_ON_RELEASE, CS_MEMORY_MIGRATE)
799 * cs: the cpuset to update 813 * cs: the cpuset to update
800 * buf: the buffer where we read the 0 or 1 814 * buf: the buffer where we read the 0 or 1
801 * 815 *
@@ -848,6 +862,7 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
848 struct task_struct *tsk; 862 struct task_struct *tsk;
849 struct cpuset *oldcs; 863 struct cpuset *oldcs;
850 cpumask_t cpus; 864 cpumask_t cpus;
865 nodemask_t from, to;
851 866
852 if (sscanf(pidbuf, "%d", &pid) != 1) 867 if (sscanf(pidbuf, "%d", &pid) != 1)
853 return -EIO; 868 return -EIO;
@@ -893,7 +908,12 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
893 guarantee_online_cpus(cs, &cpus); 908 guarantee_online_cpus(cs, &cpus);
894 set_cpus_allowed(tsk, cpus); 909 set_cpus_allowed(tsk, cpus);
895 910
911 from = oldcs->mems_allowed;
912 to = cs->mems_allowed;
913
896 up(&callback_sem); 914 up(&callback_sem);
915 if (is_memory_migrate(cs))
916 do_migrate_pages(tsk->mm, &from, &to, MPOL_MF_MOVE_ALL);
897 put_task_struct(tsk); 917 put_task_struct(tsk);
898 if (atomic_dec_and_test(&oldcs->count)) 918 if (atomic_dec_and_test(&oldcs->count))
899 check_for_release(oldcs, ppathbuf); 919 check_for_release(oldcs, ppathbuf);
@@ -905,6 +925,7 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
905typedef enum { 925typedef enum {
906 FILE_ROOT, 926 FILE_ROOT,
907 FILE_DIR, 927 FILE_DIR,
928 FILE_MEMORY_MIGRATE,
908 FILE_CPULIST, 929 FILE_CPULIST,
909 FILE_MEMLIST, 930 FILE_MEMLIST,
910 FILE_CPU_EXCLUSIVE, 931 FILE_CPU_EXCLUSIVE,
@@ -960,6 +981,9 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
960 case FILE_NOTIFY_ON_RELEASE: 981 case FILE_NOTIFY_ON_RELEASE:
961 retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer); 982 retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer);
962 break; 983 break;
984 case FILE_MEMORY_MIGRATE:
985 retval = update_flag(CS_MEMORY_MIGRATE, cs, buffer);
986 break;
963 case FILE_TASKLIST: 987 case FILE_TASKLIST:
964 retval = attach_task(cs, buffer, &pathbuf); 988 retval = attach_task(cs, buffer, &pathbuf);
965 break; 989 break;
@@ -1060,6 +1084,9 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
1060 case FILE_NOTIFY_ON_RELEASE: 1084 case FILE_NOTIFY_ON_RELEASE:
1061 *s++ = notify_on_release(cs) ? '1' : '0'; 1085 *s++ = notify_on_release(cs) ? '1' : '0';
1062 break; 1086 break;
1087 case FILE_MEMORY_MIGRATE:
1088 *s++ = is_memory_migrate(cs) ? '1' : '0';
1089 break;
1063 default: 1090 default:
1064 retval = -EINVAL; 1091 retval = -EINVAL;
1065 goto out; 1092 goto out;
@@ -1408,6 +1435,11 @@ static struct cftype cft_notify_on_release = {
1408 .private = FILE_NOTIFY_ON_RELEASE, 1435 .private = FILE_NOTIFY_ON_RELEASE,
1409}; 1436};
1410 1437
1438static struct cftype cft_memory_migrate = {
1439 .name = "memory_migrate",
1440 .private = FILE_MEMORY_MIGRATE,
1441};
1442
1411static int cpuset_populate_dir(struct dentry *cs_dentry) 1443static int cpuset_populate_dir(struct dentry *cs_dentry)
1412{ 1444{
1413 int err; 1445 int err;
@@ -1422,6 +1454,8 @@ static int cpuset_populate_dir(struct dentry *cs_dentry)
1422 return err; 1454 return err;
1423 if ((err = cpuset_add_file(cs_dentry, &cft_notify_on_release)) < 0) 1455 if ((err = cpuset_add_file(cs_dentry, &cft_notify_on_release)) < 0)
1424 return err; 1456 return err;
1457 if ((err = cpuset_add_file(cs_dentry, &cft_memory_migrate)) < 0)
1458 return err;
1425 if ((err = cpuset_add_file(cs_dentry, &cft_tasks)) < 0) 1459 if ((err = cpuset_add_file(cs_dentry, &cft_tasks)) < 0)
1426 return err; 1460 return err;
1427 return 0; 1461 return 0;