From: Dean Nelson <dcn@sgi.com>
To: Chris Wright <chrisw@osdl.org>
Cc: akpm@osdl.org, linux-kernel@vger.kernel.org
Subject: Re: [Patch] export sched_setscheduler() for kernel module use
Date: Mon, 15 Nov 2004 14:33:43 -0600 [thread overview]
Message-ID: <20041115203343.GA32173@sgi.com> (raw)
In-Reply-To: <20041115105801.T14339@build.pdx.osdl.net>
On Mon, Nov 15, 2004 at 10:58:01AM -0800, Chris Wright wrote:
> * Dean Nelson (dcn@sgi.com) wrote:
> > +int do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
>
> this should be static.
You're right. I made another change in that one now passes the task_struct
pointer to sched_setscheduler() instead of the pid. This requires that
the caller of sched_setscheduler() hold the tasklist_lock. The new patch
for people's feedback follows.
Thanks,
Dean
Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/include/linux/sched.h 2004-11-12 09:40:26.000000000 -0600
+++ linux-2.6/include/linux/sched.h 2004-11-15 13:43:48.000000000 -0600
@@ -727,6 +727,7 @@
extern int task_nice(const task_t *p);
extern int task_curr(const task_t *p);
extern int idle_cpu(int cpu);
+extern int sched_setscheduler(struct task_struct *, int, struct sched_param *);
void yield(void);
Index: linux-2.6/kernel/sched.c
===================================================================
--- linux-2.6.orig/kernel/sched.c 2004-11-12 09:40:26.000000000 -0600
+++ linux-2.6/kernel/sched.c 2004-11-15 14:22:45.000000000 -0600
@@ -2938,7 +2938,7 @@
*/
rq = task_rq_lock(p, &flags);
/*
- * The RT priorities are set via setscheduler(), but we still
+ * The RT priorities are set via sched_setscheduler(), but we still
* allow the 'normal' nice value to be set - but as expected
* it wont have any effect on scheduling until the task is
* not SCHED_NORMAL:
@@ -3072,67 +3072,50 @@
p->prio = p->static_prio;
}
-/*
- * setscheduler - change the scheduling policy and/or RT priority of a thread.
+/**
+ * sched_setscheduler - change the scheduling policy and/or RT priority of
+ * a thread.
+ * @p: the task in question.
+ * @policy: new policy.
+ * @param: structure containing the new RT priority.
+ *
+ * The caller of this function must be holding the tasklist_lock.
*/
-static int setscheduler(pid_t pid, int policy, struct sched_param __user *param)
+int sched_setscheduler(struct task_struct *p, int policy, struct sched_param *param)
{
- struct sched_param lp;
- int retval = -EINVAL;
+ int retval;
int oldprio, oldpolicy = -1;
prio_array_t *array;
unsigned long flags;
runqueue_t *rq;
- task_t *p;
-
- if (!param || pid < 0)
- goto out_nounlock;
-
- retval = -EFAULT;
- if (copy_from_user(&lp, param, sizeof(struct sched_param)))
- goto out_nounlock;
-
- /*
- * We play safe to avoid deadlocks.
- */
- read_lock_irq(&tasklist_lock);
-
- p = find_process_by_pid(pid);
- retval = -ESRCH;
- if (!p)
- goto out_unlock;
recheck:
/* double check policy once rq lock held */
if (policy < 0)
policy = oldpolicy = p->policy;
- else {
- retval = -EINVAL;
- if (policy != SCHED_FIFO && policy != SCHED_RR &&
+ else if (policy != SCHED_FIFO && policy != SCHED_RR &&
policy != SCHED_NORMAL)
- goto out_unlock;
- }
+ return -EINVAL;
/*
* Valid priorities for SCHED_FIFO and SCHED_RR are
* 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL is 0.
*/
- retval = -EINVAL;
- if (lp.sched_priority < 0 || lp.sched_priority > MAX_USER_RT_PRIO-1)
- goto out_unlock;
- if ((policy == SCHED_NORMAL) != (lp.sched_priority == 0))
- goto out_unlock;
+ if (param->sched_priority < 0 ||
+ param->sched_priority > MAX_USER_RT_PRIO-1)
+ return -EINVAL;
+ if ((policy == SCHED_NORMAL) != (param->sched_priority == 0))
+ return -EINVAL;
- retval = -EPERM;
if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
!capable(CAP_SYS_NICE))
- goto out_unlock;
+ return -EPERM;
if ((current->euid != p->euid) && (current->euid != p->uid) &&
!capable(CAP_SYS_NICE))
- goto out_unlock;
+ return -EPERM;
- retval = security_task_setscheduler(p, policy, &lp);
+ retval = security_task_setscheduler(p, policy, param);
if (retval)
- goto out_unlock;
+ return retval;
/*
* To be able to change p->policy safely, the apropriate
* runqueue lock must be held.
@@ -3147,9 +3130,8 @@
array = p->array;
if (array)
deactivate_task(p, task_rq(p));
- retval = 0;
oldprio = p->prio;
- __setscheduler(p, policy, lp.sched_priority);
+ __setscheduler(p, policy, param->sched_priority);
if (array) {
__activate_task(p, task_rq(p));
/*
@@ -3164,22 +3146,41 @@
resched_task(rq->curr);
}
task_rq_unlock(rq, &flags);
-out_unlock:
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sched_setscheduler);
+
+static int do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
+{
+ int retval;
+ struct sched_param lparam;
+ struct task_struct *p;
+
+ if (!param || pid < 0)
+ return -EINVAL;
+ if (copy_from_user(&lparam, param, sizeof(struct sched_param)))
+ return -EFAULT;
+ read_lock_irq(&tasklist_lock);
+ p = find_process_by_pid(pid);
+ if (!p) {
+ read_unlock_irq(&tasklist_lock);
+ return -ESRCH;
+ }
+ retval = sched_setscheduler(p, policy, &lparam);
read_unlock_irq(&tasklist_lock);
-out_nounlock:
return retval;
}
/**
* sys_sched_setscheduler - set/change the scheduler policy and RT priority
* @pid: the pid in question.
- * @policy: new policy
+ * @policy: new policy.
* @param: structure containing the new RT priority.
*/
asmlinkage long sys_sched_setscheduler(pid_t pid, int policy,
struct sched_param __user *param)
{
- return setscheduler(pid, policy, param);
+ return do_sched_setscheduler(pid, policy, param);
}
/**
@@ -3189,7 +3190,7 @@
*/
asmlinkage long sys_sched_setparam(pid_t pid, struct sched_param __user *param)
{
- return setscheduler(pid, -1, param);
+ return do_sched_setscheduler(pid, -1, param);
}
/**
next prev parent reply other threads:[~2004-11-15 20:35 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-11-15 18:35 [Patch] export sched_setscheduler() for kernel module use Dean Nelson
2004-11-15 18:58 ` Chris Wright
2004-11-15 20:33 ` Dean Nelson [this message]
2004-11-15 20:41 ` Jan Engelhardt
2004-11-15 21:03 ` Dean Nelson
2004-11-15 21:27 ` Chris Wright
2004-12-09 14:36 ` Dean Nelson
2004-11-16 10:48 ` Ingo Molnar
2004-11-16 18:34 ` pthread_cond_signal not waking thread Andrew A.
2004-11-16 20:31 ` Nikita Danilov
2004-11-16 20:45 ` Andrew A.
2004-11-16 21:00 ` Nikita Danilov
2004-11-16 20:18 ` [Patch] export sched_setscheduler() for kernel module use Dean Nelson
2004-11-16 22:36 ` Ingo Molnar
2004-11-16 22:01 ` Chris Friesen
2004-11-16 23:05 ` Ingo Molnar
2004-12-08 20:34 ` Dean Nelson
2004-12-09 12:46 ` Ingo Molnar
-- strict thread matches above, loose matches on Subject: below --
2004-12-13 20:14 [PATCH] " Dean Nelson
2004-12-15 9:49 ` Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20041115203343.GA32173@sgi.com \
--to=dcn@sgi.com \
--cc=akpm@osdl.org \
--cc=chrisw@osdl.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox