// SPDX-License-Identifier: GPL-2.0-only
/*
 * kernel/freezer.c - Function to freeze a process
 *
 * Originally from kernel/power/process.c
 */

#include <linux/interrupt.h>
#include <linux/suspend.h>
#include <linux/export.h>
#include <linux/syscalls.h>
#include <linux/freezer.h>
#include <linux/oom.h>
#include <linux/kthread.h>

/* total number of freezing conditions in effect */
DEFINE_STATIC_KEY_FALSE(freezer_active);
EXPORT_SYMBOL(freezer_active);

/*
 * indicate whether PM freezing is in effect, protected by
 * system_transition_mutex
 */
bool pm_freezing;
bool pm_nosig_freezing;

/* protects freezing and frozen transitions */
static DEFINE_SPINLOCK(freezer_lock);

/**
 * freezing_slow_path - slow path for testing whether a task needs to be frozen
 * @p: task to be tested
 *
 * This function is called by freezing() if freezer_active isn't zero
 * and tests whether @p needs to enter and stay in frozen state.  Can be
 * called under any context.  The freezers are responsible for ensuring the
 * target tasks see the updated state.
 */
bool freezing_slow_path(struct task_struct *p)
{
	if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK))
		return false;

	if (tsk_is_oom_victim(p))
		return false;

	if (pm_nosig_freezing || cgroup_freezing(p))
		return true;

	if (pm_freezing && !(p->flags & PF_KTHREAD))
		return true;

	return false;
}
EXPORT_SYMBOL(freezing_slow_path);

bool frozen(struct task_struct *p)
{
	return READ_ONCE(p->__state) & TASK_FROZEN;
}

/* Refrigerator is place where frozen processes are stored :-). */
bool __refrigerator(bool check_kthr_stop)
{
	unsigned int state = get_current_state();
	bool was_frozen = false;

	pr_debug("%s entered refrigerator\n", current->comm);

	WARN_ON_ONCE(state && !(state & TASK_NORMAL));

	for (;;) {
		bool freeze;

		raw_spin_lock_irq(&current->pi_lock);
		WRITE_ONCE(current->__state, TASK_FROZEN);
		/* unstale saved_state so that __thaw_task() will wake us up */
		current->saved_state = TASK_RUNNING;
		raw_spin_unlock_irq(&current->pi_lock);

		spin_lock_irq(&freezer_lock);
		freeze = freezing(current) && !(check_kthr_stop && kthread_should_stop());
		spin_unlock_irq(&freezer_lock);

		if (!freeze)
			break;

		was_frozen = true;
		schedule();
	}
	__set_current_state(TASK_RUNNING);

	pr_debug("%s left refrigerator\n", current->comm);

	return was_frozen;
}
EXPORT_SYMBOL(__refrigerator);

static void fake_signal_wake_up(struct task_struct *p)
{
	unsigned long flags;

	if (lock_task_sighand(p, &flags)) {
		signal_wake_up(p, 0);
		unlock_task_sighand(p, &flags);
	}
}

static int __set_task_frozen(struct task_struct *p, void *arg)
{
	unsigned int state = READ_ONCE(p->__state);

	/*
	 * Allow freezing the sched_delayed tasks; they will not execute until
	 * ttwu() fixes them up, so it is safe to swap their state now, instead
	 * of waiting for them to get fully dequeued.
	 */
	if (task_is_runnable(p))
		return 0;

	if (p != current && task_curr(p))
		return 0;

	if (!(state & (TASK_FREEZABLE | __TASK_STOPPED | __TASK_TRACED)))
		return 0;

	/*
	 * Only TASK_NORMAL can be augmented with TASK_FREEZABLE, since they
	 * can suffer spurious wakeups.
	 */
	if (state & TASK_FREEZABLE)
		WARN_ON_ONCE(!(state & TASK_NORMAL));

#ifdef CONFIG_LOCKDEP
	/*
	 * It's dangerous to freeze with locks held; there be dragons there.
	 */
	if (!(state & __TASK_FREEZABLE_UNSAFE))
		WARN_ON_ONCE(debug_locks && p->lockdep_depth);
#endif

	p->saved_state = p->__state;
	WRITE_ONCE(p->__state, TASK_FROZEN);
	return TASK_FROZEN;
}

static bool __freeze_task(struct task_struct *p)
{
	/* TASK_FREEZABLE|TASK_STOPPED|TASK_TRACED -> TASK_FROZEN */
	return task_call_func(p, __set_task_frozen, NULL);
}

/**
 * freeze_task - send a freeze request to given task
 * @p: task to send the request to
 *
 * If @p is freezing, the freeze request is sent either by sending a fake
 * signal (if it's not a kernel thread) or waking it up (if it's a kernel
 * thread).
 *
 * RETURNS:
 * %false, if @p is not freezing or already frozen; %true, otherwise
 */
bool freeze_task(struct task_struct *p)
{
	unsigned long flags;

	spin_lock_irqsave(&freezer_lock, flags);
	if (!freezing(p) || frozen(p) || __freeze_task(p)) {
		spin_unlock_irqrestore(&freezer_lock, flags);
		return false;
	}

	if (!(p->flags & PF_KTHREAD))
		fake_signal_wake_up(p);
	else
		wake_up_state(p, TASK_NORMAL);

	spin_unlock_irqrestore(&freezer_lock, flags);
	return true;
}

/*
 * 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 __restore_freezer_state(struct task_struct *p, void *arg)
{
	unsigned int state = p->saved_state;

	if (state != TASK_RUNNING) {
		WRITE_ONCE(p->__state, state);
		p->saved_state = TASK_RUNNING;
		return 1;
	}

	return 0;
}

void __thaw_task(struct task_struct *p)
{
	guard(spinlock_irqsave)(&freezer_lock);
	if (frozen(p) && !task_call_func(p, __restore_freezer_state, NULL))
		wake_up_state(p, TASK_FROZEN);
}

/*
 * thaw_process - Thaw a frozen process
 * @p: the process to be thawed
 *
 * Iterate over all threads of @p and call __thaw_task() on each.
 */
void thaw_process(struct task_struct *p)
{
	struct task_struct *t;

	rcu_read_lock();
	for_each_thread(p, t) {
		__thaw_task(t);
	}
	rcu_read_unlock();
}

/**
 * set_freezable - make %current freezable
 *
 * Mark %current freezable and enter refrigerator if necessary.
 */
bool set_freezable(void)
{
	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;
	spin_unlock_irq(&freezer_lock);

	return try_to_freeze();
}
EXPORT_SYMBOL(set_freezable);
