| 161 | } |
| 162 | |
| 163 | static int |
| 164 | sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, intmax_t arg2, |
| 165 | struct sysctl_req *req, struct rm_priotracker *tracker) |
| 166 | { |
| 167 | int error; |
| 168 | |
| 169 | if (oid->oid_kind & CTLFLAG_DYN) |
| 170 | atomic_add_int(&oid->oid_running, 1); |
| 171 | |
| 172 | if (tracker != NULL) |
| 173 | SYSCTL_RUNLOCK(tracker); |
| 174 | else |
| 175 | SYSCTL_WUNLOCK(); |
| 176 | |
| 177 | /* |
| 178 | * Treat set CTLFLAG_NEEDGIANT and unset CTLFLAG_MPSAFE flags the same, |
| 179 | * untill we're ready to remove all traces of Giant from sysctl(9). |
| 180 | */ |
| 181 | if ((oid->oid_kind & CTLFLAG_NEEDGIANT) || |
| 182 | (!(oid->oid_kind & CTLFLAG_MPSAFE))) |
| 183 | mtx_lock(&Giant); |
| 184 | error = oid->oid_handler(oid, arg1, arg2, req); |
| 185 | if ((oid->oid_kind & CTLFLAG_NEEDGIANT) || |
| 186 | (!(oid->oid_kind & CTLFLAG_MPSAFE))) |
| 187 | mtx_unlock(&Giant); |
| 188 | |
| 189 | KFAIL_POINT_ERROR(_debug_fail_point, sysctl_running, error); |
| 190 | |
| 191 | if (tracker != NULL) |
| 192 | SYSCTL_RLOCK(tracker); |
| 193 | else |
| 194 | SYSCTL_WLOCK(); |
| 195 | |
| 196 | if (oid->oid_kind & CTLFLAG_DYN) { |
| 197 | if (atomic_fetchadd_int(&oid->oid_running, -1) == 1 && |
| 198 | (oid->oid_kind & CTLFLAG_DYING) != 0) |
| 199 | wakeup(&oid->oid_running); |
| 200 | } |
| 201 | |
| 202 | return (error); |
| 203 | } |
| 204 | |
| 205 | static void |
| 206 | sysctl_load_tunable_by_oid_locked(struct sysctl_oid *oidp) |
no test coverage detected