• Paul Jackson's avatar
    [PATCH] cpusets: dual semaphore locking overhaul · 053199ed
    Paul Jackson authored
    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: default avatarPaul Jackson <pj@sgi.com>
    Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    053199ed
cpuset.c 52.3 KB