From: Robert Love <rml@tech9.net>
To: alan@redhat.com
Cc: mingo@elte.hu, linux-kernel@vger.kernel.org
Subject: [PATCH] 2.4-ac: scheduler comment infusion
Date: 11 Sep 2002 18:21:37 -0400 [thread overview]
Message-ID: <1031782897.1023.31.camel@phantasy> (raw)
[-- Attachment #1: Type: text/plain, Size: 177 bytes --]
Alan,
Add a largish amount of comments, mostly by Ingo. Most functions now
have a nice explanation above them.
Patch is against 2.4.20-pre5-ac4, please apply.
Robert Love
[-- Attachment #2: 210-sched-comments.patch --]
[-- Type: text/x-patch, Size: 12501 bytes --]
diff -urN linux-2.4.20-pre5-ac4-rml/kernel/sched.c linux/kernel/sched.c
--- linux-2.4.20-pre5-ac4-rml/kernel/sched.c Wed Sep 11 16:56:20 2002
+++ linux/kernel/sched.c Wed Sep 11 16:57:10 2002
@@ -227,21 +227,24 @@
p->array = array;
}
+/*
+ * effective_prio - return the priority that is based on the static
+ * priority but is modified by bonuses/penalties.
+ *
+ * We scale the actual sleep average [0 .... MAX_SLEEP_AVG]
+ * into the -5 ... 0 ... +5 bonus/penalty range.
+ *
+ * We use 25% of the full 0...39 priority range so that:
+ *
+ * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs.
+ * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks.
+ *
+ * Both properties are important to certain workloads.
+ */
static inline int effective_prio(task_t *p)
{
int bonus, prio;
- /*
- * Here we scale the actual sleep average [0 .... MAX_SLEEP_AVG]
- * into the -5 ... 0 ... +5 bonus/penalty range.
- *
- * We use 25% of the full 0...39 priority range so that:
- *
- * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs.
- * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks.
- *
- * Both properties are important to certain workloads.
- */
bonus = MAX_USER_PRIO*PRIO_BONUS_RATIO*p->sleep_avg/MAX_SLEEP_AVG/100 -
MAX_USER_PRIO*PRIO_BONUS_RATIO/100/2;
@@ -253,6 +256,12 @@
return prio;
}
+/*
+ * activate_task - move a task to the runqueue.
+ *
+ * Also update all the scheduling statistics stuff. (sleep average
+ * calculation, priority modifiers, etc.)
+ */
static inline void activate_task(task_t *p, runqueue_t *rq)
{
unsigned long sleep_time = jiffies - p->sleep_timestamp;
@@ -275,6 +284,9 @@
rq->nr_running++;
}
+/*
+ * deactivate_task - remove a task from the runqueue.
+ */
static inline void deactivate_task(struct task_struct *p, runqueue_t *rq)
{
rq->nr_running--;
@@ -284,6 +296,13 @@
p->array = NULL;
}
+/*
+ * resched_task - mark a task 'to be rescheduled now'.
+ *
+ * On UP this means the setting of the need_resched flag, on SMP it
+ * might also involve a cross-CPU call to trigger the scheduler on
+ * the target CPU.
+ */
static inline void resched_task(task_t *p)
{
#ifdef CONFIG_SMP
@@ -302,8 +321,10 @@
#ifdef CONFIG_SMP
/*
- * Wait for a process to unschedule. This is used by the exit() and
- * ptrace() code.
+ * wait_task_inactive - wait for a thread to unschedule.
+ *
+ * The caller must ensure that the task *will* unschedule sometime soon,
+ * else this function might spin for a *long* time.
*/
void wait_task_inactive(task_t * p)
{
@@ -325,9 +346,10 @@
}
/*
- * Kick the remote CPU if the task is running currently,
- * this code is used by the signal code to signal tasks
- * which are in user-mode as quickly as possible.
+ * kick_if_running - kick the remote CPU if the task is running currently.
+ *
+ * This code is used by the signal code to signal tasks
+ * which are in user-mode, as quickly as possible.
*
* (Note that we do this lockless - if the task does anything
* while the message is in flight then it will notice the
@@ -340,13 +362,18 @@
}
#endif
-/*
- * Wake up a process. Put it on the run-queue if it's not
- * already there. The "current" process is always on the
- * run-queue (except when the actual re-schedule is in
- * progress), and as such you're allowed to do the simpler
- * "current->state = TASK_RUNNING" to mark yourself runnable
- * without the overhead of this.
+/***
+ * try_to_wake_up - wake up a thread
+ * @p: the to-be-woken-up thread
+ * @sync: do a synchronous wakeup?
+ *
+ * Put it on the run-queue if it's not already there. The "current"
+ * thread is always on the run-queue (except when the actual
+ * re-schedule is in progress), and as such you're allowed to do
+ * the simpler "current->state = TASK_RUNNING" to mark yourself
+ * runnable without the overhead of this.
+ *
+ * returns failure only if the task is already active.
*/
static int try_to_wake_up(task_t * p, int sync)
{
@@ -374,9 +401,6 @@
if (old_state == TASK_UNINTERRUPTIBLE)
rq->nr_uninterruptible--;
activate_task(p, rq);
- /*
- * If sync is set, a resched_task() is a NOOP
- */
if (p->prio < rq->curr->prio)
resched_task(rq->curr);
success = 1;
@@ -392,6 +416,12 @@
return try_to_wake_up(p, 0);
}
+/*
+ * wake_up_forked_process - wake up a freshly forked process.
+ *
+ * This function will do some initial scheduler statistics housekeeping
+ * that must be done for every newly created process.
+ */
void wake_up_forked_process(task_t * p)
{
runqueue_t *rq = this_rq_lock();
@@ -416,7 +446,7 @@
/*
* Potentially available exiting-child timeslices are
* retrieved here - this way the parent does not get
- * penalized for creating too many processes.
+ * penalized for creating too many threads.
*
* (this cannot be used to 'generate' timeslices
* artificially, because any timeslice recovered here
@@ -438,6 +468,11 @@
p->sleep_avg) / (EXIT_WEIGHT + 1);
}
+/**
+ * schedule_tail - first thing a freshly forked thread must call.
+ *
+ * @prev: the thread we just switched away from.
+ */
#if CONFIG_SMP
asmlinkage void schedule_tail(task_t *prev)
{
@@ -446,6 +481,10 @@
}
#endif
+/*
+ * context_switch - switch to the new MM and the new
+ * thread's register state.
+ */
static inline task_t * context_switch(task_t *prev, task_t *next)
{
struct mm_struct *mm = next->mm;
@@ -469,6 +508,13 @@
return prev;
}
+/*
+ * nr_running, nr_uninterruptible and nr_context_switches:
+ *
+ * externally visible scheduler statistics: current number of runnable
+ * threads, current number of uninterruptible-sleeping threads, total
+ * number of context switches performed since bootup.
+ */
unsigned long nr_running(void)
{
unsigned long i, sum = 0;
@@ -499,6 +545,10 @@
return sum;
}
+/**
+ * idle_cpu - is a given cpu idle currently?
+ * @cpu: the processor in question.
+ */
inline int idle_cpu(int cpu)
{
return cpu_curr(cpu) == cpu_rq(cpu)->idle;
@@ -506,8 +556,10 @@
#if CONFIG_SMP
/*
- * Lock the busiest runqueue as well, this_rq is locked already.
- * Recalculate nr_running if we have to drop the runqueue lock.
+ * double_lock_balance - lock the busiest runqueue
+ *
+ * this_rq is locked already. Recalculate nr_running if we have to
+ * drop the runqueue lock.
*/
static inline unsigned int double_lock_balance(runqueue_t *this_rq,
runqueue_t *busiest, int this_cpu, int idle, unsigned int nr_running)
@@ -691,8 +743,8 @@
}
/*
- * One of the idle_cpu_tick() or the busy_cpu_tick() function will
- * gets called every timer tick, on every CPU. Our balancing action
+ * One of the idle_cpu_tick() and busy_cpu_tick() functions will
+ * get called every timer tick, on every CPU. Our balancing action
* frequency and balancing agressivity depends on whether the CPU is
* idle or not.
*
@@ -806,7 +858,7 @@
void scheduling_functions_start_here(void) { }
/*
- * 'schedule()' is the main scheduler function.
+ * schedule() is the main scheduler function.
*/
asmlinkage void schedule(void)
{
@@ -916,6 +968,12 @@
}
}
+/**
+ * __wake_up - wake up threads blocked on a waitqueue.
+ * @q: the waitqueue
+ * @mode: which threads
+ * @nr_exclusive: how many wake-one or wake-many threads to wake up
+ */
void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
{
unsigned long flags;
@@ -930,6 +988,17 @@
#if CONFIG_SMP
+/**
+ * __wake_up - sync- wake up threads blocked on a waitqueue.
+ * @q: the waitqueue
+ * @mode: which threads
+ * @nr_exclusive: how many wake-one or wake-many threads to wake up
+ *
+ * The sync wakeup differs that the waker knows that it will schedule
+ * away soon, so while the target thread will be woken up, it will not
+ * be migrated to another CPU - ie. the two threads are 'synchronized'
+ * with each other. This can prevent needless bouncing between CPUs.
+ */
void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
{
unsigned long flags;
@@ -1079,12 +1148,13 @@
#ifndef __alpha__
-/*
- * This has been replaced by sys_setpriority. Maybe it should be
- * moved into the arch dependent tree for those ports that require
- * it for backward compatibility?
+/**
+ * sys_nice - change the priority of the current process.
+ * @increment: priority increment
+ *
+ * sys_setpriority is a more generic, but much slower function that
+ * does similar things.
*/
-
asmlinkage long sys_nice(int increment)
{
long nice;
@@ -1114,9 +1184,11 @@
#endif
-/*
- * This is the priority value as seen by users in /proc
+/**
+ * task_prio - return the priority value of a given task.
+ * @p: the task in question.
*
+ * This is the priority value as seen by users in /proc.
* RT tasks are offset by -200. Normal tasks are centered
* around 0, value goes from -16 to +15.
*/
@@ -1125,16 +1197,27 @@
return p->prio - MAX_USER_RT_PRIO;
}
+/**
+ * task_nice - return the nice value of a given task.
+ * @p: the task in question.
+ */
int task_nice(task_t *p)
{
return TASK_NICE(p);
}
+/**
+ * find_process_by_pid - find a process with a matching PID value.
+ * @pid: the pid in question.
+ */
static inline task_t *find_process_by_pid(pid_t pid)
{
return pid ? find_task_by_pid(pid) : current;
}
+/*
+ * setscheduler - change the scheduling policy and/or RT priority of a thread.
+ */
static int setscheduler(pid_t pid, int policy, struct sched_param *param)
{
struct sched_param lp;
@@ -1217,17 +1300,32 @@
return retval;
}
+/**
+ * sys_sched_setscheduler - set/change the scheduler policy and RT priority
+ * @pid: the pid in question.
+ * @policy: new policy
+ * @param: structure containing the new RT priority.
+ */
asmlinkage long sys_sched_setscheduler(pid_t pid, int policy,
struct sched_param *param)
{
return setscheduler(pid, policy, param);
}
+/**
+ * sys_sched_setparam - set/change the RT priority of a thread
+ * @pid: the pid in question.
+ * @param: structure containing the new RT priority.
+ */
asmlinkage long sys_sched_setparam(pid_t pid, struct sched_param *param)
{
return setscheduler(pid, -1, param);
}
+/**
+ * sys_sched_getscheduler - get the policy (scheduling class) of a thread
+ * @pid: the pid in question.
+ */
asmlinkage long sys_sched_getscheduler(pid_t pid)
{
int retval = -EINVAL;
@@ -1247,6 +1345,11 @@
return retval;
}
+/**
+ * sys_sched_getparam - get the RT priority of a thread
+ * @pid: the pid in question.
+ * @param: sched_param structure containing the RT priority.
+ */
asmlinkage long sys_sched_getparam(pid_t pid, struct sched_param *param)
{
struct sched_param lp;
@@ -1411,6 +1514,13 @@
sys_sched_yield();
}
+/**
+ * sys_sched_get_priority_max - return maximum RT priority.
+ * @policy: scheduling class.
+ *
+ * this syscall returns the maximum rt_priority that can be used
+ * by a given scheduling class.
+ */
asmlinkage long sys_sched_get_priority_max(int policy)
{
int ret = -EINVAL;
@@ -1427,6 +1537,13 @@
return ret;
}
+/**
+ * sys_sched_get_priority_min - return minimum RT priority.
+ * @policy: scheduling class.
+ *
+ * this syscall returns the minimum rt_priority that can be used
+ * by a given scheduling class.
+ */
asmlinkage long sys_sched_get_priority_min(int policy)
{
int ret = -EINVAL;
@@ -1442,6 +1559,14 @@
return ret;
}
+/**
+ * sys_sched_rr_get_interval - return the default timeslice of a process.
+ * @pid: pid of the process.
+ * @interval: userspace pointer to the timeslice value.
+ *
+ * this syscall writes the default timeslice value of a given process
+ * into the user-space timespec buffer. A value of '0' means infinity.
+ */
asmlinkage long sys_sched_rr_get_interval(pid_t pid, struct timespec *interval)
{
int retval = -EINVAL;
@@ -1734,6 +1859,10 @@
;
}
+/*
+ * migration_thread - this is a highprio system thread that performs
+ * thread migration by 'pulling' threads into the target runqueue.
+ */
static int migration_thread(void * bind_cpu)
{
struct sched_param param = { sched_priority: MAX_RT_PRIO-1 };
reply other threads:[~2002-09-11 22:17 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=1031782897.1023.31.camel@phantasy \
--to=rml@tech9.net \
--cc=alan@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.