diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cpuset.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index e6d002fc7392..88b416dfbc72 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -821,11 +821,22 @@ static int update_cpumask(struct cpuset *cs, char *buf) | |||
821 | return -EACCES; | 821 | return -EACCES; |
822 | 822 | ||
823 | trialcs = *cs; | 823 | trialcs = *cs; |
824 | retval = cpulist_parse(buf, trialcs.cpus_allowed); | 824 | |
825 | if (retval < 0) | 825 | /* |
826 | return retval; | 826 | * We allow a cpuset's cpus_allowed to be empty; if it has attached |
827 | * tasks, we'll catch it later when we validate the change and return | ||
828 | * -ENOSPC. | ||
829 | */ | ||
830 | if (!buf[0] || (buf[0] == '\n' && !buf[1])) { | ||
831 | cpus_clear(trialcs.cpus_allowed); | ||
832 | } else { | ||
833 | retval = cpulist_parse(buf, trialcs.cpus_allowed); | ||
834 | if (retval < 0) | ||
835 | return retval; | ||
836 | } | ||
827 | cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map); | 837 | cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map); |
828 | if (cpus_empty(trialcs.cpus_allowed)) | 838 | /* cpus_allowed cannot be empty for a cpuset with attached tasks. */ |
839 | if (atomic_read(&cs->count) && cpus_empty(trialcs.cpus_allowed)) | ||
829 | return -ENOSPC; | 840 | return -ENOSPC; |
830 | retval = validate_change(cs, &trialcs); | 841 | retval = validate_change(cs, &trialcs); |
831 | if (retval < 0) | 842 | if (retval < 0) |
@@ -918,16 +929,27 @@ static int update_nodemask(struct cpuset *cs, char *buf) | |||
918 | return -EACCES; | 929 | return -EACCES; |
919 | 930 | ||
920 | trialcs = *cs; | 931 | trialcs = *cs; |
921 | retval = nodelist_parse(buf, trialcs.mems_allowed); | 932 | |
922 | if (retval < 0) | 933 | /* |
923 | goto done; | 934 | * We allow a cpuset's mems_allowed to be empty; if it has attached |
935 | * tasks, we'll catch it later when we validate the change and return | ||
936 | * -ENOSPC. | ||
937 | */ | ||
938 | if (!buf[0] || (buf[0] == '\n' && !buf[1])) { | ||
939 | nodes_clear(trialcs.mems_allowed); | ||
940 | } else { | ||
941 | retval = nodelist_parse(buf, trialcs.mems_allowed); | ||
942 | if (retval < 0) | ||
943 | goto done; | ||
944 | } | ||
924 | nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map); | 945 | nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map); |
925 | oldmem = cs->mems_allowed; | 946 | oldmem = cs->mems_allowed; |
926 | if (nodes_equal(oldmem, trialcs.mems_allowed)) { | 947 | if (nodes_equal(oldmem, trialcs.mems_allowed)) { |
927 | retval = 0; /* Too easy - nothing to do */ | 948 | retval = 0; /* Too easy - nothing to do */ |
928 | goto done; | 949 | goto done; |
929 | } | 950 | } |
930 | if (nodes_empty(trialcs.mems_allowed)) { | 951 | /* mems_allowed cannot be empty for a cpuset with attached tasks. */ |
952 | if (atomic_read(&cs->count) && nodes_empty(trialcs.mems_allowed)) { | ||
931 | retval = -ENOSPC; | 953 | retval = -ENOSPC; |
932 | goto done; | 954 | goto done; |
933 | } | 955 | } |