| 1139 | } |
| 1140 | |
| 1141 | static int |
| 1142 | cpuset_setproc_newbase(struct thread *td, struct cpuset *set, |
| 1143 | struct cpuset *nroot, struct cpuset **nsetp, |
| 1144 | struct setlist *cpusets, struct domainlist *domainlist) |
| 1145 | { |
| 1146 | struct domainset ndomain; |
| 1147 | cpuset_t nmask; |
| 1148 | struct cpuset *pbase; |
| 1149 | int error; |
| 1150 | |
| 1151 | pbase = cpuset_getbase(td->td_cpuset); |
| 1152 | |
| 1153 | /* Copy process mask, then further apply the new root mask. */ |
| 1154 | CPU_COPY(&pbase->cs_mask, &nmask); |
| 1155 | CPU_AND(&nmask, &nroot->cs_mask); |
| 1156 | |
| 1157 | domainset_copy(pbase->cs_domain, &ndomain); |
| 1158 | DOMAINSET_AND(&ndomain.ds_mask, &set->cs_domain->ds_mask); |
| 1159 | |
| 1160 | /* Policy is too restrictive, will not work. */ |
| 1161 | if (CPU_EMPTY(&nmask) || DOMAINSET_EMPTY(&ndomain.ds_mask)) |
| 1162 | return (EDEADLK); |
| 1163 | |
| 1164 | /* |
| 1165 | * Remove pbase from the freelist in advance, it'll be pushed to |
| 1166 | * cpuset_ids on success. We assume here that cpuset_create() will not |
| 1167 | * touch pbase on failure, and we just enqueue it back to the freelist |
| 1168 | * to remain in a consistent state. |
| 1169 | */ |
| 1170 | pbase = LIST_FIRST(cpusets); |
| 1171 | LIST_REMOVE(pbase, cs_link); |
| 1172 | error = cpuset_create(&pbase, set, &nmask); |
| 1173 | if (error != 0) { |
| 1174 | LIST_INSERT_HEAD(cpusets, pbase, cs_link); |
| 1175 | return (error); |
| 1176 | } |
| 1177 | |
| 1178 | /* Duplicates some work from above... oh well. */ |
| 1179 | pbase->cs_domain = domainset_shadow(set->cs_domain, &ndomain, |
| 1180 | domainlist); |
| 1181 | *nsetp = pbase; |
| 1182 | return (0); |
| 1183 | } |
| 1184 | |
| 1185 | /* |
| 1186 | * Handle four cases for updating an entire process. |
no test coverage detected