]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Revert "freezer: kill unused set_freezable_with_signal()"
authorStephen Rothwell <sfr@canb.auug.org.au>
Mon, 14 Nov 2011 02:06:38 +0000 (13:06 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Mon, 14 Nov 2011 02:06:38 +0000 (13:06 +1100)
This reverts commit cd3bc8fbc2d55ae0918184fb34992054dc4eb710.

include/linux/freezer.h
include/linux/sched.h
kernel/freezer.c
kernel/kthread.c

index 09570ac22be6063d2efe1cd1e11f8aa39ab02cff..cc779bb9cd74309019cf6f9f8668c2102df585a5 100644 (file)
@@ -49,7 +49,7 @@ static inline bool try_to_freeze(void)
 }
 
 extern bool freeze_task(struct task_struct *p);
-extern bool set_freezable(void);
+extern bool __set_freezable(bool with_signal);
 
 #ifdef CONFIG_CGROUP_FREEZER
 extern bool cgroup_freezing(struct task_struct *task);
@@ -104,6 +104,23 @@ static inline int freezer_should_skip(struct task_struct *p)
        return !!(p->flags & PF_FREEZER_SKIP);
 }
 
+/*
+ * Tell the freezer that the current task should be frozen by it
+ */
+static inline bool set_freezable(void)
+{
+       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 bool set_freezable_with_signal(void)
+{
+       return __set_freezable(true);
+}
+
 /*
  * Freezer-friendly wrappers around wait_event_interruptible(),
  * wait_event_killable() and wait_event_interruptible_timeout(), originally
@@ -161,6 +178,7 @@ static inline void freezer_do_not_count(void) {}
 static inline void freezer_count(void) {}
 static inline int freezer_should_skip(struct task_struct *p) { return 0; }
 static inline void set_freezable(void) {}
+static inline void set_freezable_with_signal(void) {}
 
 #define wait_event_freezable(wq, condition)                            \
                wait_event_interruptible(wq, condition)
index 35718ff316009c930e90cb07173fe78736b56b12..5e5734ee37af3e26f07a65cf51ac4aaaf635bc2d 100644 (file)
@@ -1788,6 +1788,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *
 #define PF_MEMPOLICY   0x10000000      /* Non-default NUMA mempolicy */
 #define PF_MUTEX_TESTER        0x20000000      /* Thread belongs to the rt mutex tester */
 #define PF_FREEZER_SKIP        0x40000000      /* Freezer should not count it as freezable */
+#define PF_FREEZER_NOSIG 0x80000000    /* Freezer won't send signals to it */
 
 /*
  * Only the _current_ task can read/write to tsk->flags, but other
index 9815b8d1eed5536e312c561a0c066578e359bd51..2589a61de44c9d8d33adc441948e4146b0c13a28 100644 (file)
@@ -39,7 +39,7 @@ bool freezing_slow_path(struct task_struct *p)
        if (pm_nosig_freezing || cgroup_freezing(p))
                return true;
 
-       if (pm_freezing && !(p->flags & PF_KTHREAD))
+       if (pm_freezing && !(p->flags & PF_FREEZER_NOSIG))
                return true;
 
        return false;
@@ -72,6 +72,10 @@ bool __refrigerator(bool check_kthr_stop)
                schedule();
        }
 
+       spin_lock_irq(&current->sighand->siglock);
+       recalc_sigpending(); /* We sent fake signal, clean it up */
+       spin_unlock_irq(&current->sighand->siglock);
+
        pr_debug("%s left refrigerator\n", current->comm);
 
        /*
@@ -116,7 +120,7 @@ bool freeze_task(struct task_struct *p)
                return false;
        }
 
-       if (!(p->flags & PF_KTHREAD)) {
+       if (!(p->flags & PF_FREEZER_NOSIG)) {
                fake_signal_wake_up(p);
                /*
                 * fake_signal_wake_up() goes through p's scheduler
@@ -141,19 +145,28 @@ void __thaw_task(struct task_struct *p)
         * be visible to @p as waking up implies wmb.  Waking up inside
         * freezer_lock also prevents wakeups from leaking outside
         * refrigerator.
+        *
+        * If !FROZEN, @p hasn't reached refrigerator, recalc sigpending to
+        * avoid leaving dangling TIF_SIGPENDING behind.
         */
        spin_lock_irqsave(&freezer_lock, flags);
-       if (frozen(p))
+       if (frozen(p)) {
                wake_up_process(p);
+       } else {
+               spin_lock(&p->sighand->siglock);
+               recalc_sigpending_and_wake(p);
+               spin_unlock(&p->sighand->siglock);
+       }
        spin_unlock_irqrestore(&freezer_lock, flags);
 }
 
 /**
- * set_freezable - make %current freezable
+ * __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(void)
+bool __set_freezable(bool with_signal)
 {
        might_sleep();
 
@@ -164,8 +177,10 @@ bool set_freezable(void)
         */
        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);
+EXPORT_SYMBOL(__set_freezable);
index 3d3de633702eab369586096a47a2f10dde5720aa..1c36deaae2f1fee24ff03d8518ff9b4fa6afdfc3 100644 (file)
@@ -282,7 +282,7 @@ int kthreadd(void *unused)
        set_cpus_allowed_ptr(tsk, cpu_all_mask);
        set_mems_allowed(node_states[N_HIGH_MEMORY]);
 
-       current->flags |= PF_NOFREEZE;
+       current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;
 
        for (;;) {
                set_current_state(TASK_INTERRUPTIBLE);