aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorTim Schmielau <tim@physik3.uni-rostock.de>2004-10-13 07:27:49 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-10-13 07:27:49 -0700
commitb9877c907d56b803b5b0241c2465ce768809fce9 (patch)
tree86de6ef294704e1a5a31591b157c41402fe7c897 /mm
parent1a9c15ac3687ec00574be4ad0f3ee1b299062ca4 (diff)
downloadhistory-b9877c907d56b803b5b0241c2465ce768809fce9.tar.gz
[PATCH] Fix reporting of process start times
Derive process start times from the posix_clock_monotonic notion of uptime instead of "jiffies", consistent with the earlier change to /proc/uptime itself. (http://linus.bkbits.net:8080/linux-2.5/cset@3ef4851dGg0fxX58R9Zv8SIq9fzNmQ?na%0Av=index.html|src/.|src/fs|src/fs/proc|related/fs/proc/proc_misc.c) Process start times are reported to userspace in units of 1/USER_HZ since boot, thus applications as procps need the value of "uptime" to convert them into absolute time. Currently "uptime" is derived from an ntp-corrected time base, but process start time is derived from the free-running "jiffies" counter. This results in inaccurate, drifting process start times as seen by the user, even if the exported number stays constant, because the users notion of "jiffies" changes in time. It's John Stultz's patch anyways, which I only messed up a bit, but since people started trading signed-off lines on lkml: Signed-off-by: Tim Schmielau <tim@physik3.uni-rostock.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/oom_kill.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 48f6dde410b342..3868e29e85bef9 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -26,6 +26,7 @@
/**
* oom_badness - calculate a numeric value for how bad this task has been
* @p: task struct of which task we should calculate
+ * @p: current uptime in seconds
*
* The formula used is relatively simple and documented inline in the
* function. The main rationale is that we want to select a good task
@@ -41,7 +42,7 @@
* of least surprise ... (be careful when you change it)
*/
-static unsigned long badness(struct task_struct *p)
+static unsigned long badness(struct task_struct *p, unsigned long uptime)
{
unsigned long points, cpu_time, run_time, s;
@@ -56,12 +57,16 @@ static unsigned long badness(struct task_struct *p)
points = p->mm->total_vm;
/*
- * CPU time is in seconds and run time is in minutes. There is no
- * particular reason for this other than that it turned out to work
- * very well in practice.
+ * CPU time is in tens of seconds and run time is in thousands
+ * of seconds. There is no particular reason for this other than
+ * that it turned out to work very well in practice.
*/
cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3);
- run_time = (get_jiffies_64() - p->start_time) >> (SHIFT_HZ + 10);
+
+ if (uptime >= p->start_time.tv_sec)
+ run_time = (uptime - p->start_time.tv_sec) >> 10;
+ else
+ run_time = 0;
s = int_sqrt(cpu_time);
if (s)
@@ -111,10 +116,12 @@ static struct task_struct * select_bad_process(void)
unsigned long maxpoints = 0;
struct task_struct *g, *p;
struct task_struct *chosen = NULL;
+ struct timespec uptime;
+ do_posix_clock_monotonic_gettime(&uptime);
do_each_thread(g, p)
if (p->pid) {
- unsigned long points = badness(p);
+ unsigned long points = badness(p, uptime.tv_sec);
if (points > maxpoints) {
chosen = p;
maxpoints = points;