X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=mm%2Foom_kill.c;h=2d30febeafaf5d84a6a596d4b0b711972050fa1b;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=2f15290492b9d6c49a31fd6cb75d91f0474ee8f9;hpb=a8e794ca871505c8ea96cc102f4ad555c5231d7f;p=linux-2.6.git diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 2f1529049..2d30febea 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,9 +42,9 @@ * of least surprise ... (be careful when you change it) */ -static int badness(struct task_struct *p) +static unsigned long badness(struct task_struct *p, unsigned long uptime) { - int points, cpu_time, run_time, s; + unsigned long points, cpu_time, run_time, s; if (!p->mm) return 0; @@ -57,12 +58,16 @@ static int badness(struct task_struct *p) /* add vserver badness ;) */ /* - * 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) @@ -109,13 +114,15 @@ static int badness(struct task_struct *p) */ static struct task_struct * select_bad_process(void) { - int maxpoints = 0; + 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) { - int points = badness(p); + unsigned long points = badness(p, uptime.tv_sec); if (points > maxpoints) { chosen = p; maxpoints = points; @@ -221,7 +228,7 @@ retry: /** * out_of_memory - is the system out of memory? */ -void out_of_memory(void) +void out_of_memory(int gfp_mask) { /* * oom_lock protects out_of_memory()'s static variables. @@ -231,12 +238,6 @@ void out_of_memory(void) static unsigned long first, last, count, lastkill; unsigned long now, since; - /* - * Enough swap space left? Not OOM. - */ - if (nr_swap_pages > 0) - return; - spin_lock(&oom_lock); now = jiffies; since = now - last; @@ -246,7 +247,6 @@ void out_of_memory(void) * If it's been a long time since last failure, * we're not oom. */ - last = now; if (since > 5*HZ) goto reset; @@ -279,6 +279,9 @@ void out_of_memory(void) */ lastkill = now; + printk("oom-killer: gfp_mask=0x%x\n", gfp_mask); + show_free_areas(); + /* oom_kill() sleeps */ spin_unlock(&oom_lock); oom_kill();