for (;;) {
                bool freeze;
 
+               raw_spin_lock_irq(¤t->pi_lock);
                set_current_state(TASK_FROZEN);
+               /* unstale saved_state so that __thaw_task() will wake us up */
+               current->saved_state = TASK_RUNNING;
+               raw_spin_unlock_irq(¤t->pi_lock);
 
                spin_lock_irq(&freezer_lock);
                freeze = freezing(current) && !(check_kthr_stop && kthread_should_stop());
                WARN_ON_ONCE(debug_locks && p->lockdep_depth);
 #endif
 
+       p->saved_state = p->__state;
        WRITE_ONCE(p->__state, TASK_FROZEN);
        return TASK_FROZEN;
 }
 }
 
 /*
- * The special task states (TASK_STOPPED, TASK_TRACED) keep their canonical
- * state in p->jobctl. If either of them got a wakeup that was missed because
- * TASK_FROZEN, then their canonical state reflects that and the below will
- * refuse to restore the special state and instead issue the wakeup.
+ * Restore the saved_state before the task entered freezer. For typical task
+ * in the __refrigerator(), saved_state == TASK_RUNNING so nothing happens
+ * here. For tasks which were TASK_NORMAL | TASK_FREEZABLE, their initial state
+ * is restored unless they got an expected wakeup (see ttwu_state_match()).
+ * Returns 1 if the task state was restored.
  */
-static int __set_task_special(struct task_struct *p, void *arg)
+static int __restore_freezer_state(struct task_struct *p, void *arg)
 {
-       unsigned int state = 0;
+       unsigned int state = p->saved_state;
 
-       if (p->jobctl & JOBCTL_TRACED)
-               state = TASK_TRACED;
-
-       else if (p->jobctl & JOBCTL_STOPPED)
-               state = TASK_STOPPED;
-
-       if (state)
+       if (state != TASK_RUNNING) {
                WRITE_ONCE(p->__state, state);
+               return 1;
+       }
 
-       return state;
+       return 0;
 }
 
 void __thaw_task(struct task_struct *p)
 {
-       unsigned long flags, flags2;
+       unsigned long flags;
 
        spin_lock_irqsave(&freezer_lock, flags);
        if (WARN_ON_ONCE(freezing(p)))
                goto unlock;
 
-       if (lock_task_sighand(p, &flags2)) {
-               /* TASK_FROZEN -> TASK_{STOPPED,TRACED} */
-               bool ret = task_call_func(p, __set_task_special, NULL);
-               unlock_task_sighand(p, &flags2);
-               if (ret)
-                       goto unlock;
-       }
+       if (task_call_func(p, __restore_freezer_state, NULL))
+               goto unlock;
 
        wake_up_state(p, TASK_FROZEN);
 unlock:
 
 int task_state_match(struct task_struct *p, unsigned int state)
 {
        /*
-        * Serialize against current_save_and_set_rtlock_wait_state() and
-        * current_restore_rtlock_saved_state().
+        * Serialize against current_save_and_set_rtlock_wait_state(),
+        * current_restore_rtlock_saved_state(), and __refrigerator().
         */
        guard(raw_spinlock_irq)(&p->pi_lock);
        return __task_state_match(p, state);
  * The caller holds p::pi_lock if p != current or has preemption
  * disabled when p == current.
  *
- * The rules of PREEMPT_RT saved_state:
+ * The rules of saved_state:
  *
  *   The related locking code always holds p::pi_lock when updating
  *   p::saved_state, which means the code is fully serialized in both cases.
  *
- *   The lock wait and lock wakeups happen via TASK_RTLOCK_WAIT. No other
- *   bits set. This allows to distinguish all wakeup scenarios.
+ *   For PREEMPT_RT, the lock wait and lock wakeups happen via TASK_RTLOCK_WAIT.
+ *   No other bits set. This allows to distinguish all wakeup scenarios.
+ *
+ *   For FREEZER, the wakeup happens via TASK_FROZEN. No other bits set. This
+ *   allows us to prevent early wakeup of tasks before they can be run on
+ *   asymmetric ISA architectures (eg ARMv9).
  */
 static __always_inline
 bool ttwu_state_match(struct task_struct *p, unsigned int state, int *success)
 
        /*
         * Saved state preserves the task state across blocking on
-        * an RT lock.  If the state matches, set p::saved_state to
-        * TASK_RUNNING, but do not wake the task because it waits
-        * for a lock wakeup. Also indicate success because from
-        * the regular waker's point of view this has succeeded.
+        * an RT lock or TASK_FREEZABLE tasks.  If the state matches,
+        * set p::saved_state to TASK_RUNNING, but do not wake the task
+        * because it waits for a lock wakeup or __thaw_task(). Also
+        * indicate success because from the regular waker's point of
+        * view this has succeeded.
         *
         * After acquiring the lock the task will restore p::__state
         * from p::saved_state which ensures that the regular