Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_cpuset.c
Show First 20 Lines • Show All 320 Lines • ▼ Show 20 Lines | cpuset_init(struct cpuset *set, struct cpuset *parent, | ||||
if (!domainset_valid(parent->cs_domain, domain)) | if (!domainset_valid(parent->cs_domain, domain)) | ||||
return (EDEADLK); | return (EDEADLK); | ||||
CPU_COPY(mask, &set->cs_mask); | CPU_COPY(mask, &set->cs_mask); | ||||
LIST_INIT(&set->cs_children); | LIST_INIT(&set->cs_children); | ||||
refcount_init(&set->cs_ref, 1); | refcount_init(&set->cs_ref, 1); | ||||
set->cs_flags = 0; | set->cs_flags = 0; | ||||
mtx_lock_spin(&cpuset_lock); | mtx_lock_spin(&cpuset_lock); | ||||
set->cs_domain = domain; | set->cs_domain = domain; | ||||
CPU_AND(&set->cs_mask, &parent->cs_mask); | CPU_AND(&set->cs_mask, &set->cs_mask, &parent->cs_mask); | ||||
set->cs_id = id; | set->cs_id = id; | ||||
set->cs_parent = cpuset_ref(parent); | set->cs_parent = cpuset_ref(parent); | ||||
LIST_INSERT_HEAD(&parent->cs_children, set, cs_siblings); | LIST_INSERT_HEAD(&parent->cs_children, set, cs_siblings); | ||||
if (set->cs_id != CPUSET_INVALID) | if (set->cs_id != CPUSET_INVALID) | ||||
LIST_INSERT_HEAD(&cpuset_ids, set, cs_link); | LIST_INSERT_HEAD(&cpuset_ids, set, cs_link); | ||||
mtx_unlock_spin(&cpuset_lock); | mtx_unlock_spin(&cpuset_lock); | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 302 Lines • ▼ Show 20 Lines | cpuset_testupdate(struct cpuset *set, cpuset_t *mask, int augment_mask) | ||||
struct cpuset *nset; | struct cpuset *nset; | ||||
cpuset_t newmask; | cpuset_t newmask; | ||||
int error; | int error; | ||||
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 (augment_mask) { | if (augment_mask) { | ||||
CPU_COPY(&set->cs_mask, &newmask); | CPU_AND(&newmask, &set->cs_mask, mask); | ||||
CPU_AND(&newmask, mask); | |||||
} else | } else | ||||
CPU_COPY(mask, &newmask); | CPU_COPY(mask, &newmask); | ||||
if (CPU_EMPTY(&newmask)) | if (CPU_EMPTY(&newmask)) | ||||
return (EDEADLK); | return (EDEADLK); | ||||
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, 1)) != 0) | if ((error = cpuset_testupdate(nset, &newmask, 1)) != 0) | ||||
break; | break; | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Applies the mask 'mask' without checking for empty sets or permissions. | * Applies the mask 'mask' without checking for empty sets or permissions. | ||||
*/ | */ | ||||
static void | static void | ||||
cpuset_update(struct cpuset *set, cpuset_t *mask) | cpuset_update(struct cpuset *set, cpuset_t *mask) | ||||
{ | { | ||||
struct cpuset *nset; | struct cpuset *nset; | ||||
mtx_assert(&cpuset_lock, MA_OWNED); | mtx_assert(&cpuset_lock, MA_OWNED); | ||||
CPU_AND(&set->cs_mask, mask); | CPU_AND(&set->cs_mask, &set->cs_mask, mask); | ||||
LIST_FOREACH(nset, &set->cs_children, cs_siblings) | LIST_FOREACH(nset, &set->cs_children, cs_siblings) | ||||
cpuset_update(nset, &set->cs_mask); | cpuset_update(nset, &set->cs_mask); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Modify the set 'set' to use a copy of the mask provided. Apply this new | * Modify the set 'set' to use a copy of the mask provided. Apply this new | ||||
▲ Show 20 Lines • Show All 398 Lines • ▼ Show 20 Lines | cpuset_setproc_setthread_mask(struct cpuset *tdset, struct cpuset *set, | ||||
parent = cpuset_getbase(tdset); | parent = cpuset_getbase(tdset); | ||||
/* | /* | ||||
* If the thread restricted its mask then apply that same | * If the thread restricted its mask then apply that same | ||||
* restriction to the new set, otherwise take it wholesale. | * restriction to the new set, otherwise take it wholesale. | ||||
*/ | */ | ||||
if (CPU_CMP(&tdset->cs_mask, &parent->cs_mask) != 0) { | if (CPU_CMP(&tdset->cs_mask, &parent->cs_mask) != 0) { | ||||
CPU_COPY(&tdset->cs_mask, mask); | CPU_AND(mask, &tdset->cs_mask, &set->cs_mask); | ||||
CPU_AND(mask, &set->cs_mask); | |||||
} else | } else | ||||
CPU_COPY(&set->cs_mask, mask); | CPU_COPY(&set->cs_mask, mask); | ||||
/* | /* | ||||
* If the thread restricted the domain then we apply the | * If the thread restricted the domain then we apply the | ||||
* restriction to the new set but retain the policy. | * restriction to the new set but retain the policy. | ||||
*/ | */ | ||||
if (tdset->cs_domain != parent->cs_domain) { | if (tdset->cs_domain != parent->cs_domain) { | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | cpuset_setproc_newbase(struct thread *td, struct cpuset *set, | ||||
struct domainset ndomain; | struct domainset ndomain; | ||||
cpuset_t nmask; | cpuset_t nmask; | ||||
struct cpuset *pbase; | struct cpuset *pbase; | ||||
int error; | int error; | ||||
pbase = cpuset_getbase(td->td_cpuset); | pbase = cpuset_getbase(td->td_cpuset); | ||||
/* Copy process mask, then further apply the new root mask. */ | /* Copy process mask, then further apply the new root mask. */ | ||||
CPU_COPY(&pbase->cs_mask, &nmask); | CPU_AND(&nmask, &pbase->cs_mask, &nroot->cs_mask); | ||||
CPU_AND(&nmask, &nroot->cs_mask); | |||||
domainset_copy(pbase->cs_domain, &ndomain); | domainset_copy(pbase->cs_domain, &ndomain); | ||||
DOMAINSET_AND(&ndomain.ds_mask, &set->cs_domain->ds_mask); | DOMAINSET_AND(&ndomain.ds_mask, &set->cs_domain->ds_mask); | ||||
/* Policy is too restrictive, will not work. */ | /* Policy is too restrictive, will not work. */ | ||||
if (CPU_EMPTY(&nmask) || DOMAINSET_EMPTY(&ndomain.ds_mask)) | if (CPU_EMPTY(&nmask) || DOMAINSET_EMPTY(&ndomain.ds_mask)) | ||||
return (EDEADLK); | return (EDEADLK); | ||||
▲ Show 20 Lines • Show All 775 Lines • ▼ Show 20 Lines | case CPU_LEVEL_WHICH: | ||||
case CPU_WHICH_TID: | case CPU_WHICH_TID: | ||||
thread_lock(ttd); | thread_lock(ttd); | ||||
CPU_COPY(&ttd->td_cpuset->cs_mask, mask); | CPU_COPY(&ttd->td_cpuset->cs_mask, mask); | ||||
thread_unlock(ttd); | thread_unlock(ttd); | ||||
break; | break; | ||||
case CPU_WHICH_PID: | case CPU_WHICH_PID: | ||||
FOREACH_THREAD_IN_PROC(p, ttd) { | FOREACH_THREAD_IN_PROC(p, ttd) { | ||||
thread_lock(ttd); | thread_lock(ttd); | ||||
CPU_OR(mask, &ttd->td_cpuset->cs_mask); | CPU_OR(mask, mask, &ttd->td_cpuset->cs_mask); | ||||
thread_unlock(ttd); | thread_unlock(ttd); | ||||
} | } | ||||
break; | break; | ||||
case CPU_WHICH_CPUSET: | case CPU_WHICH_CPUSET: | ||||
case CPU_WHICH_JAIL: | case CPU_WHICH_JAIL: | ||||
CPU_COPY(&set->cs_mask, mask); | CPU_COPY(&set->cs_mask, mask); | ||||
break; | break; | ||||
case CPU_WHICH_IRQ: | case CPU_WHICH_IRQ: | ||||
▲ Show 20 Lines • Show All 502 Lines • Show Last 20 Lines |