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:
parent
ee852b9c75
commit
c9813d0a37
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=251470
@ -303,7 +303,7 @@ cpuset_create(struct cpuset **setp, struct cpuset *parent, const cpuset_t *mask)
|
||||
* empty as well as RDONLY flags.
|
||||
*/
|
||||
static int
|
||||
cpuset_testupdate(struct cpuset *set, cpuset_t *mask)
|
||||
cpuset_testupdate(struct cpuset *set, cpuset_t *mask, int check_mask)
|
||||
{
|
||||
struct cpuset *nset;
|
||||
cpuset_t newmask;
|
||||
@ -312,13 +312,16 @@ cpuset_testupdate(struct cpuset *set, cpuset_t *mask)
|
||||
mtx_assert(&cpuset_lock, MA_OWNED);
|
||||
if (set->cs_flags & CPU_SET_RDONLY)
|
||||
return (EPERM);
|
||||
if (check_mask) {
|
||||
if (!CPU_OVERLAP(&set->cs_mask, mask))
|
||||
return (EDEADLK);
|
||||
CPU_COPY(&set->cs_mask, &newmask);
|
||||
CPU_AND(&newmask, mask);
|
||||
} else
|
||||
CPU_COPY(mask, &newmask);
|
||||
error = 0;
|
||||
LIST_FOREACH(nset, &set->cs_children, cs_siblings)
|
||||
if ((error = cpuset_testupdate(nset, &newmask)) != 0)
|
||||
if ((error = cpuset_testupdate(nset, &newmask, 1)) != 0)
|
||||
break;
|
||||
return (error);
|
||||
}
|
||||
@ -370,11 +373,11 @@ cpuset_modify(struct cpuset *set, cpuset_t *mask)
|
||||
if (root && !CPU_SUBSET(&root->cs_mask, mask))
|
||||
return (EINVAL);
|
||||
mtx_lock_spin(&cpuset_lock);
|
||||
error = cpuset_testupdate(set, mask);
|
||||
error = cpuset_testupdate(set, mask, 0);
|
||||
if (error)
|
||||
goto out;
|
||||
cpuset_update(set, mask);
|
||||
CPU_COPY(mask, &set->cs_mask);
|
||||
cpuset_update(set, mask);
|
||||
out:
|
||||
mtx_unlock_spin(&cpuset_lock);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user