30 Jul, 2007

1 commit

  • Introduce CONFIG_SUSPEND representing the ability to enter system sleep
    states, such as the ACPI S3 state, and allow the user to choose SUSPEND
    and HIBERNATION independently of each other.

    Make HOTPLUG_CPU be selected automatically if SUSPEND or HIBERNATION has
    been chosen and the kernel is intended for SMP systems.

    Also, introduce CONFIG_PM_SLEEP which is automatically selected if
    CONFIG_SUSPEND or CONFIG_HIBERNATION is set and use it to select the
    code needed for both suspend and hibernation.

    The top-level power management headers and the ACPI code related to
    suspend and hibernation are modified to use the new definitions (the
    changes in drivers/acpi/sleep/main.c are, mostly, moving code to reduce
    the number of ifdefs).

    There are many other files in which CONFIG_PM can be replaced with
    CONFIG_PM_SLEEP or even with CONFIG_SUSPEND, but they can be updated in
    the future.

    Signed-off-by: Rafael J. Wysocki
    Signed-off-by: Linus Torvalds

    Rafael J. Wysocki
     

20 Jul, 2007

1 commit

  • Kernel threads should not have TIF_FREEZE set when user space processes are
    being frozen, since otherwise some of them might be frozen prematurely.
    To prevent this from happening we can (1) make exit_mm() unset TIF_FREEZE
    unconditionally just after clearing tsk->mm and (2) make try_to_freeze_tasks()
    check if p->mm is different from zero and PF_BORROWED_MM is unset in p->flags
    when user space processes are to be frozen.

    Namely, when user space processes are being frozen, we only should set
    TIF_FREEZE for tasks that have p->mm different from NULL and don't have
    PF_BORROWED_MM set in p->flags. For this reason task_lock() must be used to
    prevent try_to_freeze_tasks() from racing with use_mm()/unuse_mm(), in which
    p->mm and p->flags.PF_BORROWED_MM are changed under task_lock(p). Also, we
    need to prevent the following scenario from happening:

    * daemonize() is called by a task spawned from a user space code path
    * freezer checks if the task has p->mm set and the result is positive
    * task enters exit_mm() and clears its TIF_FREEZE
    * freezer sets TIF_FREEZE for the task
    * task calls try_to_freeze() and goes to the refrigerator, which is wrong at
    that point

    This requires us to acquire task_lock(p) before p->flags.PF_BORROWED_MM and
    p->mm are examined and release it after TIF_FREEZE is set for p (or it turns
    out that TIF_FREEZE should not be set).

    Signed-off-by: Rafael J. Wysocki
    Cc: Gautham R Shenoy
    Cc: Pavel Machek
    Cc: Nigel Cunningham
    Cc: Oleg Nesterov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Rafael J. Wysocki
     

18 Jul, 2007

1 commit

  • Currently, the freezer treats all tasks as freezable, except for the kernel
    threads that explicitly set the PF_NOFREEZE flag for themselves. This
    approach is problematic, since it requires every kernel thread to either
    set PF_NOFREEZE explicitly, or call try_to_freeze(), even if it doesn't
    care for the freezing of tasks at all.

    It seems better to only require the kernel threads that want to or need to
    be frozen to use some freezer-related code and to remove any
    freezer-related code from the other (nonfreezable) kernel threads, which is
    done in this patch.

    The patch causes all kernel threads to be nonfreezable by default (ie. to
    have PF_NOFREEZE set by default) and introduces the set_freezable()
    function that should be called by the freezable kernel threads in order to
    unset PF_NOFREEZE. It also makes all of the currently freezable kernel
    threads call set_freezable(), so it shouldn't cause any (intentional)
    change of behaviour to appear. Additionally, it updates documentation to
    describe the freezing of tasks more accurately.

    [akpm@linux-foundation.org: build fixes]
    Signed-off-by: Rafael J. Wysocki
    Acked-by: Nigel Cunningham
    Cc: Pavel Machek
    Cc: Oleg Nesterov
    Cc: Gautham R Shenoy
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Rafael J. Wysocki
     

24 May, 2007

4 commits

  • Other than refrigerator, no one else calls frozen_process(). So move it from
    include/linux/freezer.h to kernel/power/process.c.

    Also, since a task can be marked as frozen by itself, we don't need to pass
    the (struct task_struct *p) parameter to frozen_process().

    Signed-off-by: Gautham R Shenoy
    Signed-off-by: Rafael J. Wysocki
    Cc: Oleg Nesterov
    Cc: Pavel Machek
    Cc: "Eric W. Biederman"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Gautham R Shenoy
     
  • This patch fixes the race pointed out by Oleg Nesterov.

    * Freezer marks a thread as freezeable.
    * The thread now marks itself PF_NOFREEZE, but it will be frozen on
    on calling try_to_freeze(). Thus the task is frozen, even though it doesn't
    want to.
    * Subsequent thaw_processes() will also fail to thaw the task since it is
    marked PF_NOFREEZE.

    Avoid this problem by checking the task's PF_NOFREEZE status in
    frozen_processes() before marking the task as frozen.

    Signed-off-by: Gautham R Shenoy
    Signed-off-by: Rafael J. Wysocki
    Cc: Oleg Nesterov
    Cc: Pavel Machek
    Cc: "Eric W. Biederman"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Gautham R Shenoy
     
  • Currently try_to_freeze_tasks() has to wait until all of the vforked processes
    exit and for this reason every user can make it fail. To fix this problem we
    can introduce the additional process flag PF_FREEZER_SKIP to be used by tasks
    that do not want to be counted as freezable by the freezer and want to have
    TIF_FREEZE set nevertheless. Then, this flag can be set by tasks using
    sys_vfork() before they call wait_for_completion(&vfork) and cleared after
    they have woken up. After clearing it, the tasks should call try_to_freeze()
    as soon as possible.

    Signed-off-by: Rafael J. Wysocki
    Cc: Gautham R Shenoy
    Cc: Oleg Nesterov
    Cc: Pavel Machek
    Cc: "Eric W. Biederman"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Rafael J. Wysocki
     
  • If the freezing of tasks fails and a task is preempted in refrigerator()
    before calling frozen_process(), then thaw_tasks() may run before this task is
    frozen. In that case the task will freeze and no one will thaw it.

    To fix this race we can call freezing(current) in refrigerator() along with
    frozen_process(current) under the task_lock() which also should be taken in
    the error path of try_to_freeze_tasks() as well as in thaw_process().
    Moreover, if thaw_process() additionally clears TIF_FREEZE for tasks that are
    not frozen, we can be sure that all tasks are thawed and there are no pending
    "freeze" requests after thaw_tasks() has run.

    Signed-off-by: Rafael J. Wysocki
    Acked-by: Pavel Machek
    Cc: Gautham R Shenoy
    Cc: Oleg Nesterov
    Cc: "Eric W. Biederman"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Rafael J. Wysocki
     

14 Dec, 2006

1 commit

  • 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: Rafael J. Wysocki
    Acked-by: Pavel Machek
    Cc: Russell King
    Cc: David Howells
    Cc: Andi Kleen
    Cc: "Luck, Tony"
    Cc: Benjamin Herrenschmidt
    Cc: Paul Mackerras
    Cc: Paul Mundt
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Rafael J. Wysocki
     

11 Dec, 2006

1 commit

  • freezer.h uses task_struct fields so it should include sched.h.

    CC [M] fs/jfs/jfs_txnmgr.o
    In file included from fs/jfs/jfs_txnmgr.c:49:
    include/linux/freezer.h: In function 'frozen':
    include/linux/freezer.h:9: error: dereferencing pointer to incomplete type
    include/linux/freezer.h:9: error: 'PF_FROZEN' undeclared (first use in this function)
    include/linux/freezer.h:9: error: (Each undeclared identifier is reported only once
    include/linux/freezer.h:9: error: for each function it appears in.)
    include/linux/freezer.h: In function 'freezing':
    include/linux/freezer.h:17: error: dereferencing pointer to incomplete type
    include/linux/freezer.h:17: error: 'PF_FREEZE' undeclared (first use in this function)
    include/linux/freezer.h: In function 'freeze':
    include/linux/freezer.h:26: error: dereferencing pointer to incomplete type
    include/linux/freezer.h:26: error: 'PF_FREEZE' undeclared (first use in this function)
    include/linux/freezer.h: In function 'do_not_freeze':
    include/linux/freezer.h:34: error: dereferencing pointer to incomplete type
    include/linux/freezer.h:34: error: 'PF_FREEZE' undeclared (first use in this function)
    include/linux/freezer.h: In function 'thaw_process':
    include/linux/freezer.h:43: error: dereferencing pointer to incomplete type
    include/linux/freezer.h:43: error: 'PF_FROZEN' undeclared (first use in this function)
    include/linux/freezer.h:44: warning: implicit declaration of function 'wake_up_process'
    include/linux/freezer.h: In function 'frozen_process':
    include/linux/freezer.h:55: error: dereferencing pointer to incomplete type
    include/linux/freezer.h:55: error: dereferencing pointer to incomplete type
    include/linux/freezer.h:55: error: 'PF_FREEZE' undeclared (first use in this function)
    include/linux/freezer.h:55: error: 'PF_FROZEN' undeclared (first use in this function)
    fs/jfs/jfs_txnmgr.c: In function 'freezing':
    include/linux/freezer.h:18: warning: control reaches end of non-void function
    make[2]: *** [fs/jfs/jfs_txnmgr.o] Error 1

    Signed-off-by: Randy Dunlap
    Acked-by: Dave Kleikamp
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Randy Dunlap
     

08 Dec, 2006

3 commits

  • Move the loop from thaw_processes() to a separate function and call it
    independently for kernel threads and user space processes so that the order
    of thawing tasks is clearly visible.

    Drop thaw_kernel_threads() which is never used.

    Signed-off-by: Rafael J. Wysocki
    Cc: Pavel Machek
    Cc: Nigel Cunningham
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Rafael J. Wysocki
     
  • Modify process thawing so that we can thaw kernel space without thawing
    userspace, and thaw kernelspace first. This will be useful in later
    patches, where I intend to get swsusp thawing kernel threads only before
    seeking to free memory.

    Signed-off-by: Nigel Cunningham
    Cc: Pavel Machek
    Cc: "Rafael J. Wysocki"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Nigel Cunningham
     
  • Move process freezing functions from include/linux/sched.h to freezer.h, so
    that modifications to the freezer or the kernel configuration don't require
    recompiling just about everything.

    [akpm@osdl.org: fix ueagle driver]
    Signed-off-by: Nigel Cunningham
    Cc: "Rafael J. Wysocki"
    Cc: Pavel Machek
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Nigel Cunningham