| 261 |
261 |
return (0);
|
| 262 |
262 |
}
|
| 263 |
263 |
|
|
264 |
int
|
|
265 |
sys_lwp_rtprio(struct lwp_rtprio_args *uap)
|
|
266 |
{
|
|
267 |
struct proc *p = curproc;
|
|
268 |
struct lwp *lp;
|
|
269 |
struct rtprio rtp;
|
|
270 |
struct ucred *cr = p->p_ucred;
|
|
271 |
int error;
|
|
272 |
|
|
273 |
error = copyin(uap->rtp, &rtp, sizeof(struct rtprio));
|
|
274 |
if (error)
|
|
275 |
return error;
|
|
276 |
|
|
277 |
if (uap->pid < 0) {
|
|
278 |
return EINVAL;
|
|
279 |
} else if (uap->pid == 0) {
|
|
280 |
/* curproc already loaded on p */
|
|
281 |
} else {
|
|
282 |
p = pfind(uap->pid);
|
|
283 |
}
|
|
284 |
|
|
285 |
if (p == 0) {
|
|
286 |
return ESRCH;
|
|
287 |
}
|
|
288 |
|
|
289 |
if (uap->tid < -1) {
|
|
290 |
return EINVAL;
|
|
291 |
} else if (uap->tid == -1) {
|
|
292 |
/*
|
|
293 |
* sadly, tid can be 0 so we can't use 0 here
|
|
294 |
* like sys_rtprio()
|
|
295 |
*/
|
|
296 |
lp = curthread->td_lwp;
|
|
297 |
} else {
|
|
298 |
FOREACH_LWP_IN_PROC(lp, p) {
|
|
299 |
if (lp->lwp_tid == uap->tid) {
|
|
300 |
break;
|
|
301 |
}
|
|
302 |
}
|
|
303 |
if (!lp) {
|
|
304 |
return ESRCH;
|
|
305 |
}
|
|
306 |
}
|
|
307 |
|
|
308 |
switch (uap->function) {
|
|
309 |
case RTP_LOOKUP:
|
|
310 |
return (copyout(&lp->lwp_rtprio, uap->rtp,
|
|
311 |
sizeof(struct rtprio)));
|
|
312 |
case RTP_SET:
|
|
313 |
if (cr->cr_uid && cr->cr_ruid &&
|
|
314 |
cr->cr_uid != p->p_ucred->cr_uid &&
|
|
315 |
cr->cr_ruid != p->p_ucred->cr_uid) {
|
|
316 |
return EPERM;
|
|
317 |
}
|
|
318 |
/* disallow setting rtprio in most cases if not superuser */
|
|
319 |
if (suser_cred(cr, 0)) {
|
|
320 |
/* can't set someone else's */
|
|
321 |
if (uap->pid) { /* XXX */
|
|
322 |
return EPERM;
|
|
323 |
}
|
|
324 |
/* can't set realtime priority */
|
|
325 |
/*
|
|
326 |
* Realtime priority has to be restricted for reasons which should be
|
|
327 |
* obvious. However, for idle priority, there is a potential for
|
|
328 |
* system deadlock if an idleprio process gains a lock on a resource
|
|
329 |
* that other processes need (and the idleprio process can't run
|
|
330 |
* due to a CPU-bound normal process). Fix me! XXX
|
|
331 |
*/
|
|
332 |
if (RTP_PRIO_IS_REALTIME(rtp.type)) {
|
|
333 |
return EPERM;
|
|
334 |
}
|
|
335 |
}
|
|
336 |
switch (rtp.type) {
|
|
337 |
#ifdef RTP_PRIO_FIFO
|
|
338 |
case RTP_PRIO_FIFO:
|
|
339 |
#endif
|
|
340 |
case RTP_PRIO_REALTIME:
|
|
341 |
case RTP_PRIO_NORMAL:
|
|
342 |
case RTP_PRIO_IDLE:
|
|
343 |
if (rtp.prio > RTP_PRIO_MAX)
|
|
344 |
return EINVAL;
|
|
345 |
lp->lwp_rtprio = rtp;
|
|
346 |
return 0;
|
|
347 |
default:
|
|
348 |
return EINVAL;
|
|
349 |
}
|
|
350 |
default:
|
|
351 |
return EINVAL;
|
|
352 |
}
|
|
353 |
panic("can't get here");
|
|
354 |
}
|
|
355 |
|
| 264 |
356 |
/*
|
| 265 |
357 |
* Set realtime priority
|
| 266 |
358 |
*/
|