[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>
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index c472f97..3bc6069 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -48,6 +48,9 @@
extern struct file_operations proc_cpuset_operations;
extern char *cpuset_task_status_allowed(struct task_struct *task, char *buffer);
+extern void cpuset_lock(void);
+extern void cpuset_unlock(void);
+
#else /* !CONFIG_CPUSETS */
static inline int cpuset_init_early(void) { return 0; }
@@ -93,6 +96,9 @@
return buffer;
}
+static inline void cpuset_lock(void) {}
+static inline void cpuset_unlock(void) {}
+
#endif /* !CONFIG_CPUSETS */
#endif /* _LINUX_CPUSET_H */