[PATCH] cpuset oom lock fix

The problem, reported in:

  http://bugzilla.kernel.org/show_bug.cgi?id=5859

and by various other email messages and lkml posts is that the cpuset hook
in the oom (out of memory) code can try to take a cpuset semaphore while
holding the tasklist_lock (a spinlock).

One must not sleep while holding a spinlock.

The fix seems easy enough - move the cpuset semaphore region outside the
tasklist_lock region.

This required a few lines of mechanism to implement.  The oom code where
the locking needs to be changed does not have access to the cpuset locks,
which are internal to kernel/cpuset.c only.  So I provided a couple more
cpuset interface routines, available to the rest of the kernel, which
simple take and drop the lock needed here (cpusets callback_sem).

Signed-off-by: Paul Jackson <pj@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Paul Jackson 2006-01-14 13:21:06 -08:00 committed by Linus Torvalds
parent ed68cb3676
commit 505970b96e
3 changed files with 37 additions and 5 deletions

View file

@ -274,6 +274,7 @@ void out_of_memory(gfp_t gfp_mask, int order)
show_mem();
}
cpuset_lock();
read_lock(&tasklist_lock);
retry:
p = select_bad_process();
@ -284,6 +285,7 @@ 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");
}
@ -293,6 +295,7 @@ retry:
out:
read_unlock(&tasklist_lock);
cpuset_unlock();
if (mm)
mmput(mm);