// SPDX-License-Identifier: GPL-2.0
#include "debug.h"
#include "env.h"
#include "lock-contention.h"
#include "machine.h"
#include "symbol.h"

#include <limits.h>
#include <string.h>

#include <linux/hash.h>
#include <linux/zalloc.h>

#define __lockhashfn(key)	hash_long((unsigned long)key, LOCKHASH_BITS)
#define lockhashentry(key)	(lockhash_table + __lockhashfn((key)))

struct callstack_filter {
	struct list_head list;
	char name[];
};

static LIST_HEAD(callstack_filters);
struct hlist_head *lockhash_table;

int parse_call_stack(const struct option *opt __maybe_unused, const char *str,
		     int unset __maybe_unused)
{
	char *s, *tmp, *tok;
	int ret = 0;

	s = strdup(str);
	if (s == NULL)
		return -1;

	for (tok = strtok_r(s, ", ", &tmp); tok; tok = strtok_r(NULL, ", ", &tmp)) {
		struct callstack_filter *entry;

		entry = malloc(sizeof(*entry) + strlen(tok) + 1);
		if (entry == NULL) {
			pr_err("Memory allocation failure\n");
			free(s);
			return -1;
		}

		strcpy(entry->name, tok);
		list_add_tail(&entry->list, &callstack_filters);
	}

	free(s);
	return ret;
}

bool needs_callstack(void)
{
	return !list_empty(&callstack_filters);
}

struct lock_stat *lock_stat_find(u64 addr)
{
	struct hlist_head *entry = lockhashentry(addr);
	struct lock_stat *ret;

	hlist_for_each_entry(ret, entry, hash_entry) {
		if (ret->addr == addr)
			return ret;
	}
	return NULL;
}

struct lock_stat *lock_stat_findnew(u64 addr, const char *name, int flags)
{
	struct hlist_head *entry = lockhashentry(addr);
	struct lock_stat *ret, *new;

	hlist_for_each_entry(ret, entry, hash_entry) {
		if (ret->addr == addr)
			return ret;
	}

	new = zalloc(sizeof(struct lock_stat));
	if (!new)
		goto alloc_failed;

	new->addr = addr;
	new->name = strdup(name);
	if (!new->name) {
		free(new);
		goto alloc_failed;
	}

	new->flags = flags;
	new->wait_time_min = ULLONG_MAX;

	hlist_add_head(&new->hash_entry, entry);
	return new;

alloc_failed:
	pr_err("memory allocation failed\n");
	return NULL;
}

bool match_callstack_filter(struct machine *machine, u64 *callstack, int max_stack_depth)
{
	struct map *kmap;
	struct symbol *sym;
	u64 ip;
	uint16_t e_machine = perf_env__e_machine(machine->env, /*e_flags=*/NULL);
	bool is_powerpc = e_machine == EM_PPC64 || e_machine == EM_PPC;

	if (list_empty(&callstack_filters))
		return true;

	for (int i = 0; i < max_stack_depth; i++) {
		struct callstack_filter *filter;

		/*
		 * In powerpc, the callchain saved by kernel always includes
		 * first three entries as the NIP (next instruction pointer),
		 * LR (link register), and the contents of LR save area in the
		 * second stack frame. In certain scenarios its possible to have
		 * invalid kernel instruction addresses in either LR or the second
		 * stack frame's LR. In that case, kernel will store that address as
		 * zero.
		 *
		 * The below check will continue to look into callstack,
		 * incase first or second callstack index entry has 0
		 * address for powerpc.
		 */
		if (!callstack || (!callstack[i] && (!is_powerpc || (i != 1 && i != 2))))
			break;

		ip = callstack[i];
		sym = machine__find_kernel_symbol(machine, ip, &kmap);
		if (sym == NULL)
			continue;

		list_for_each_entry(filter, &callstack_filters, list) {
			if (strstr(sym->name, filter->name))
				return true;
		}
	}
	return false;
}
