summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/freezer.h9
-rw-r--r--kernel/freezer.c25
2 files changed, 30 insertions, 4 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 3d50913d39d..a0f1b3a3604 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -49,6 +49,7 @@ static inline bool try_to_freeze(void)
}
extern bool freeze_task(struct task_struct *p, bool sig_only);
+extern bool __set_freezable(bool with_signal);
#ifdef CONFIG_CGROUP_FREEZER
extern bool cgroup_freezing(struct task_struct *task);
@@ -106,18 +107,18 @@ static inline int freezer_should_skip(struct task_struct *p)
/*
* Tell the freezer that the current task should be frozen by it
*/
-static inline void set_freezable(void)
+static inline bool set_freezable(void)
{
- current->flags &= ~PF_NOFREEZE;
+ return __set_freezable(false);
}
/*
* Tell the freezer that the current task should be frozen by it and that it
* should send a fake signal to the task to freeze it.
*/
-static inline void set_freezable_with_signal(void)
+static inline bool set_freezable_with_signal(void)
{
- current->flags &= ~(PF_NOFREEZE | PF_FREEZER_NOSIG);
+ return __set_freezable(true);
}
/*
diff --git a/kernel/freezer.c b/kernel/freezer.c
index 95a12384424..b1e7a7b3d2c 100644
--- a/kernel/freezer.c
+++ b/kernel/freezer.c
@@ -171,3 +171,28 @@ void __thaw_task(struct task_struct *p)
}
spin_unlock_irqrestore(&freezer_lock, flags);
}
+
+/**
+ * __set_freezable - make %current freezable
+ * @with_signal: do we want %TIF_SIGPENDING for notification too?
+ *
+ * Mark %current freezable and enter refrigerator if necessary.
+ */
+bool __set_freezable(bool with_signal)
+{
+ might_sleep();
+
+ /*
+ * Modify flags while holding freezer_lock. This ensures the
+ * freezer notices that we aren't frozen yet or the freezing
+ * condition is visible to try_to_freeze() below.
+ */
+ spin_lock_irq(&freezer_lock);
+ current->flags &= ~PF_NOFREEZE;
+ if (with_signal)
+ current->flags &= ~PF_FREEZER_NOSIG;
+ spin_unlock_irq(&freezer_lock);
+
+ return try_to_freeze();
+}
+EXPORT_SYMBOL(__set_freezable);