Messages in this thread | | | Date | Mon, 4 May 1998 09:47:15 +0200 (MET DST) | From | Rik van Riel <> | Subject | Draft version of Out-Of-Memory killer |
| |
Hi,
I've made a draft version of the out-of-memory killer (linux/mm/oom_kill.c) but it isn't complete yet and could probably be better.
Especially the IOPL/IOPERM stuff is very important but I haven't figured it out yet :(
Also, there's no code yet to trigger this routine, so everybody should be safe for now :) (I post this mainly because we've had several flamewars over this issue and I want to prevent that this time)
Rik. +-------------------------------------------+--------------------------+ | Linux: - LinuxHQ MM-patches page | Scouting webmaster | | - kswapd ask-him & complain-to guy | Vries cubscout leader | | http://www.phys.uu.nl/~riel/ | <H.H.vanRiel@phys.uu.nl> | +-------------------------------------------+--------------------------+
/* * linux/mm/oom_kill.c * * Copyright (C) 1998 Rik van Riel * * The routines in this file are used to kill a process when * we're seriously out of memory. This gets called from kswapd() * in linux/mm/vmscan.c when the pageout daemon gets stuck. * * We hope to call this function as little as often, there are * no critical code paths in here. Don't try to be smart, just * leave it ultra-readable so we'll never mess up... */
#include <linux/sched.h>
#define DEBUG
/* Ugly helper function, we don't want to do without it because * the points variable might overflow if we just squared the * size instead. */ inline int int_sqrt(int x) { int i,out; for (i = 10; i-- > 0;) out = x + out >> 1; if (out) return out; return 1; }
inline int badness(task_struct *p) { int points = p->mm->total_vm; points /= int_sqrt((p->tms->tms_utime + p->tms->tms_stime) >> (SHIFT_HZ + 6)) if (p->priority < DEF_PRIORITY) points <<= 1; if (p->uid == 0 || p->euid == 0) points >>= 1; /* FIXME: - strange assumption being made :) * - not jiffie-overflow safe! */ if (p->start_time < jiffies >> 6) points >>= 1; /* FIXME: How can I test for IOPL or IOPERM permissions??? */ if (/* p->tss-> || */ p->cap_effective & CAP_SYS_RAWIO) points = 0; #ifdef DEBUG printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n", p->pid, p->comm, points); #endif }
inline struct task_struct * select_bad_process(void) { int points = 0; struct task_struct *p = NULL; struct task_struct *chosen = NULL; read_lock(&tasklist_lock); /* We might need this on SMP */ for_each_task(p) if (p->pid && badness(p) > points) chosen = p; read_unlock(&tasklist_lock); return chosen; }
/* * The SCHED_FIFO magic is because we want the process to * be able to kill itself even when kswapd is running. */ void oom_kill(void) {
struct task_struct *p = select_bad_process(); if (p == NULL) return; force_sig(SIGKILL, p); p->policy = SCHED_FIFO; p->rt_priority = 1000; current->policy |= SCHED_YIELD; schedule(); }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |