• Isaac J. Manjarres's avatar
    stop_machine: Disable preemption after queueing stopper threads · 2610e889
    Isaac J. Manjarres authored
    This commit:
    
      9fb8d5dc ("stop_machine, Disable preemption when waking two stopper threads")
    
    does not fully address the race condition that can occur
    as follows:
    
    On one CPU, call it CPU 3, thread 1 invokes
    cpu_stop_queue_two_works(2, 3,...), and the execution is such
    that thread 1 queues the works for migration/2 and migration/3,
    and is preempted after releasing the locks for migration/2 and
    migration/3, but before waking the threads.
    
    Then, On CPU 2, a kworker, call it thread 2, is running,
    and it invokes cpu_stop_queue_two_works(1, 2,...), such that
    thread 2 queues the works for migration/1 and migration/2.
    Meanwhile, on CPU 3, thread 1 resumes execution, and wakes
    migration/2 and migration/3. This means that when CPU 2
    releases the locks for migration/1 and migration/2, but before
    it wakes those threads, it can be preempted by migration/2.
    
    If thread 2 is preempted by migration/2, then migration/2 will
    execute the first work item successfully, since migration/3
    was woken up by CPU 3, but when it goes to execute the second
    work item, it disables preemption, calls multi_cpu_stop(),
    and thus, CPU 2 will wait forever for migration/1, which should
    have been woken up by thread 2. However migration/1 cannot be
    woken up by thread 2, since it is a kworker, so it is affine to
    CPU 2, but CPU 2 is running migration/2 with preemption
    disabled, so thread 2 will never run.
    
    Disable preemption after queueing works for stopper threads
    to ensure that the operation of queueing the works and waking
    the stopper threads is atomic.
    Co-Developed-by: default avatarPrasad Sodagudi <psodagud@codeaurora.org>
    Co-Developed-by: default avatarPavankumar Kondeti <pkondeti@codeaurora.org>
    Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
    Signed-off-by: default avatarPrasad Sodagudi <psodagud@codeaurora.org>
    Signed-off-by: default avatarPavankumar Kondeti <pkondeti@codeaurora.org>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: bigeasy@linutronix.de
    Cc: gregkh@linuxfoundation.org
    Cc: matt@codeblueprint.co.uk
    Fixes: 9fb8d5dc ("stop_machine, Disable preemption when waking two stopper threads")
    Link: http://lkml.kernel.org/r/1531856129-9871-1-git-send-email-isaacm@codeaurora.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    2610e889
stop_machine.c 17.7 KB