aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorPaul Jackson <pj@sgi.com>2005-10-30 18:02:30 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-30 20:37:21 -0500
commit053199edf54f685e7dea765b60d4d5e9070dadec (patch)
treea2d12a8b7f07b59048da992e7ae9405bc4ee292b /include/linux
parent5aa15b5f27fc2c404530c6c8eabdb8437deb3163 (diff)
[PATCH] cpusets: dual semaphore locking overhaul
Overhaul cpuset locking. Replace single semaphore with two semaphores. The suggestion to use two locks was made by Roman Zippel. Both locks are global. Code that wants to modify cpusets must first acquire the exclusive manage_sem, which allows them read-only access to cpusets, and holds off other would-be modifiers. Before making actual changes, the second semaphore, callback_sem must be acquired as well. Code that needs only to query cpusets must acquire callback_sem, which is also a global exclusive lock. The earlier problems with double tripping are avoided, because it is allowed for holders of manage_sem to nest the second callback_sem lock, and only callback_sem is needed by code called from within __alloc_pages(), where the double tripping had been possible. This is not quite the same as a normal read/write semaphore, because obtaining read-only access with intent to change must hold off other such attempts, while allowing read-only access w/o such intention. Changing cpusets involves several related checks and changes, which must be done while allowing read-only queries (to avoid the double trip), but while ensuring nothing changes (holding off other would be modifiers.) This overhaul of cpuset locking also makes careful use of task_lock() to guard access to the task->cpuset pointer, closing a couple of race conditions noticed while reading this code (thanks, Roman). I've never seen these races fail in any use or test. See further the comments in the code. Signed-off-by: Paul Jackson <pj@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/sched.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 1c30bc308ef1..b2d2dc14f0b9 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1211,7 +1211,7 @@ extern void unhash_process(struct task_struct *p);
1211/* 1211/*
1212 * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring 1212 * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring
1213 * subscriptions and synchronises with wait4(). Also used in procfs. Also 1213 * subscriptions and synchronises with wait4(). Also used in procfs. Also
1214 * pins the final release of task.io_context. 1214 * pins the final release of task.io_context. Also protects ->cpuset.
1215 * 1215 *
1216 * Nests both inside and outside of read_lock(&tasklist_lock). 1216 * Nests both inside and outside of read_lock(&tasklist_lock).
1217 * It must not be nested with write_lock_irq(&tasklist_lock), 1217 * It must not be nested with write_lock_irq(&tasklist_lock),