diff options
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r-- | kernel/cpuset.c | 50 |
1 files changed, 20 insertions, 30 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 203ca52e78dd..64ad59cfad9b 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -488,6 +488,14 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) | |||
488 | return -EINVAL; | 488 | return -EINVAL; |
489 | } | 489 | } |
490 | 490 | ||
491 | /* Cpusets with tasks can't have empty cpus_allowed or mems_allowed */ | ||
492 | if (cgroup_task_count(cur->css.cgroup)) { | ||
493 | if (cpus_empty(trial->cpus_allowed) || | ||
494 | nodes_empty(trial->mems_allowed)) { | ||
495 | return -ENOSPC; | ||
496 | } | ||
497 | } | ||
498 | |||
491 | return 0; | 499 | return 0; |
492 | } | 500 | } |
493 | 501 | ||
@@ -710,11 +718,13 @@ static int update_cpumask(struct cpuset *cs, char *buf) | |||
710 | trialcs = *cs; | 718 | trialcs = *cs; |
711 | 719 | ||
712 | /* | 720 | /* |
713 | * We allow a cpuset's cpus_allowed to be empty; if it has attached | 721 | * An empty cpus_allowed is ok iff there are no tasks in the cpuset. |
714 | * tasks, we'll catch it later when we validate the change and return | 722 | * Since cpulist_parse() fails on an empty mask, we special case |
715 | * -ENOSPC. | 723 | * that parsing. The validate_change() call ensures that cpusets |
724 | * with tasks have cpus. | ||
716 | */ | 725 | */ |
717 | if (!buf[0] || (buf[0] == '\n' && !buf[1])) { | 726 | buf = strstrip(buf); |
727 | if (!*buf) { | ||
718 | cpus_clear(trialcs.cpus_allowed); | 728 | cpus_clear(trialcs.cpus_allowed); |
719 | } else { | 729 | } else { |
720 | retval = cpulist_parse(buf, trialcs.cpus_allowed); | 730 | retval = cpulist_parse(buf, trialcs.cpus_allowed); |
@@ -722,10 +732,6 @@ static int update_cpumask(struct cpuset *cs, char *buf) | |||
722 | return retval; | 732 | return retval; |
723 | } | 733 | } |
724 | cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map); | 734 | cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map); |
725 | /* cpus_allowed cannot be empty for a cpuset with attached tasks. */ | ||
726 | if (cgroup_task_count(cs->css.cgroup) && | ||
727 | cpus_empty(trialcs.cpus_allowed)) | ||
728 | return -ENOSPC; | ||
729 | retval = validate_change(cs, &trialcs); | 735 | retval = validate_change(cs, &trialcs); |
730 | if (retval < 0) | 736 | if (retval < 0) |
731 | return retval; | 737 | return retval; |
@@ -830,29 +836,19 @@ static int update_nodemask(struct cpuset *cs, char *buf) | |||
830 | trialcs = *cs; | 836 | trialcs = *cs; |
831 | 837 | ||
832 | /* | 838 | /* |
833 | * We allow a cpuset's mems_allowed to be empty; if it has attached | 839 | * An empty mems_allowed is ok iff there are no tasks in the cpuset. |
834 | * tasks, we'll catch it later when we validate the change and return | 840 | * Since nodelist_parse() fails on an empty mask, we special case |
835 | * -ENOSPC. | 841 | * that parsing. The validate_change() call ensures that cpusets |
842 | * with tasks have memory. | ||
836 | */ | 843 | */ |
837 | if (!buf[0] || (buf[0] == '\n' && !buf[1])) { | 844 | buf = strstrip(buf); |
845 | if (!*buf) { | ||
838 | nodes_clear(trialcs.mems_allowed); | 846 | nodes_clear(trialcs.mems_allowed); |
839 | } else { | 847 | } else { |
840 | retval = nodelist_parse(buf, trialcs.mems_allowed); | 848 | retval = nodelist_parse(buf, trialcs.mems_allowed); |
841 | if (retval < 0) | 849 | if (retval < 0) |
842 | goto done; | 850 | goto done; |
843 | if (!nodes_intersects(trialcs.mems_allowed, | ||
844 | node_states[N_HIGH_MEMORY])) { | ||
845 | /* | ||
846 | * error if only memoryless nodes specified. | ||
847 | */ | ||
848 | retval = -ENOSPC; | ||
849 | goto done; | ||
850 | } | ||
851 | } | 851 | } |
852 | /* | ||
853 | * Exclude memoryless nodes. We know that trialcs.mems_allowed | ||
854 | * contains at least one node with memory. | ||
855 | */ | ||
856 | nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, | 852 | nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, |
857 | node_states[N_HIGH_MEMORY]); | 853 | node_states[N_HIGH_MEMORY]); |
858 | oldmem = cs->mems_allowed; | 854 | oldmem = cs->mems_allowed; |
@@ -860,12 +856,6 @@ static int update_nodemask(struct cpuset *cs, char *buf) | |||
860 | retval = 0; /* Too easy - nothing to do */ | 856 | retval = 0; /* Too easy - nothing to do */ |
861 | goto done; | 857 | goto done; |
862 | } | 858 | } |
863 | /* mems_allowed cannot be empty for a cpuset with attached tasks. */ | ||
864 | if (cgroup_task_count(cs->css.cgroup) && | ||
865 | nodes_empty(trialcs.mems_allowed)) { | ||
866 | retval = -ENOSPC; | ||
867 | goto done; | ||
868 | } | ||
869 | retval = validate_change(cs, &trialcs); | 859 | retval = validate_change(cs, &trialcs); |
870 | if (retval < 0) | 860 | if (retval < 0) |
871 | goto done; | 861 | goto done; |