// SPDX-License-Identifier: GPL-2.0

#include <linux/seq_file.h>
#include <linux/kallsyms.h>
#include <linux/module.h>
#include <linux/ftrace.h>
#include <linux/fs.h>

#include "trace_output.h"

struct recursed_functions {
	unsigned long		ip;
	unsigned long		parent_ip;
};

static struct recursed_functions recursed_functions[CONFIG_FTRACE_RECORD_RECURSION_SIZE];
static atomic_t nr_records;

/*
 * Cache the last found function. Yes, updates to this is racey, but
 * so is memory cache ;-)
 */
static unsigned long cached_function;

void ftrace_record_recursion(unsigned long ip, unsigned long parent_ip)
{
	int index = 0;
	int i;
	unsigned long old;

 again:
	/* First check the last one recorded */
	if (ip == cached_function)
		return;

	i = atomic_read(&nr_records);
	/* nr_records is -1 when clearing records */
	smp_mb__after_atomic();
	if (i < 0)
		return;

	/*
	 * If there's two writers and this writer comes in second,
	 * the cmpxchg() below to update the ip will fail. Then this
	 * writer will try again. It is possible that index will now
	 * be greater than nr_records. This is because the writer
	 * that succeeded has not updated the nr_records yet.
	 * This writer could keep trying again until the other writer
	 * updates nr_records. But if the other writer takes an
	 * interrupt, and that interrupt locks up that CPU, we do
	 * not want this CPU to lock up due to the recursion protection,
	 * and have a bug report showing this CPU as the cause of
	 * locking up the computer. To not lose this record, this
	 * writer will simply use the next position to update the
	 * recursed_functions, and it will update the nr_records
	 * accordingly.
	 */
	if (index < i)
		index = i;
	if (index >= CONFIG_FTRACE_RECORD_RECURSION_SIZE)
		return;

	for (i = index - 1; i >= 0; i--) {
		if (recursed_functions[i].ip == ip) {
			cached_function = ip;
			return;
		}
	}

	cached_function = ip;

	/*
	 * We only want to add a function if it hasn't been added before.
	 * Add to the current location before incrementing the count.
	 * If it fails to add, then increment the index (save in i)
	 * and try again.
	 */
	old = cmpxchg(&recursed_functions[index].ip, 0, ip);
	if (old != 0) {
		/* Did something else already added this for us? */
		if (old == ip)
			return;
		/* Try the next location (use i for the next index) */
		index++;
		goto again;
	}

	recursed_functions[index].parent_ip = parent_ip;

	/*
	 * It's still possible that we could race with the clearing
	 *    CPU0                                    CPU1
	 *    ----                                    ----
	 *                                       ip = func
	 *  nr_records = -1;
	 *  recursed_functions[0] = 0;
	 *                                       i = -1
	 *                                       if (i < 0)
	 *  nr_records = 0;
	 *  (new recursion detected)
	 *      recursed_functions[0] = func
	 *                                            cmpxchg(recursed_functions[0],
	 *                                                    func, 0)
	 *
	 * But the worse that could happen is that we get a zero in
	 * the recursed_functions array, and it's likely that "func" will
	 * be recorded again.
	 */
	i = atomic_read(&nr_records);
	smp_mb__after_atomic();
	if (i < 0)
		cmpxchg(&recursed_functions[index].ip, ip, 0);
	else if (i <= index)
		atomic_cmpxchg(&nr_records, i, index + 1);
}
EXPORT_SYMBOL_GPL(ftrace_record_recursion);

static DEFINE_MUTEX(recursed_function_lock);
static struct trace_seq *tseq;

static void *recursed_function_seq_start(struct seq_file *m, loff_t *pos)
{
	void *ret = NULL;
	int index;

	mutex_lock(&recursed_function_lock);
	index = atomic_read(&nr_records);
	if (*pos < index) {
		ret = &recursed_functions[*pos];
	}

	tseq = kzalloc_obj(*tseq);
	if (!tseq)
		return ERR_PTR(-ENOMEM);

	trace_seq_init(tseq);

	return ret;
}

static void *recursed_function_seq_next(struct seq_file *m, void *v, loff_t *pos)
{
	int index;
	int p;

	index = atomic_read(&nr_records);
	p = ++(*pos);

	return p < index ? &recursed_functions[p] : NULL;
}

static void recursed_function_seq_stop(struct seq_file *m, void *v)
{
	kfree(tseq);
	mutex_unlock(&recursed_function_lock);
}

static int recursed_function_seq_show(struct seq_file *m, void *v)
{
	struct recursed_functions *record = v;
	int ret = 0;

	if (record) {
		trace_seq_print_sym(tseq, record->parent_ip, true);
		trace_seq_puts(tseq, ":\t");
		trace_seq_print_sym(tseq, record->ip, true);
		trace_seq_putc(tseq, '\n');
		ret = trace_print_seq(m, tseq);
	}

	return ret;
}

static const struct seq_operations recursed_function_seq_ops = {
	.start  = recursed_function_seq_start,
	.next   = recursed_function_seq_next,
	.stop   = recursed_function_seq_stop,
	.show   = recursed_function_seq_show
};

static int recursed_function_open(struct inode *inode, struct file *file)
{
	guard(mutex)(&recursed_function_lock);

	/* If this file was opened for write, then erase contents */
	if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
		/* disable updating records */
		atomic_set(&nr_records, -1);
		smp_mb__after_atomic();
		memset(recursed_functions, 0, sizeof(recursed_functions));
		smp_wmb();
		/* enable them again */
		atomic_set(&nr_records, 0);
	}
	if (file->f_mode & FMODE_READ)
		return seq_open(file, &recursed_function_seq_ops);

	return 0;
}

static ssize_t recursed_function_write(struct file *file,
				       const char __user *buffer,
				       size_t count, loff_t *ppos)
{
	return count;
}

static int recursed_function_release(struct inode *inode, struct file *file)
{
	if (file->f_mode & FMODE_READ)
		seq_release(inode, file);
	return 0;
}

static const struct file_operations recursed_functions_fops = {
	.open           = recursed_function_open,
	.write		= recursed_function_write,
	.read           = seq_read,
	.llseek         = seq_lseek,
	.release        = recursed_function_release,
};

__init static int create_recursed_functions(void)
{

	trace_create_file("recursed_functions", TRACE_MODE_WRITE,
			  NULL, NULL, &recursed_functions_fops);
	return 0;
}

fs_initcall(create_recursed_functions);
