// SPDX-License-Identifier: GPL-2.0-only
/*
 * on_cpus() support based on cpumasks.
 *
 * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com>
 */
#include <libcflat.h>
#include <cpumask.h>
#include <on-cpus.h>
#include <asm/barrier.h>
#include <asm/smp.h>

bool cpu0_calls_idle;

struct on_cpu_info {
	void (*func)(void *data);
	void *data;
	cpumask_t waiters;
};
static struct on_cpu_info on_cpu_info[NR_CPUS];
static cpumask_t on_cpu_info_lock;

static bool get_on_cpu_info(int cpu)
{
	return !cpumask_test_and_set_cpu(cpu, &on_cpu_info_lock);
}

static void put_on_cpu_info(int cpu)
{
	int ret = cpumask_test_and_clear_cpu(cpu, &on_cpu_info_lock);
	assert(ret);
}

static void __deadlock_check(int cpu, const cpumask_t *waiters, bool *found)
{
	int i;

	for_each_cpu(i, waiters) {
		if (i == cpu) {
			printf("CPU%d", cpu);
			*found = true;
			return;
		}
		__deadlock_check(cpu, &on_cpu_info[i].waiters, found);
		if (*found) {
			printf(" <=> CPU%d", i);
			return;
		}
	}
}

static void deadlock_check(int me, int cpu)
{
	bool found = false;

	__deadlock_check(cpu, &on_cpu_info[me].waiters, &found);
	if (found) {
		printf(" <=> CPU%d deadlock detectd\n", me);
		assert(0);
	}
}

static void cpu_wait(int cpu)
{
	int me = smp_processor_id();

	if (cpu == me)
		return;

	cpumask_set_cpu(me, &on_cpu_info[cpu].waiters);
	deadlock_check(me, cpu);
	while (!cpu_idle(cpu))
		smp_wait_for_event();
	cpumask_clear_cpu(me, &on_cpu_info[cpu].waiters);
}

void do_idle(void)
{
	int cpu = smp_processor_id();

	if (cpu == 0)
		cpu0_calls_idle = true;

	set_cpu_idle(cpu, true);
	smp_send_event();

	for (;;) {
		while (cpu_idle(cpu))
			smp_wait_for_event();
		smp_rmb();
		on_cpu_info[cpu].func(on_cpu_info[cpu].data);
		on_cpu_info[cpu].func = NULL;
		smp_wmb();
		set_cpu_idle(cpu, true);
		smp_send_event();
	}
}

void on_cpu_async(int cpu, void (*func)(void *data), void *data)
{
	if (cpu == smp_processor_id()) {
		func(data);
		return;
	}

	assert_msg(cpu != 0 || cpu0_calls_idle, "Waiting on CPU0, which is unlikely to idle. "
						"If this is intended set cpu0_calls_idle=1");

	smp_boot_secondary_nofail(cpu, do_idle);

	for (;;) {
		cpu_wait(cpu);
		if (get_on_cpu_info(cpu)) {
			if ((volatile void *)on_cpu_info[cpu].func == NULL)
				break;
			put_on_cpu_info(cpu);
		}
	}

	on_cpu_info[cpu].func = func;
	on_cpu_info[cpu].data = data;
	set_cpu_idle(cpu, false);
	put_on_cpu_info(cpu);
	smp_send_event();
}

void on_cpumask_async(const cpumask_t *mask, void (*func)(void *data), void *data)
{
	int cpu, me = smp_processor_id();

	for_each_cpu(cpu, mask) {
		if (cpu == me)
			continue;
		on_cpu_async(cpu, func, data);
	}
	if (cpumask_test_cpu(me, mask))
		func(data);
}

void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data)
{
	int cpu, me = smp_processor_id();

	for_each_cpu(cpu, mask) {
		if (cpu == me)
			continue;
		on_cpu_async(cpu, func, data);
	}
	if (cpumask_test_cpu(me, mask))
		func(data);

	for_each_cpu(cpu, mask) {
		if (cpu == me)
			continue;
		cpumask_set_cpu(me, &on_cpu_info[cpu].waiters);
		deadlock_check(me, cpu);
	}
	while (cpumask_weight(&cpu_idle_mask) < nr_cpus - 1)
		smp_wait_for_event();
	for_each_cpu(cpu, mask)
		cpumask_clear_cpu(me, &on_cpu_info[cpu].waiters);
}

void on_cpu(int cpu, void (*func)(void *data), void *data)
{
	on_cpu_async(cpu, func, data);
	cpu_wait(cpu);
}

void on_cpus(void (*func)(void *data), void *data)
{
	on_cpumask(&cpu_present_mask, func, data);
}
