Skip to content
  • Rafael J. Wysocki's avatar
    [PATCH] PM: Fix SMP races in the freezer · 8a102eed
    Rafael J. Wysocki authored
    
    
    Currently, to tell a task that it should go to the refrigerator, we set the
    PF_FREEZE flag for it and send a fake signal to it.  Unfortunately there
    are two SMP-related problems with this approach.  First, a task running on
    another CPU may be updating its flags while the freezer attempts to set
    PF_FREEZE for it and this may leave the task's flags in an inconsistent
    state.  Second, there is a potential race between freeze_process() and
    refrigerator() in which freeze_process() running on one CPU is reading a
    task's PF_FREEZE flag while refrigerator() running on another CPU has just
    set PF_FROZEN for the same task and attempts to reset PF_FREEZE for it.  If
    the refrigerator wins the race, freeze_process() will state that PF_FREEZE
    hasn't been set for the task and will set it unnecessarily, so the task
    will go to the refrigerator once again after it's been thawed.
    
    To solve first of these problems we need to stop using PF_FREEZE to tell
    tasks that they should go to the refrigerator.  Instead, we can introduce a
    special TIF_*** flag and use it for this purpose, since it is allowed to
    change the other tasks' TIF_*** flags and there are special calls for it.
    
    To avoid the freeze_process()-refrigerator() race we can make
    freeze_process() to always check the task's PF_FROZEN flag after it's read
    its "freeze" flag.  We should also make sure that refrigerator() will
    always reset the task's "freeze" flag after it's set PF_FROZEN for it.
    
    Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
    Acked-by: default avatarPavel Machek <pavel@ucw.cz>
    Cc: Russell King <rmk@arm.linux.org.uk>
    Cc: David Howells <dhowells@redhat.com>
    Cc: Andi Kleen <ak@muc.de>
    Cc: "Luck, Tony" <tony.luck@intel.com>
    Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Paul Mundt <lethal@linux-sh.org>
    Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    8a102eed