summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_resource.c')
-rw-r--r--sys/kern/kern_resource.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index c7cb511..1556993 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -273,6 +273,101 @@ donice(struct thread *td, struct proc *p, int n)
}
/*
+ * Set realtime priority for LWP.
+ *
+ * MPSAFE
+ */
+#ifndef _SYS_SYSPROTO_H_
+struct rtprio_thread_args {
+ int function;
+ lwpid_t lwpid;
+ struct rtprio *rtp;
+};
+#endif
+
+int
+rtprio_thread(struct thread *td, struct rtprio_thread_args *uap)
+{
+ struct proc *curp;
+ struct proc *p;
+ struct rtprio rtp;
+ struct thread *td1;
+ int cierror, error;
+
+ /* Perform copyin before acquiring locks if needed. */
+ if (uap->function == RTP_SET)
+ cierror = copyin(uap->rtp, &rtp, sizeof(struct rtprio));
+ else
+ cierror = 0;
+
+ curp = td->td_proc;
+ /*
+ * Though lwpid is unique, only current process is supported
+ * since there is no efficient way to look up a LWP yet.
+ */
+ p = curp;
+ PROC_LOCK(p);
+
+ switch (uap->function) {
+ case RTP_LOOKUP:
+ if ((error = p_cansee(td, p)))
+ break;
+ mtx_lock_spin(&sched_lock);
+ if (uap->lwpid == 0 || uap->lwpid == td->td_tid)
+ td1 = td;
+ else
+ td1 = thread_find(p, uap->lwpid);
+ if (td1 != NULL)
+ pri_to_rtp(td1->td_ksegrp, &rtp);
+ else
+ error = ESRCH;
+ mtx_unlock_spin(&sched_lock);
+ PROC_UNLOCK(p);
+ return (copyout(&rtp, uap->rtp, sizeof(struct rtprio)));
+ case RTP_SET:
+ if ((error = p_cansched(td, p)) || (error = cierror))
+ break;
+
+ /* Disallow setting rtprio in most cases if not superuser. */
+ if (suser(td) != 0) {
+ /* can't set realtime priority */
+/*
+ * Realtime priority has to be restricted for reasons which should be
+ * obvious. However, for idle priority, there is a potential for
+ * system deadlock if an idleprio process gains a lock on a resource
+ * that other processes need (and the idleprio process can't run
+ * due to a CPU-bound normal process). Fix me! XXX
+ */
+#if 0
+ if (RTP_PRIO_IS_REALTIME(rtp.type)) {
+#else
+ if (rtp.type != RTP_PRIO_NORMAL) {
+#endif
+ error = EPERM;
+ break;
+ }
+ }
+
+ mtx_lock_spin(&sched_lock);
+ if (uap->lwpid == 0 || uap->lwpid == td->td_tid)
+ td1 = td;
+ else
+ td1 = thread_find(p, uap->lwpid);
+ if (td1 != NULL)
+ error = rtp_to_pri(&rtp, td1->td_ksegrp);
+ else
+ error = ESRCH;
+ mtx_unlock_spin(&sched_lock);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ PROC_UNLOCK(p);
+ return (error);
+}
+
+/*
* Set realtime priority.
*
* MPSAFE
OpenPOWER on IntegriCloud