Do not compare the existing mask of a cpuset with a new mask when changing

the mask of a cpuset.  Also, change the cpuset's mask before updating the
masks of all children.  Previously changing a cpuset's mask first required
setting the mask to a super-set of both the old and new masks and then
changing it a second time to the new mask.
This commit is contained in:
John Baldwin 2013-06-06 14:43:19 +00:00
parent ee852b9c75
commit c9813d0a37
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=251470

View File

@ -303,7 +303,7 @@ cpuset_create(struct cpuset **setp, struct cpuset *parent, const cpuset_t *mask)
* empty as well as RDONLY flags. * empty as well as RDONLY flags.
*/ */
static int static int
cpuset_testupdate(struct cpuset *set, cpuset_t *mask) cpuset_testupdate(struct cpuset *set, cpuset_t *mask, int check_mask)
{ {
struct cpuset *nset; struct cpuset *nset;
cpuset_t newmask; cpuset_t newmask;
@ -312,13 +312,16 @@ cpuset_testupdate(struct cpuset *set, cpuset_t *mask)
mtx_assert(&cpuset_lock, MA_OWNED); mtx_assert(&cpuset_lock, MA_OWNED);
if (set->cs_flags & CPU_SET_RDONLY) if (set->cs_flags & CPU_SET_RDONLY)
return (EPERM); return (EPERM);
if (!CPU_OVERLAP(&set->cs_mask, mask)) if (check_mask) {
return (EDEADLK); if (!CPU_OVERLAP(&set->cs_mask, mask))
CPU_COPY(&set->cs_mask, &newmask); return (EDEADLK);
CPU_AND(&newmask, mask); CPU_COPY(&set->cs_mask, &newmask);
CPU_AND(&newmask, mask);
} else
CPU_COPY(mask, &newmask);
error = 0; error = 0;
LIST_FOREACH(nset, &set->cs_children, cs_siblings) LIST_FOREACH(nset, &set->cs_children, cs_siblings)
if ((error = cpuset_testupdate(nset, &newmask)) != 0) if ((error = cpuset_testupdate(nset, &newmask, 1)) != 0)
break; break;
return (error); return (error);
} }
@ -370,11 +373,11 @@ cpuset_modify(struct cpuset *set, cpuset_t *mask)
if (root && !CPU_SUBSET(&root->cs_mask, mask)) if (root && !CPU_SUBSET(&root->cs_mask, mask))
return (EINVAL); return (EINVAL);
mtx_lock_spin(&cpuset_lock); mtx_lock_spin(&cpuset_lock);
error = cpuset_testupdate(set, mask); error = cpuset_testupdate(set, mask, 0);
if (error) if (error)
goto out; goto out;
cpuset_update(set, mask);
CPU_COPY(mask, &set->cs_mask); CPU_COPY(mask, &set->cs_mask);
cpuset_update(set, mask);
out: out:
mtx_unlock_spin(&cpuset_lock); mtx_unlock_spin(&cpuset_lock);