X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=mm%2Foom_kill.c;h=96473b482099793384af969b8158e1306e2d4f58;hb=65f7651788e18fadb2fbb7276af935d7871e1803;hp=00d0bd7d6a2bfd3d7eaf389fc2ef8b96011d6883;hpb=fe071d7e8aae5745c009c808bb8933f22a9e305a;p=linux-2.6 diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 00d0bd7d6a..96473b4820 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -28,7 +28,7 @@ int sysctl_panic_on_oom; int sysctl_oom_kill_allocating_task; -static DEFINE_MUTEX(zone_scan_mutex); +static DEFINE_SPINLOCK(zone_scan_mutex); /* #define DEBUG */ /** @@ -143,7 +143,7 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) * because p may have allocated or otherwise mapped memory on * this node before. However it will be less likely. */ - if (!cpuset_excl_nodes_overlap(p)) + if (!cpuset_mems_allowed_intersects(current, p)) points /= 8; /* @@ -212,7 +212,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints) if (!p->mm) continue; /* skip the init task */ - if (is_init(p)) + if (is_global_init(p)) continue; /* @@ -265,7 +265,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints) */ static void __oom_kill_task(struct task_struct *p, int verbose) { - if (is_init(p)) { + if (is_global_init(p)) { WARN_ON(1); printk(KERN_WARNING "tried to kill init!\n"); return; @@ -278,14 +278,15 @@ static void __oom_kill_task(struct task_struct *p, int verbose) } if (verbose) - printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm); + printk(KERN_ERR "Killed process %d (%s)\n", + task_pid_nr(p), p->comm); /* * We give our sacrificial lamb high priority and access to * all the memory it needs. That way it should be able to * exit() and clear out its resources quickly... */ - p->time_slice = HZ; + p->rt.time_slice = HZ; set_tsk_thread_flag(p, TIF_MEMDIE); force_sig(SIGKILL, p); @@ -326,18 +327,25 @@ static int oom_kill_task(struct task_struct *p) * to memory reserves though, otherwise we might deplete all memory. */ do_each_thread(g, q) { - if (q->mm == mm && q->tgid != p->tgid) + if (q->mm == mm && !same_thread_group(q, p)) force_sig(SIGKILL, q); } while_each_thread(g, q); return 0; } -static int oom_kill_process(struct task_struct *p, unsigned long points, - const char *message) +static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, + unsigned long points, const char *message) { struct task_struct *c; - struct list_head *tsk; + + if (printk_ratelimit()) { + printk(KERN_WARNING "%s invoked oom-killer: " + "gfp_mask=0x%x, order=%d, oomkilladj=%d\n", + current->comm, gfp_mask, order, current->oomkilladj); + dump_stack(); + show_mem(); + } /* * If the task is already exiting, don't alarm the sysadmin or kill @@ -349,11 +357,10 @@ static int oom_kill_process(struct task_struct *p, unsigned long points, } printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n", - message, p->pid, p->comm, points); + message, task_pid_nr(p), p->comm, points); /* Try to kill a child first */ - list_for_each(tsk, &p->children) { - c = list_entry(tsk, struct task_struct, sibling); + list_for_each_entry(c, &p->children, sibling) { if (c->mm == p->mm) continue; if (!oom_kill_task(c)) @@ -388,7 +395,7 @@ int try_set_zone_oom(struct zonelist *zonelist) z = zonelist->zones; - mutex_lock(&zone_scan_mutex); + spin_lock(&zone_scan_mutex); do { if (zone_is_oom_locked(*z)) { ret = 0; @@ -405,7 +412,7 @@ int try_set_zone_oom(struct zonelist *zonelist) zone_set_flag(*z, ZONE_OOM_LOCKED); } while (*(++z) != NULL); out: - mutex_unlock(&zone_scan_mutex); + spin_unlock(&zone_scan_mutex); return ret; } @@ -420,11 +427,11 @@ void clear_zonelist_oom(struct zonelist *zonelist) z = zonelist->zones; - mutex_lock(&zone_scan_mutex); + spin_lock(&zone_scan_mutex); do { zone_clear_flag(*z, ZONE_OOM_LOCKED); } while (*(++z) != NULL); - mutex_unlock(&zone_scan_mutex); + spin_unlock(&zone_scan_mutex); } /** @@ -447,14 +454,6 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) /* Got some memory back in the last second. */ return; - if (printk_ratelimit()) { - printk(KERN_WARNING "%s invoked oom-killer: " - "gfp_mask=0x%x, order=%d, oomkilladj=%d\n", - current->comm, gfp_mask, order, current->oomkilladj); - dump_stack(); - show_mem(); - } - if (sysctl_panic_on_oom == 2) panic("out of memory. Compulsory panic_on_oom is selected.\n"); @@ -463,12 +462,11 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) * NUMA) that may require different handling. */ constraint = constrained_alloc(zonelist, gfp_mask); - cpuset_lock(); read_lock(&tasklist_lock); switch (constraint) { case CONSTRAINT_MEMORY_POLICY: - oom_kill_process(current, points, + oom_kill_process(current, gfp_mask, order, points, "No available memory (MPOL_BIND)"); break; @@ -478,7 +476,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) /* Fall-through */ case CONSTRAINT_CPUSET: if (sysctl_oom_kill_allocating_task) { - oom_kill_process(current, points, + oom_kill_process(current, gfp_mask, order, points, "Out of memory (oom_kill_allocating_task)"); break; } @@ -495,11 +493,11 @@ retry: /* Found nothing?!?! Either we hang forever, or we panic. */ if (!p) { read_unlock(&tasklist_lock); - cpuset_unlock(); panic("Out of memory and no killable processes...\n"); } - if (oom_kill_process(p, points, "Out of memory")) + if (oom_kill_process(p, gfp_mask, order, points, + "Out of memory")) goto retry; break; @@ -507,7 +505,6 @@ retry: out: read_unlock(&tasklist_lock); - cpuset_unlock(); /* * Give "p" a good chance of killing itself before we