// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <inttypes.h>
#include "builtin.h"
#include "perf.h"

#include "util/evlist.h" // for struct evsel_str_handler
#include "util/evsel.h"
#include "util/symbol.h"
#include "util/thread.h"
#include "util/header.h"
#include "util/target.h"
#include "util/callchain.h"
#include "util/lock-contention.h"
#include "util/bpf_skel/lock_data.h"

#include <subcmd/pager.h>
#include <subcmd/parse-options.h>
#include "util/trace-event.h"
#include "util/tracepoint.h"

#include "util/debug.h"
#include "util/session.h"
#include "util/tool.h"
#include "util/data.h"
#include "util/string2.h"
#include "util/map.h"
#include "util/util.h"

#include <sys/types.h>
#include <sys/prctl.h>
#include <semaphore.h>
#include <math.h>
#include <limits.h>
#include <ctype.h>

#include <linux/list.h>
#include <linux/hash.h>
#include <linux/kernel.h>
#include <linux/zalloc.h>
#include <linux/err.h>
#include <linux/stringify.h>

static struct perf_session *session;
static struct target target;

/* based on kernel/lockdep.c */
#define LOCKHASH_BITS		12
#define LOCKHASH_SIZE		(1UL << LOCKHASH_BITS)

static struct hlist_head lockhash_table[LOCKHASH_SIZE];

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

static struct rb_root		thread_stats;

static bool combine_locks;
static bool show_thread_stats;
static bool show_lock_addrs;
static bool show_lock_owner;
static bool use_bpf;
static unsigned long bpf_map_entries = 10240;
static int max_stack_depth = CONTENTION_STACK_DEPTH;
static int stack_skip = CONTENTION_STACK_SKIP;
static int print_nr_entries = INT_MAX / 2;
static LIST_HEAD(callstack_filters);

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

static struct lock_filter filters;

static enum lock_aggr_mode aggr_mode = LOCK_AGGR_ADDR;

static bool needs_callstack(void)
{
	return verbose > 0 || !list_empty(&callstack_filters);
}

static struct thread_stat *thread_stat_find(u32 tid)
{
	struct rb_node *node;
	struct thread_stat *st;

	node = thread_stats.rb_node;
	while (node) {
		st = container_of(node, struct thread_stat, rb);
		if (st->tid == tid)
			return st;
		else if (tid < st->tid)
			node = node->rb_left;
		else
			node = node->rb_right;
	}

	return NULL;
}

static void thread_stat_insert(struct thread_stat *new)
{
	struct rb_node **rb = &thread_stats.rb_node;
	struct rb_node *parent = NULL;
	struct thread_stat *p;

	while (*rb) {
		p = container_of(*rb, struct thread_stat, rb);
		parent = *rb;

		if (new->tid < p->tid)
			rb = &(*rb)->rb_left;
		else if (new->tid > p->tid)
			rb = &(*rb)->rb_right;
		else
			BUG_ON("inserting invalid thread_stat\n");
	}

	rb_link_node(&new->rb, parent, rb);
	rb_insert_color(&new->rb, &thread_stats);
}

static struct thread_stat *thread_stat_findnew_after_first(u32 tid)
{
	struct thread_stat *st;

	st = thread_stat_find(tid);
	if (st)
		return st;

	st = zalloc(sizeof(struct thread_stat));
	if (!st) {
		pr_err("memory allocation failed\n");
		return NULL;
	}

	st->tid = tid;
	INIT_LIST_HEAD(&st->seq_list);

	thread_stat_insert(st);

	return st;
}

static struct thread_stat *thread_stat_findnew_first(u32 tid);
static struct thread_stat *(*thread_stat_findnew)(u32 tid) =
	thread_stat_findnew_first;

static struct thread_stat *thread_stat_findnew_first(u32 tid)
{
	struct thread_stat *st;

	st = zalloc(sizeof(struct thread_stat));
	if (!st) {
		pr_err("memory allocation failed\n");
		return NULL;
	}
	st->tid = tid;
	INIT_LIST_HEAD(&st->seq_list);

	rb_link_node(&st->rb, NULL, &thread_stats.rb_node);
	rb_insert_color(&st->rb, &thread_stats);

	thread_stat_findnew = thread_stat_findnew_after_first;
	return st;
}

/* build simple key function one is bigger than two */
#define SINGLE_KEY(member)						\
	static int lock_stat_key_ ## member(struct lock_stat *one,	\
					 struct lock_stat *two)		\
	{								\
		return one->member > two->member;			\
	}

SINGLE_KEY(nr_acquired)
SINGLE_KEY(nr_contended)
SINGLE_KEY(avg_wait_time)
SINGLE_KEY(wait_time_total)
SINGLE_KEY(wait_time_max)

static int lock_stat_key_wait_time_min(struct lock_stat *one,
					struct lock_stat *two)
{
	u64 s1 = one->wait_time_min;
	u64 s2 = two->wait_time_min;
	if (s1 == ULLONG_MAX)
		s1 = 0;
	if (s2 == ULLONG_MAX)
		s2 = 0;
	return s1 > s2;
}

struct lock_key {
	/*
	 * name: the value for specify by user
	 * this should be simpler than raw name of member
	 * e.g. nr_acquired -> acquired, wait_time_total -> wait_total
	 */
	const char		*name;
	/* header: the string printed on the header line */
	const char		*header;
	/* len: the printing width of the field */
	int			len;
	/* key: a pointer to function to compare two lock stats for sorting */
	int			(*key)(struct lock_stat*, struct lock_stat*);
	/* print: a pointer to function to print a given lock stats */
	void			(*print)(struct lock_key*, struct lock_stat*);
	/* list: list entry to link this */
	struct list_head	list;
};

static void lock_stat_key_print_time(unsigned long long nsec, int len)
{
	static const struct {
		float base;
		const char *unit;
	} table[] = {
		{ 1e9 * 3600, "h " },
		{ 1e9 * 60, "m " },
		{ 1e9, "s " },
		{ 1e6, "ms" },
		{ 1e3, "us" },
		{ 0, NULL },
	};

	for (int i = 0; table[i].unit; i++) {
		if (nsec < table[i].base)
			continue;

		pr_info("%*.2f %s", len - 3, nsec / table[i].base, table[i].unit);
		return;
	}

	pr_info("%*llu %s", len - 3, nsec, "ns");
}

#define PRINT_KEY(member)						\
static void lock_stat_key_print_ ## member(struct lock_key *key,	\
					   struct lock_stat *ls)	\
{									\
	pr_info("%*llu", key->len, (unsigned long long)ls->member);	\
}

#define PRINT_TIME(member)						\
static void lock_stat_key_print_ ## member(struct lock_key *key,	\
					   struct lock_stat *ls)	\
{									\
	lock_stat_key_print_time((unsigned long long)ls->member, key->len);	\
}

PRINT_KEY(nr_acquired)
PRINT_KEY(nr_contended)
PRINT_TIME(avg_wait_time)
PRINT_TIME(wait_time_total)
PRINT_TIME(wait_time_max)

static void lock_stat_key_print_wait_time_min(struct lock_key *key,
					      struct lock_stat *ls)
{
	u64 wait_time = ls->wait_time_min;

	if (wait_time == ULLONG_MAX)
		wait_time = 0;

	lock_stat_key_print_time(wait_time, key->len);
}


static const char		*sort_key = "acquired";

static int			(*compare)(struct lock_stat *, struct lock_stat *);

static struct rb_root		sorted; /* place to store intermediate data */
static struct rb_root		result;	/* place to store sorted data */

static LIST_HEAD(lock_keys);
static const char		*output_fields;

#define DEF_KEY_LOCK(name, header, fn_suffix, len)			\
	{ #name, header, len, lock_stat_key_ ## fn_suffix, lock_stat_key_print_ ## fn_suffix, {} }
static struct lock_key report_keys[] = {
	DEF_KEY_LOCK(acquired, "acquired", nr_acquired, 10),
	DEF_KEY_LOCK(contended, "contended", nr_contended, 10),
	DEF_KEY_LOCK(avg_wait, "avg wait", avg_wait_time, 12),
	DEF_KEY_LOCK(wait_total, "total wait", wait_time_total, 12),
	DEF_KEY_LOCK(wait_max, "max wait", wait_time_max, 12),
	DEF_KEY_LOCK(wait_min, "min wait", wait_time_min, 12),

	/* extra comparisons much complicated should be here */
	{ }
};

static struct lock_key contention_keys[] = {
	DEF_KEY_LOCK(contended, "contended", nr_contended, 10),
	DEF_KEY_LOCK(wait_total, "total wait", wait_time_total, 12),
	DEF_KEY_LOCK(wait_max, "max wait", wait_time_max, 12),
	DEF_KEY_LOCK(wait_min, "min wait", wait_time_min, 12),
	DEF_KEY_LOCK(avg_wait, "avg wait", avg_wait_time, 12),

	/* extra comparisons much complicated should be here */
	{ }
};

static int select_key(bool contention)
{
	int i;
	struct lock_key *keys = report_keys;

	if (contention)
		keys = contention_keys;

	for (i = 0; keys[i].name; i++) {
		if (!strcmp(keys[i].name, sort_key)) {
			compare = keys[i].key;

			/* selected key should be in the output fields */
			if (list_empty(&keys[i].list))
				list_add_tail(&keys[i].list, &lock_keys);

			return 0;
		}
	}

	pr_err("Unknown compare key: %s\n", sort_key);
	return -1;
}

static int add_output_field(bool contention, char *name)
{
	int i;
	struct lock_key *keys = report_keys;

	if (contention)
		keys = contention_keys;

	for (i = 0; keys[i].name; i++) {
		if (strcmp(keys[i].name, name))
			continue;

		/* prevent double link */
		if (list_empty(&keys[i].list))
			list_add_tail(&keys[i].list, &lock_keys);

		return 0;
	}

	pr_err("Unknown output field: %s\n", name);
	return -1;
}

static int setup_output_field(bool contention, const char *str)
{
	char *tok, *tmp, *orig;
	int i, ret = 0;
	struct lock_key *keys = report_keys;

	if (contention)
		keys = contention_keys;

	/* no output field given: use all of them */
	if (str == NULL) {
		for (i = 0; keys[i].name; i++)
			list_add_tail(&keys[i].list, &lock_keys);
		return 0;
	}

	for (i = 0; keys[i].name; i++)
		INIT_LIST_HEAD(&keys[i].list);

	orig = tmp = strdup(str);
	if (orig == NULL)
		return -ENOMEM;

	while ((tok = strsep(&tmp, ",")) != NULL){
		ret = add_output_field(contention, tok);
		if (ret < 0)
			break;
	}
	free(orig);

	return ret;
}

static void combine_lock_stats(struct lock_stat *st)
{
	struct rb_node **rb = &sorted.rb_node;
	struct rb_node *parent = NULL;
	struct lock_stat *p;
	int ret;

	while (*rb) {
		p = container_of(*rb, struct lock_stat, rb);
		parent = *rb;

		if (st->name && p->name)
			ret = strcmp(st->name, p->name);
		else
			ret = !!st->name - !!p->name;

		if (ret == 0) {
			p->nr_acquired += st->nr_acquired;
			p->nr_contended += st->nr_contended;
			p->wait_time_total += st->wait_time_total;

			if (p->nr_contended)
				p->avg_wait_time = p->wait_time_total / p->nr_contended;

			if (p->wait_time_min > st->wait_time_min)
				p->wait_time_min = st->wait_time_min;
			if (p->wait_time_max < st->wait_time_max)
				p->wait_time_max = st->wait_time_max;

			p->broken |= st->broken;
			st->combined = 1;
			return;
		}

		if (ret < 0)
			rb = &(*rb)->rb_left;
		else
			rb = &(*rb)->rb_right;
	}

	rb_link_node(&st->rb, parent, rb);
	rb_insert_color(&st->rb, &sorted);
}

static void insert_to_result(struct lock_stat *st,
			     int (*bigger)(struct lock_stat *, struct lock_stat *))
{
	struct rb_node **rb = &result.rb_node;
	struct rb_node *parent = NULL;
	struct lock_stat *p;

	if (combine_locks && st->combined)
		return;

	while (*rb) {
		p = container_of(*rb, struct lock_stat, rb);
		parent = *rb;

		if (bigger(st, p))
			rb = &(*rb)->rb_left;
		else
			rb = &(*rb)->rb_right;
	}

	rb_link_node(&st->rb, parent, rb);
	rb_insert_color(&st->rb, &result);
}

/* returns left most element of result, and erase it */
static struct lock_stat *pop_from_result(void)
{
	struct rb_node *node = result.rb_node;

	if (!node)
		return NULL;

	while (node->rb_left)
		node = node->rb_left;

	rb_erase(node, &result);
	return container_of(node, struct lock_stat, rb);
}

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)
{
	struct map *kmap;
	struct symbol *sym;
	u64 ip;

	if (list_empty(&callstack_filters))
		return true;

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

		if (!callstack || !callstack[i])
			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;
}

struct trace_lock_handler {
	/* it's used on CONFIG_LOCKDEP */
	int (*acquire_event)(struct evsel *evsel,
			     struct perf_sample *sample);

	/* it's used on CONFIG_LOCKDEP && CONFIG_LOCK_STAT */
	int (*acquired_event)(struct evsel *evsel,
			      struct perf_sample *sample);

	/* it's used on CONFIG_LOCKDEP && CONFIG_LOCK_STAT */
	int (*contended_event)(struct evsel *evsel,
			       struct perf_sample *sample);

	/* it's used on CONFIG_LOCKDEP */
	int (*release_event)(struct evsel *evsel,
			     struct perf_sample *sample);

	/* it's used when CONFIG_LOCKDEP is off */
	int (*contention_begin_event)(struct evsel *evsel,
				      struct perf_sample *sample);

	/* it's used when CONFIG_LOCKDEP is off */
	int (*contention_end_event)(struct evsel *evsel,
				    struct perf_sample *sample);
};

static struct lock_seq_stat *get_seq(struct thread_stat *ts, u64 addr)
{
	struct lock_seq_stat *seq;

	list_for_each_entry(seq, &ts->seq_list, list) {
		if (seq->addr == addr)
			return seq;
	}

	seq = zalloc(sizeof(struct lock_seq_stat));
	if (!seq) {
		pr_err("memory allocation failed\n");
		return NULL;
	}
	seq->state = SEQ_STATE_UNINITIALIZED;
	seq->addr = addr;

	list_add(&seq->list, &ts->seq_list);
	return seq;
}

enum broken_state {
	BROKEN_ACQUIRE,
	BROKEN_ACQUIRED,
	BROKEN_CONTENDED,
	BROKEN_RELEASE,
	BROKEN_MAX,
};

static int bad_hist[BROKEN_MAX];

enum acquire_flags {
	TRY_LOCK = 1,
	READ_LOCK = 2,
};

static int get_key_by_aggr_mode_simple(u64 *key, u64 addr, u32 tid)
{
	switch (aggr_mode) {
	case LOCK_AGGR_ADDR:
		*key = addr;
		break;
	case LOCK_AGGR_TASK:
		*key = tid;
		break;
	case LOCK_AGGR_CALLER:
	default:
		pr_err("Invalid aggregation mode: %d\n", aggr_mode);
		return -EINVAL;
	}
	return 0;
}

static u64 callchain_id(struct evsel *evsel, struct perf_sample *sample);

static int get_key_by_aggr_mode(u64 *key, u64 addr, struct evsel *evsel,
				 struct perf_sample *sample)
{
	if (aggr_mode == LOCK_AGGR_CALLER) {
		*key = callchain_id(evsel, sample);
		return 0;
	}
	return get_key_by_aggr_mode_simple(key, addr, sample->tid);
}

static int report_lock_acquire_event(struct evsel *evsel,
				     struct perf_sample *sample)
{
	struct lock_stat *ls;
	struct thread_stat *ts;
	struct lock_seq_stat *seq;
	const char *name = evsel__strval(evsel, sample, "name");
	u64 addr = evsel__intval(evsel, sample, "lockdep_addr");
	int flag = evsel__intval(evsel, sample, "flags");
	u64 key;
	int ret;

	ret = get_key_by_aggr_mode_simple(&key, addr, sample->tid);
	if (ret < 0)
		return ret;

	ls = lock_stat_findnew(key, name, 0);
	if (!ls)
		return -ENOMEM;

	ts = thread_stat_findnew(sample->tid);
	if (!ts)
		return -ENOMEM;

	seq = get_seq(ts, addr);
	if (!seq)
		return -ENOMEM;

	switch (seq->state) {
	case SEQ_STATE_UNINITIALIZED:
	case SEQ_STATE_RELEASED:
		if (!flag) {
			seq->state = SEQ_STATE_ACQUIRING;
		} else {
			if (flag & TRY_LOCK)
				ls->nr_trylock++;
			if (flag & READ_LOCK)
				ls->nr_readlock++;
			seq->state = SEQ_STATE_READ_ACQUIRED;
			seq->read_count = 1;
			ls->nr_acquired++;
		}
		break;
	case SEQ_STATE_READ_ACQUIRED:
		if (flag & READ_LOCK) {
			seq->read_count++;
			ls->nr_acquired++;
			goto end;
		} else {
			goto broken;
		}
		break;
	case SEQ_STATE_ACQUIRED:
	case SEQ_STATE_ACQUIRING:
	case SEQ_STATE_CONTENDED:
broken:
		/* broken lock sequence */
		if (!ls->broken) {
			ls->broken = 1;
			bad_hist[BROKEN_ACQUIRE]++;
		}
		list_del_init(&seq->list);
		free(seq);
		goto end;
	default:
		BUG_ON("Unknown state of lock sequence found!\n");
		break;
	}

	ls->nr_acquire++;
	seq->prev_event_time = sample->time;
end:
	return 0;
}

static int report_lock_acquired_event(struct evsel *evsel,
				      struct perf_sample *sample)
{
	struct lock_stat *ls;
	struct thread_stat *ts;
	struct lock_seq_stat *seq;
	u64 contended_term;
	const char *name = evsel__strval(evsel, sample, "name");
	u64 addr = evsel__intval(evsel, sample, "lockdep_addr");
	u64 key;
	int ret;

	ret = get_key_by_aggr_mode_simple(&key, addr, sample->tid);
	if (ret < 0)
		return ret;

	ls = lock_stat_findnew(key, name, 0);
	if (!ls)
		return -ENOMEM;

	ts = thread_stat_findnew(sample->tid);
	if (!ts)
		return -ENOMEM;

	seq = get_seq(ts, addr);
	if (!seq)
		return -ENOMEM;

	switch (seq->state) {
	case SEQ_STATE_UNINITIALIZED:
		/* orphan event, do nothing */
		return 0;
	case SEQ_STATE_ACQUIRING:
		break;
	case SEQ_STATE_CONTENDED:
		contended_term = sample->time - seq->prev_event_time;
		ls->wait_time_total += contended_term;
		if (contended_term < ls->wait_time_min)
			ls->wait_time_min = contended_term;
		if (ls->wait_time_max < contended_term)
			ls->wait_time_max = contended_term;
		break;
	case SEQ_STATE_RELEASED:
	case SEQ_STATE_ACQUIRED:
	case SEQ_STATE_READ_ACQUIRED:
		/* broken lock sequence */
		if (!ls->broken) {
			ls->broken = 1;
			bad_hist[BROKEN_ACQUIRED]++;
		}
		list_del_init(&seq->list);
		free(seq);
		goto end;
	default:
		BUG_ON("Unknown state of lock sequence found!\n");
		break;
	}

	seq->state = SEQ_STATE_ACQUIRED;
	ls->nr_acquired++;
	ls->avg_wait_time = ls->nr_contended ? ls->wait_time_total/ls->nr_contended : 0;
	seq->prev_event_time = sample->time;
end:
	return 0;
}

static int report_lock_contended_event(struct evsel *evsel,
				       struct perf_sample *sample)
{
	struct lock_stat *ls;
	struct thread_stat *ts;
	struct lock_seq_stat *seq;
	const char *name = evsel__strval(evsel, sample, "name");
	u64 addr = evsel__intval(evsel, sample, "lockdep_addr");
	u64 key;
	int ret;

	ret = get_key_by_aggr_mode_simple(&key, addr, sample->tid);
	if (ret < 0)
		return ret;

	ls = lock_stat_findnew(key, name, 0);
	if (!ls)
		return -ENOMEM;

	ts = thread_stat_findnew(sample->tid);
	if (!ts)
		return -ENOMEM;

	seq = get_seq(ts, addr);
	if (!seq)
		return -ENOMEM;

	switch (seq->state) {
	case SEQ_STATE_UNINITIALIZED:
		/* orphan event, do nothing */
		return 0;
	case SEQ_STATE_ACQUIRING:
		break;
	case SEQ_STATE_RELEASED:
	case SEQ_STATE_ACQUIRED:
	case SEQ_STATE_READ_ACQUIRED:
	case SEQ_STATE_CONTENDED:
		/* broken lock sequence */
		if (!ls->broken) {
			ls->broken = 1;
			bad_hist[BROKEN_CONTENDED]++;
		}
		list_del_init(&seq->list);
		free(seq);
		goto end;
	default:
		BUG_ON("Unknown state of lock sequence found!\n");
		break;
	}

	seq->state = SEQ_STATE_CONTENDED;
	ls->nr_contended++;
	ls->avg_wait_time = ls->wait_time_total/ls->nr_contended;
	seq->prev_event_time = sample->time;
end:
	return 0;
}

static int report_lock_release_event(struct evsel *evsel,
				     struct perf_sample *sample)
{
	struct lock_stat *ls;
	struct thread_stat *ts;
	struct lock_seq_stat *seq;
	const char *name = evsel__strval(evsel, sample, "name");
	u64 addr = evsel__intval(evsel, sample, "lockdep_addr");
	u64 key;
	int ret;

	ret = get_key_by_aggr_mode_simple(&key, addr, sample->tid);
	if (ret < 0)
		return ret;

	ls = lock_stat_findnew(key, name, 0);
	if (!ls)
		return -ENOMEM;

	ts = thread_stat_findnew(sample->tid);
	if (!ts)
		return -ENOMEM;

	seq = get_seq(ts, addr);
	if (!seq)
		return -ENOMEM;

	switch (seq->state) {
	case SEQ_STATE_UNINITIALIZED:
		goto end;
	case SEQ_STATE_ACQUIRED:
		break;
	case SEQ_STATE_READ_ACQUIRED:
		seq->read_count--;
		BUG_ON(seq->read_count < 0);
		if (seq->read_count) {
			ls->nr_release++;
			goto end;
		}
		break;
	case SEQ_STATE_ACQUIRING:
	case SEQ_STATE_CONTENDED:
	case SEQ_STATE_RELEASED:
		/* broken lock sequence */
		if (!ls->broken) {
			ls->broken = 1;
			bad_hist[BROKEN_RELEASE]++;
		}
		goto free_seq;
	default:
		BUG_ON("Unknown state of lock sequence found!\n");
		break;
	}

	ls->nr_release++;
free_seq:
	list_del_init(&seq->list);
	free(seq);
end:
	return 0;
}

static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip,
				  char *buf, int size)
{
	u64 offset;

	if (map == NULL || sym == NULL) {
		buf[0] = '\0';
		return 0;
	}

	offset = map->map_ip(map, ip) - sym->start;

	if (offset)
		return scnprintf(buf, size, "%s+%#lx", sym->name, offset);
	else
		return strlcpy(buf, sym->name, size);
}
static int lock_contention_caller(struct evsel *evsel, struct perf_sample *sample,
				  char *buf, int size)
{
	struct thread *thread;
	struct callchain_cursor *cursor = &callchain_cursor;
	struct machine *machine = &session->machines.host;
	struct symbol *sym;
	int skip = 0;
	int ret;

	/* lock names will be replaced to task name later */
	if (show_thread_stats)
		return -1;

	thread = machine__findnew_thread(machine, -1, sample->pid);
	if (thread == NULL)
		return -1;

	/* use caller function name from the callchain */
	ret = thread__resolve_callchain(thread, cursor, evsel, sample,
					NULL, NULL, max_stack_depth);
	if (ret != 0) {
		thread__put(thread);
		return -1;
	}

	callchain_cursor_commit(cursor);
	thread__put(thread);

	while (true) {
		struct callchain_cursor_node *node;

		node = callchain_cursor_current(cursor);
		if (node == NULL)
			break;

		/* skip first few entries - for lock functions */
		if (++skip <= stack_skip)
			goto next;

		sym = node->ms.sym;
		if (sym && !machine__is_lock_function(machine, node->ip)) {
			get_symbol_name_offset(node->ms.map, sym, node->ip,
					       buf, size);
			return 0;
		}

next:
		callchain_cursor_advance(cursor);
	}
	return -1;
}

static u64 callchain_id(struct evsel *evsel, struct perf_sample *sample)
{
	struct callchain_cursor *cursor = &callchain_cursor;
	struct machine *machine = &session->machines.host;
	struct thread *thread;
	u64 hash = 0;
	int skip = 0;
	int ret;

	thread = machine__findnew_thread(machine, -1, sample->pid);
	if (thread == NULL)
		return -1;

	/* use caller function name from the callchain */
	ret = thread__resolve_callchain(thread, cursor, evsel, sample,
					NULL, NULL, max_stack_depth);
	thread__put(thread);

	if (ret != 0)
		return -1;

	callchain_cursor_commit(cursor);

	while (true) {
		struct callchain_cursor_node *node;

		node = callchain_cursor_current(cursor);
		if (node == NULL)
			break;

		/* skip first few entries - for lock functions */
		if (++skip <= stack_skip)
			goto next;

		if (node->ms.sym && machine__is_lock_function(machine, node->ip))
			goto next;

		hash ^= hash_long((unsigned long)node->ip, 64);

next:
		callchain_cursor_advance(cursor);
	}
	return hash;
}

static u64 *get_callstack(struct perf_sample *sample, int max_stack)
{
	u64 *callstack;
	u64 i;
	int c;

	callstack = calloc(max_stack, sizeof(*callstack));
	if (callstack == NULL)
		return NULL;

	for (i = 0, c = 0; i < sample->callchain->nr && c < max_stack; i++) {
		u64 ip = sample->callchain->ips[i];

		if (ip >= PERF_CONTEXT_MAX)
			continue;

		callstack[c++] = ip;
	}
	return callstack;
}

static int report_lock_contention_begin_event(struct evsel *evsel,
					      struct perf_sample *sample)
{
	struct lock_stat *ls;
	struct thread_stat *ts;
	struct lock_seq_stat *seq;
	u64 addr = evsel__intval(evsel, sample, "lock_addr");
	unsigned int flags = evsel__intval(evsel, sample, "flags");
	u64 key;
	int i, ret;
	static bool kmap_loaded;
	struct machine *machine = &session->machines.host;
	struct map *kmap;
	struct symbol *sym;

	ret = get_key_by_aggr_mode(&key, addr, evsel, sample);
	if (ret < 0)
		return ret;

	if (!kmap_loaded) {
		unsigned long *addrs;

		/* make sure it loads the kernel map to find lock symbols */
		map__load(machine__kernel_map(machine));
		kmap_loaded = true;

		/* convert (kernel) symbols to addresses */
		for (i = 0; i < filters.nr_syms; i++) {
			sym = machine__find_kernel_symbol_by_name(machine,
								  filters.syms[i],
								  &kmap);
			if (sym == NULL) {
				pr_warning("ignore unknown symbol: %s\n",
					   filters.syms[i]);
				continue;
			}

			addrs = realloc(filters.addrs,
					(filters.nr_addrs + 1) * sizeof(*addrs));
			if (addrs == NULL) {
				pr_warning("memory allocation failure\n");
				return -ENOMEM;
			}

			addrs[filters.nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
			filters.addrs = addrs;
		}
	}

	ls = lock_stat_find(key);
	if (!ls) {
		char buf[128];
		const char *name = "";

		switch (aggr_mode) {
		case LOCK_AGGR_ADDR:
			sym = machine__find_kernel_symbol(machine, key, &kmap);
			if (sym)
				name = sym->name;
			break;
		case LOCK_AGGR_CALLER:
			name = buf;
			if (lock_contention_caller(evsel, sample, buf, sizeof(buf)) < 0)
				name = "Unknown";
			break;
		case LOCK_AGGR_TASK:
		default:
			break;
		}

		ls = lock_stat_findnew(key, name, flags);
		if (!ls)
			return -ENOMEM;
	}

	if (filters.nr_types) {
		bool found = false;

		for (i = 0; i < filters.nr_types; i++) {
			if (flags == filters.types[i]) {
				found = true;
				break;
			}
		}

		if (!found)
			return 0;
	}

	if (filters.nr_addrs) {
		bool found = false;

		for (i = 0; i < filters.nr_addrs; i++) {
			if (addr == filters.addrs[i]) {
				found = true;
				break;
			}
		}

		if (!found)
			return 0;
	}

	if (needs_callstack()) {
		u64 *callstack = get_callstack(sample, max_stack_depth);
		if (callstack == NULL)
			return -ENOMEM;

		if (!match_callstack_filter(machine, callstack)) {
			free(callstack);
			return 0;
		}

		if (ls->callstack == NULL)
			ls->callstack = callstack;
		else
			free(callstack);
	}

	ts = thread_stat_findnew(sample->tid);
	if (!ts)
		return -ENOMEM;

	seq = get_seq(ts, addr);
	if (!seq)
		return -ENOMEM;

	switch (seq->state) {
	case SEQ_STATE_UNINITIALIZED:
	case SEQ_STATE_ACQUIRED:
		break;
	case SEQ_STATE_CONTENDED:
		/*
		 * It can have nested contention begin with mutex spinning,
		 * then we would use the original contention begin event and
		 * ignore the second one.
		 */
		goto end;
	case SEQ_STATE_ACQUIRING:
	case SEQ_STATE_READ_ACQUIRED:
	case SEQ_STATE_RELEASED:
		/* broken lock sequence */
		if (!ls->broken) {
			ls->broken = 1;
			bad_hist[BROKEN_CONTENDED]++;
		}
		list_del_init(&seq->list);
		free(seq);
		goto end;
	default:
		BUG_ON("Unknown state of lock sequence found!\n");
		break;
	}

	if (seq->state != SEQ_STATE_CONTENDED) {
		seq->state = SEQ_STATE_CONTENDED;
		seq->prev_event_time = sample->time;
		ls->nr_contended++;
	}
end:
	return 0;
}

static int report_lock_contention_end_event(struct evsel *evsel,
					    struct perf_sample *sample)
{
	struct lock_stat *ls;
	struct thread_stat *ts;
	struct lock_seq_stat *seq;
	u64 contended_term;
	u64 addr = evsel__intval(evsel, sample, "lock_addr");
	u64 key;
	int ret;

	ret = get_key_by_aggr_mode(&key, addr, evsel, sample);
	if (ret < 0)
		return ret;

	ls = lock_stat_find(key);
	if (!ls)
		return 0;

	ts = thread_stat_find(sample->tid);
	if (!ts)
		return 0;

	seq = get_seq(ts, addr);
	if (!seq)
		return -ENOMEM;

	switch (seq->state) {
	case SEQ_STATE_UNINITIALIZED:
		goto end;
	case SEQ_STATE_CONTENDED:
		contended_term = sample->time - seq->prev_event_time;
		ls->wait_time_total += contended_term;
		if (contended_term < ls->wait_time_min)
			ls->wait_time_min = contended_term;
		if (ls->wait_time_max < contended_term)
			ls->wait_time_max = contended_term;
		break;
	case SEQ_STATE_ACQUIRING:
	case SEQ_STATE_ACQUIRED:
	case SEQ_STATE_READ_ACQUIRED:
	case SEQ_STATE_RELEASED:
		/* broken lock sequence */
		if (!ls->broken) {
			ls->broken = 1;
			bad_hist[BROKEN_ACQUIRED]++;
		}
		list_del_init(&seq->list);
		free(seq);
		goto end;
	default:
		BUG_ON("Unknown state of lock sequence found!\n");
		break;
	}

	seq->state = SEQ_STATE_ACQUIRED;
	ls->nr_acquired++;
	ls->avg_wait_time = ls->wait_time_total/ls->nr_acquired;
end:
	return 0;
}

/* lock oriented handlers */
/* TODO: handlers for CPU oriented, thread oriented */
static struct trace_lock_handler report_lock_ops  = {
	.acquire_event		= report_lock_acquire_event,
	.acquired_event		= report_lock_acquired_event,
	.contended_event	= report_lock_contended_event,
	.release_event		= report_lock_release_event,
	.contention_begin_event	= report_lock_contention_begin_event,
	.contention_end_event	= report_lock_contention_end_event,
};

static struct trace_lock_handler contention_lock_ops  = {
	.contention_begin_event	= report_lock_contention_begin_event,
	.contention_end_event	= report_lock_contention_end_event,
};


static struct trace_lock_handler *trace_handler;

static int evsel__process_lock_acquire(struct evsel *evsel, struct perf_sample *sample)
{
	if (trace_handler->acquire_event)
		return trace_handler->acquire_event(evsel, sample);
	return 0;
}

static int evsel__process_lock_acquired(struct evsel *evsel, struct perf_sample *sample)
{
	if (trace_handler->acquired_event)
		return trace_handler->acquired_event(evsel, sample);
	return 0;
}

static int evsel__process_lock_contended(struct evsel *evsel, struct perf_sample *sample)
{
	if (trace_handler->contended_event)
		return trace_handler->contended_event(evsel, sample);
	return 0;
}

static int evsel__process_lock_release(struct evsel *evsel, struct perf_sample *sample)
{
	if (trace_handler->release_event)
		return trace_handler->release_event(evsel, sample);
	return 0;
}

static int evsel__process_contention_begin(struct evsel *evsel, struct perf_sample *sample)
{
	if (trace_handler->contention_begin_event)
		return trace_handler->contention_begin_event(evsel, sample);
	return 0;
}

static int evsel__process_contention_end(struct evsel *evsel, struct perf_sample *sample)
{
	if (trace_handler->contention_end_event)
		return trace_handler->contention_end_event(evsel, sample);
	return 0;
}

static void print_bad_events(int bad, int total)
{
	/* Output for debug, this have to be removed */
	int i;
	int broken = 0;
	const char *name[4] =
		{ "acquire", "acquired", "contended", "release" };

	for (i = 0; i < BROKEN_MAX; i++)
		broken += bad_hist[i];

	if (quiet || (broken == 0 && verbose <= 0))
		return;

	pr_info("\n=== output for debug===\n\n");
	pr_info("bad: %d, total: %d\n", bad, total);
	pr_info("bad rate: %.2f %%\n", (double)bad / (double)total * 100);
	pr_info("histogram of events caused bad sequence\n");
	for (i = 0; i < BROKEN_MAX; i++)
		pr_info(" %10s: %d\n", name[i], bad_hist[i]);
}

/* TODO: various way to print, coloring, nano or milli sec */
static void print_result(void)
{
	struct lock_stat *st;
	struct lock_key *key;
	char cut_name[20];
	int bad, total, printed;

	if (!quiet) {
		pr_info("%20s ", "Name");
		list_for_each_entry(key, &lock_keys, list)
			pr_info("%*s ", key->len, key->header);
		pr_info("\n\n");
	}

	bad = total = printed = 0;
	while ((st = pop_from_result())) {
		total++;
		if (st->broken)
			bad++;
		if (!st->nr_acquired)
			continue;

		bzero(cut_name, 20);

		if (strlen(st->name) < 20) {
			/* output raw name */
			const char *name = st->name;

			if (show_thread_stats) {
				struct thread *t;

				/* st->addr contains tid of thread */
				t = perf_session__findnew(session, st->addr);
				name = thread__comm_str(t);
			}

			pr_info("%20s ", name);
		} else {
			strncpy(cut_name, st->name, 16);
			cut_name[16] = '.';
			cut_name[17] = '.';
			cut_name[18] = '.';
			cut_name[19] = '\0';
			/* cut off name for saving output style */
			pr_info("%20s ", cut_name);
		}

		list_for_each_entry(key, &lock_keys, list) {
			key->print(key, st);
			pr_info(" ");
		}
		pr_info("\n");

		if (++printed >= print_nr_entries)
			break;
	}

	print_bad_events(bad, total);
}

static bool info_threads, info_map;

static void dump_threads(void)
{
	struct thread_stat *st;
	struct rb_node *node;
	struct thread *t;

	pr_info("%10s: comm\n", "Thread ID");

	node = rb_first(&thread_stats);
	while (node) {
		st = container_of(node, struct thread_stat, rb);
		t = perf_session__findnew(session, st->tid);
		pr_info("%10d: %s\n", st->tid, thread__comm_str(t));
		node = rb_next(node);
		thread__put(t);
	}
}

static int compare_maps(struct lock_stat *a, struct lock_stat *b)
{
	int ret;

	if (a->name && b->name)
		ret = strcmp(a->name, b->name);
	else
		ret = !!a->name - !!b->name;

	if (!ret)
		return a->addr < b->addr;
	else
		return ret < 0;
}

static void dump_map(void)
{
	unsigned int i;
	struct lock_stat *st;

	pr_info("Address of instance: name of class\n");
	for (i = 0; i < LOCKHASH_SIZE; i++) {
		hlist_for_each_entry(st, &lockhash_table[i], hash_entry) {
			insert_to_result(st, compare_maps);
		}
	}

	while ((st = pop_from_result()))
		pr_info(" %#llx: %s\n", (unsigned long long)st->addr, st->name);
}

static int dump_info(void)
{
	int rc = 0;

	if (info_threads)
		dump_threads();
	else if (info_map)
		dump_map();
	else {
		rc = -1;
		pr_err("Unknown type of information\n");
	}

	return rc;
}

static const struct evsel_str_handler lock_tracepoints[] = {
	{ "lock:lock_acquire",	 evsel__process_lock_acquire,   }, /* CONFIG_LOCKDEP */
	{ "lock:lock_acquired",	 evsel__process_lock_acquired,  }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
	{ "lock:lock_contended", evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
	{ "lock:lock_release",	 evsel__process_lock_release,   }, /* CONFIG_LOCKDEP */
};

static const struct evsel_str_handler contention_tracepoints[] = {
	{ "lock:contention_begin", evsel__process_contention_begin, },
	{ "lock:contention_end",   evsel__process_contention_end,   },
};

static int process_event_update(struct perf_tool *tool,
				union perf_event *event,
				struct evlist **pevlist)
{
	int ret;

	ret = perf_event__process_event_update(tool, event, pevlist);
	if (ret < 0)
		return ret;

	/* this can return -EEXIST since we call it for each evsel */
	perf_session__set_tracepoints_handlers(session, lock_tracepoints);
	perf_session__set_tracepoints_handlers(session, contention_tracepoints);
	return 0;
}

typedef int (*tracepoint_handler)(struct evsel *evsel,
				  struct perf_sample *sample);

static int process_sample_event(struct perf_tool *tool __maybe_unused,
				union perf_event *event,
				struct perf_sample *sample,
				struct evsel *evsel,
				struct machine *machine)
{
	int err = 0;
	struct thread *thread = machine__findnew_thread(machine, sample->pid,
							sample->tid);

	if (thread == NULL) {
		pr_debug("problem processing %d event, skipping it.\n",
			event->header.type);
		return -1;
	}

	if (evsel->handler != NULL) {
		tracepoint_handler f = evsel->handler;
		err = f(evsel, sample);
	}

	thread__put(thread);

	return err;
}

static void combine_result(void)
{
	unsigned int i;
	struct lock_stat *st;

	if (!combine_locks)
		return;

	for (i = 0; i < LOCKHASH_SIZE; i++) {
		hlist_for_each_entry(st, &lockhash_table[i], hash_entry) {
			combine_lock_stats(st);
		}
	}
}

static void sort_result(void)
{
	unsigned int i;
	struct lock_stat *st;

	for (i = 0; i < LOCKHASH_SIZE; i++) {
		hlist_for_each_entry(st, &lockhash_table[i], hash_entry) {
			insert_to_result(st, compare);
		}
	}
}

static const struct {
	unsigned int flags;
	const char *name;
} lock_type_table[] = {
	{ 0,				"semaphore" },
	{ LCB_F_SPIN,			"spinlock" },
	{ LCB_F_SPIN | LCB_F_READ,	"rwlock:R" },
	{ LCB_F_SPIN | LCB_F_WRITE,	"rwlock:W"},
	{ LCB_F_READ,			"rwsem:R" },
	{ LCB_F_WRITE,			"rwsem:W" },
	{ LCB_F_RT,			"rtmutex" },
	{ LCB_F_RT | LCB_F_READ,	"rwlock-rt:R" },
	{ LCB_F_RT | LCB_F_WRITE,	"rwlock-rt:W"},
	{ LCB_F_PERCPU | LCB_F_READ,	"pcpu-sem:R" },
	{ LCB_F_PERCPU | LCB_F_WRITE,	"pcpu-sem:W" },
	{ LCB_F_MUTEX,			"mutex" },
	{ LCB_F_MUTEX | LCB_F_SPIN,	"mutex" },
	/* alias for get_type_flag() */
	{ LCB_F_MUTEX | LCB_F_SPIN,	"mutex-spin" },
};

static const char *get_type_str(unsigned int flags)
{
	for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) {
		if (lock_type_table[i].flags == flags)
			return lock_type_table[i].name;
	}
	return "unknown";
}

static unsigned int get_type_flag(const char *str)
{
	for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) {
		if (!strcmp(lock_type_table[i].name, str))
			return lock_type_table[i].flags;
	}
	return UINT_MAX;
}

static void lock_filter_finish(void)
{
	zfree(&filters.types);
	filters.nr_types = 0;

	zfree(&filters.addrs);
	filters.nr_addrs = 0;

	for (int i = 0; i < filters.nr_syms; i++)
		free(filters.syms[i]);

	zfree(&filters.syms);
	filters.nr_syms = 0;
}

static void sort_contention_result(void)
{
	sort_result();
}

static void print_contention_result(struct lock_contention *con)
{
	struct lock_stat *st;
	struct lock_key *key;
	int bad, total, printed;

	if (!quiet) {
		list_for_each_entry(key, &lock_keys, list)
			pr_info("%*s ", key->len, key->header);

		switch (aggr_mode) {
		case LOCK_AGGR_TASK:
			pr_info("  %10s   %s\n\n", "pid",
				show_lock_owner ? "owner" : "comm");
			break;
		case LOCK_AGGR_CALLER:
			pr_info("  %10s   %s\n\n", "type", "caller");
			break;
		case LOCK_AGGR_ADDR:
			pr_info("  %16s   %s\n\n", "address", "symbol");
			break;
		default:
			break;
		}
	}

	bad = total = printed = 0;
	if (use_bpf)
		bad = bad_hist[BROKEN_CONTENDED];

	while ((st = pop_from_result())) {
		struct thread *t;
		int pid;

		total += use_bpf ? st->nr_contended : 1;
		if (st->broken)
			bad++;

		if (!st->wait_time_total)
			continue;

		list_for_each_entry(key, &lock_keys, list) {
			key->print(key, st);
			pr_info(" ");
		}

		switch (aggr_mode) {
		case LOCK_AGGR_CALLER:
			pr_info("  %10s   %s\n", get_type_str(st->flags), st->name);
			break;
		case LOCK_AGGR_TASK:
			pid = st->addr;
			t = perf_session__findnew(session, pid);
			pr_info("  %10d   %s\n",
				pid, pid == -1 ? "Unknown" : thread__comm_str(t));
			break;
		case LOCK_AGGR_ADDR:
			pr_info("  %016llx   %s\n", (unsigned long long)st->addr,
				st->name ? : "");
			break;
		default:
			break;
		}

		if (aggr_mode == LOCK_AGGR_CALLER && verbose > 0) {
			struct map *kmap;
			struct symbol *sym;
			char buf[128];
			u64 ip;

			for (int i = 0; i < max_stack_depth; i++) {
				if (!st->callstack || !st->callstack[i])
					break;

				ip = st->callstack[i];
				sym = machine__find_kernel_symbol(con->machine, ip, &kmap);
				get_symbol_name_offset(kmap, sym, ip, buf, sizeof(buf));
				pr_info("\t\t\t%#lx  %s\n", (unsigned long)ip, buf);
			}
		}

		if (++printed >= print_nr_entries)
			break;
	}

	print_bad_events(bad, total);
}

static bool force;

static int __cmd_report(bool display_info)
{
	int err = -EINVAL;
	struct perf_tool eops = {
		.attr		 = perf_event__process_attr,
		.event_update	 = process_event_update,
		.sample		 = process_sample_event,
		.comm		 = perf_event__process_comm,
		.mmap		 = perf_event__process_mmap,
		.namespaces	 = perf_event__process_namespaces,
		.tracing_data	 = perf_event__process_tracing_data,
		.ordered_events	 = true,
	};
	struct perf_data data = {
		.path  = input_name,
		.mode  = PERF_DATA_MODE_READ,
		.force = force,
	};

	session = perf_session__new(&data, &eops);
	if (IS_ERR(session)) {
		pr_err("Initializing perf session failed\n");
		return PTR_ERR(session);
	}

	/* for lock function check */
	symbol_conf.sort_by_name = true;
	symbol_conf.allow_aliases = true;
	symbol__init(&session->header.env);

	if (!data.is_pipe) {
		if (!perf_session__has_traces(session, "lock record"))
			goto out_delete;

		if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) {
			pr_err("Initializing perf session tracepoint handlers failed\n");
			goto out_delete;
		}

		if (perf_session__set_tracepoints_handlers(session, contention_tracepoints)) {
			pr_err("Initializing perf session tracepoint handlers failed\n");
			goto out_delete;
		}
	}

	if (setup_output_field(false, output_fields))
		goto out_delete;

	if (select_key(false))
		goto out_delete;

	if (show_thread_stats)
		aggr_mode = LOCK_AGGR_TASK;

	err = perf_session__process_events(session);
	if (err)
		goto out_delete;

	setup_pager();
	if (display_info) /* used for info subcommand */
		err = dump_info();
	else {
		combine_result();
		sort_result();
		print_result();
	}

out_delete:
	perf_session__delete(session);
	return err;
}

static void sighandler(int sig __maybe_unused)
{
}

static int check_lock_contention_options(const struct option *options,
					 const char * const *usage)

{
	if (show_thread_stats && show_lock_addrs) {
		pr_err("Cannot use thread and addr mode together\n");
		parse_options_usage(usage, options, "threads", 0);
		parse_options_usage(NULL, options, "lock-addr", 0);
		return -1;
	}

	if (show_lock_owner && !use_bpf) {
		pr_err("Lock owners are available only with BPF\n");
		parse_options_usage(usage, options, "lock-owner", 0);
		parse_options_usage(NULL, options, "use-bpf", 0);
		return -1;
	}

	if (show_lock_owner && show_lock_addrs) {
		pr_err("Cannot use owner and addr mode together\n");
		parse_options_usage(usage, options, "lock-owner", 0);
		parse_options_usage(NULL, options, "lock-addr", 0);
		return -1;
	}

	if (show_lock_owner)
		show_thread_stats = true;

	return 0;
}

static int __cmd_contention(int argc, const char **argv)
{
	int err = -EINVAL;
	struct perf_tool eops = {
		.attr		 = perf_event__process_attr,
		.event_update	 = process_event_update,
		.sample		 = process_sample_event,
		.comm		 = perf_event__process_comm,
		.mmap		 = perf_event__process_mmap,
		.tracing_data	 = perf_event__process_tracing_data,
		.ordered_events	 = true,
	};
	struct perf_data data = {
		.path  = input_name,
		.mode  = PERF_DATA_MODE_READ,
		.force = force,
	};
	struct lock_contention con = {
		.target = &target,
		.result = &lockhash_table[0],
		.map_nr_entries = bpf_map_entries,
		.max_stack = max_stack_depth,
		.stack_skip = stack_skip,
		.filters = &filters,
		.save_callstack = needs_callstack(),
		.owner = show_lock_owner,
	};

	session = perf_session__new(use_bpf ? NULL : &data, &eops);
	if (IS_ERR(session)) {
		pr_err("Initializing perf session failed\n");
		return PTR_ERR(session);
	}

	con.machine = &session->machines.host;

	con.aggr_mode = aggr_mode = show_thread_stats ? LOCK_AGGR_TASK :
		show_lock_addrs ? LOCK_AGGR_ADDR : LOCK_AGGR_CALLER;

	if (con.aggr_mode == LOCK_AGGR_CALLER)
		con.save_callstack = true;

	/* for lock function check */
	symbol_conf.sort_by_name = true;
	symbol_conf.allow_aliases = true;
	symbol__init(&session->header.env);

	if (use_bpf) {
		err = target__validate(&target);
		if (err) {
			char errbuf[512];

			target__strerror(&target, err, errbuf, 512);
			pr_err("%s\n", errbuf);
			goto out_delete;
		}

		signal(SIGINT, sighandler);
		signal(SIGCHLD, sighandler);
		signal(SIGTERM, sighandler);

		con.evlist = evlist__new();
		if (con.evlist == NULL) {
			err = -ENOMEM;
			goto out_delete;
		}

		err = evlist__create_maps(con.evlist, &target);
		if (err < 0)
			goto out_delete;

		if (argc) {
			err = evlist__prepare_workload(con.evlist, &target,
						       argv, false, NULL);
			if (err < 0)
				goto out_delete;
		}

		if (lock_contention_prepare(&con) < 0) {
			pr_err("lock contention BPF setup failed\n");
			goto out_delete;
		}
	} else if (!data.is_pipe) {
		if (!perf_session__has_traces(session, "lock record"))
			goto out_delete;

		if (!evlist__find_evsel_by_str(session->evlist,
					       "lock:contention_begin")) {
			pr_err("lock contention evsel not found\n");
			goto out_delete;
		}

		if (perf_session__set_tracepoints_handlers(session,
						contention_tracepoints)) {
			pr_err("Initializing perf session tracepoint handlers failed\n");
			goto out_delete;
		}
	}

	if (setup_output_field(true, output_fields))
		goto out_delete;

	if (select_key(true))
		goto out_delete;

	if (use_bpf) {
		lock_contention_start();
		if (argc)
			evlist__start_workload(con.evlist);

		/* wait for signal */
		pause();

		lock_contention_stop();
		lock_contention_read(&con);

		/* abuse bad hist stats for lost entries */
		bad_hist[BROKEN_CONTENDED] = con.lost;
	} else {
		err = perf_session__process_events(session);
		if (err)
			goto out_delete;
	}

	setup_pager();

	sort_contention_result();
	print_contention_result(&con);

out_delete:
	lock_filter_finish();
	evlist__delete(con.evlist);
	lock_contention_finish();
	perf_session__delete(session);
	return err;
}


static int __cmd_record(int argc, const char **argv)
{
	const char *record_args[] = {
		"record", "-R", "-m", "1024", "-c", "1", "--synth", "task",
	};
	const char *callgraph_args[] = {
		"--call-graph", "fp," __stringify(CONTENTION_STACK_DEPTH),
	};
	unsigned int rec_argc, i, j, ret;
	unsigned int nr_tracepoints;
	unsigned int nr_callgraph_args = 0;
	const char **rec_argv;
	bool has_lock_stat = true;

	for (i = 0; i < ARRAY_SIZE(lock_tracepoints); i++) {
		if (!is_valid_tracepoint(lock_tracepoints[i].name)) {
			pr_debug("tracepoint %s is not enabled. "
				 "Are CONFIG_LOCKDEP and CONFIG_LOCK_STAT enabled?\n",
				 lock_tracepoints[i].name);
			has_lock_stat = false;
			break;
		}
	}

	if (has_lock_stat)
		goto setup_args;

	for (i = 0; i < ARRAY_SIZE(contention_tracepoints); i++) {
		if (!is_valid_tracepoint(contention_tracepoints[i].name)) {
			pr_err("tracepoint %s is not enabled.\n",
			       contention_tracepoints[i].name);
			return 1;
		}
	}

	nr_callgraph_args = ARRAY_SIZE(callgraph_args);

setup_args:
	rec_argc = ARRAY_SIZE(record_args) + nr_callgraph_args + argc - 1;

	if (has_lock_stat)
		nr_tracepoints = ARRAY_SIZE(lock_tracepoints);
	else
		nr_tracepoints = ARRAY_SIZE(contention_tracepoints);

	/* factor of 2 is for -e in front of each tracepoint */
	rec_argc += 2 * nr_tracepoints;

	rec_argv = calloc(rec_argc + 1, sizeof(char *));
	if (!rec_argv)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(record_args); i++)
		rec_argv[i] = strdup(record_args[i]);

	for (j = 0; j < nr_tracepoints; j++) {
		const char *ev_name;

		if (has_lock_stat)
			ev_name = strdup(lock_tracepoints[j].name);
		else
			ev_name = strdup(contention_tracepoints[j].name);

		if (!ev_name)
			return -ENOMEM;

		rec_argv[i++] = "-e";
		rec_argv[i++] = ev_name;
	}

	for (j = 0; j < nr_callgraph_args; j++, i++)
		rec_argv[i] = callgraph_args[j];

	for (j = 1; j < (unsigned int)argc; j++, i++)
		rec_argv[i] = argv[j];

	BUG_ON(i != rec_argc);

	ret = cmd_record(i, rec_argv);
	free(rec_argv);
	return ret;
}

static int parse_map_entry(const struct option *opt, const char *str,
			    int unset __maybe_unused)
{
	unsigned long *len = (unsigned long *)opt->value;
	unsigned long val;
	char *endptr;

	errno = 0;
	val = strtoul(str, &endptr, 0);
	if (*endptr != '\0' || errno != 0) {
		pr_err("invalid BPF map length: %s\n", str);
		return -1;
	}

	*len = val;
	return 0;
}

static int parse_max_stack(const struct option *opt, const char *str,
			   int unset __maybe_unused)
{
	unsigned long *len = (unsigned long *)opt->value;
	long val;
	char *endptr;

	errno = 0;
	val = strtol(str, &endptr, 0);
	if (*endptr != '\0' || errno != 0) {
		pr_err("invalid max stack depth: %s\n", str);
		return -1;
	}

	if (val < 0 || val > sysctl__max_stack()) {
		pr_err("invalid max stack depth: %ld\n", val);
		return -1;
	}

	*len = val;
	return 0;
}

static bool add_lock_type(unsigned int flags)
{
	unsigned int *tmp;

	tmp = realloc(filters.types, (filters.nr_types + 1) * sizeof(*filters.types));
	if (tmp == NULL)
		return false;

	tmp[filters.nr_types++] = flags;
	filters.types = tmp;
	return true;
}

static int parse_lock_type(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)) {
		unsigned int flags = get_type_flag(tok);

		if (flags == -1U) {
			char buf[32];

			if (strchr(tok, ':'))
			    continue;

			/* try :R and :W suffixes for rwlock, rwsem, ... */
			scnprintf(buf, sizeof(buf), "%s:R", tok);
			flags = get_type_flag(buf);
			if (flags != UINT_MAX) {
				if (!add_lock_type(flags)) {
					ret = -1;
					break;
				}
			}

			scnprintf(buf, sizeof(buf), "%s:W", tok);
			flags = get_type_flag(buf);
			if (flags != UINT_MAX) {
				if (!add_lock_type(flags)) {
					ret = -1;
					break;
				}
			}
			continue;
		}

		if (!add_lock_type(flags)) {
			ret = -1;
			break;
		}

		if (!strcmp(tok, "mutex")) {
			flags = get_type_flag("mutex-spin");
			if (flags != UINT_MAX) {
				if (!add_lock_type(flags)) {
					ret = -1;
					break;
				}
			}
		}
	}

	free(s);
	return ret;
}

static bool add_lock_addr(unsigned long addr)
{
	unsigned long *tmp;

	tmp = realloc(filters.addrs, (filters.nr_addrs + 1) * sizeof(*filters.addrs));
	if (tmp == NULL) {
		pr_err("Memory allocation failure\n");
		return false;
	}

	tmp[filters.nr_addrs++] = addr;
	filters.addrs = tmp;
	return true;
}

static bool add_lock_sym(char *name)
{
	char **tmp;
	char *sym = strdup(name);

	if (sym == NULL) {
		pr_err("Memory allocation failure\n");
		return false;
	}

	tmp = realloc(filters.syms, (filters.nr_syms + 1) * sizeof(*filters.syms));
	if (tmp == NULL) {
		pr_err("Memory allocation failure\n");
		free(sym);
		return false;
	}

	tmp[filters.nr_syms++] = sym;
	filters.syms = tmp;
	return true;
}

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

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

	for (tok = strtok_r(s, ", ", &tmp); tok; tok = strtok_r(NULL, ", ", &tmp)) {
		char *end;

		addr = strtoul(tok, &end, 16);
		if (*end == '\0') {
			if (!add_lock_addr(addr)) {
				ret = -1;
				break;
			}
			continue;
		}

		/*
		 * At this moment, we don't have kernel symbols.  Save the symbols
		 * in a separate list and resolve them to addresses later.
		 */
		if (!add_lock_sym(tok)) {
			ret = -1;
			break;
		}
	}

	free(s);
	return ret;
}

static 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");
			return -1;
		}

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

	free(s);
	return ret;
}

int cmd_lock(int argc, const char **argv)
{
	const struct option lock_options[] = {
	OPT_STRING('i', "input", &input_name, "file", "input file name"),
	OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"),
	OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
	OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
		   "file", "vmlinux pathname"),
	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
		   "file", "kallsyms pathname"),
	OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any warnings or messages"),
	OPT_END()
	};

	const struct option info_options[] = {
	OPT_BOOLEAN('t', "threads", &info_threads,
		    "dump thread list in perf.data"),
	OPT_BOOLEAN('m', "map", &info_map,
		    "map of lock instances (address:name table)"),
	OPT_PARENT(lock_options)
	};

	const struct option report_options[] = {
	OPT_STRING('k', "key", &sort_key, "acquired",
		    "key for sorting (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"),
	OPT_STRING('F', "field", &output_fields, NULL,
		    "output fields (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"),
	/* TODO: type */
	OPT_BOOLEAN('c', "combine-locks", &combine_locks,
		    "combine locks in the same class"),
	OPT_BOOLEAN('t', "threads", &show_thread_stats,
		    "show per-thread lock stats"),
	OPT_INTEGER('E', "entries", &print_nr_entries, "display this many functions"),
	OPT_PARENT(lock_options)
	};

	struct option contention_options[] = {
	OPT_STRING('k', "key", &sort_key, "wait_total",
		    "key for sorting (contended / wait_total / wait_max / wait_min / avg_wait)"),
	OPT_STRING('F', "field", &output_fields, "contended,wait_total,wait_max,avg_wait",
		    "output fields (contended / wait_total / wait_max / wait_min / avg_wait)"),
	OPT_BOOLEAN('t', "threads", &show_thread_stats,
		    "show per-thread lock stats"),
	OPT_BOOLEAN('b', "use-bpf", &use_bpf, "use BPF program to collect lock contention stats"),
	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
		    "System-wide collection from all CPUs"),
	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
		    "List of cpus to monitor"),
	OPT_STRING('p', "pid", &target.pid, "pid",
		   "Trace on existing process id"),
	OPT_STRING(0, "tid", &target.tid, "tid",
		   "Trace on existing thread id (exclusive to --pid)"),
	OPT_CALLBACK(0, "map-nr-entries", &bpf_map_entries, "num",
		     "Max number of BPF map entries", parse_map_entry),
	OPT_CALLBACK(0, "max-stack", &max_stack_depth, "num",
		     "Set the maximum stack depth when collecting lopck contention, "
		     "Default: " __stringify(CONTENTION_STACK_DEPTH), parse_max_stack),
	OPT_INTEGER(0, "stack-skip", &stack_skip,
		    "Set the number of stack depth to skip when finding a lock caller, "
		    "Default: " __stringify(CONTENTION_STACK_SKIP)),
	OPT_INTEGER('E', "entries", &print_nr_entries, "display this many functions"),
	OPT_BOOLEAN('l', "lock-addr", &show_lock_addrs, "show lock stats by address"),
	OPT_CALLBACK('Y', "type-filter", NULL, "FLAGS",
		     "Filter specific type of locks", parse_lock_type),
	OPT_CALLBACK('L', "lock-filter", NULL, "ADDRS/NAMES",
		     "Filter specific address/symbol of locks", parse_lock_addr),
	OPT_CALLBACK('S', "callstack-filter", NULL, "NAMES",
		     "Filter specific function in the callstack", parse_call_stack),
	OPT_BOOLEAN('o', "lock-owner", &show_lock_owner, "show lock owners instead of waiters"),
	OPT_PARENT(lock_options)
	};

	const char * const info_usage[] = {
		"perf lock info [<options>]",
		NULL
	};
	const char *const lock_subcommands[] = { "record", "report", "script",
						 "info", "contention", NULL };
	const char *lock_usage[] = {
		NULL,
		NULL
	};
	const char * const report_usage[] = {
		"perf lock report [<options>]",
		NULL
	};
	const char * const contention_usage[] = {
		"perf lock contention [<options>]",
		NULL
	};
	unsigned int i;
	int rc = 0;

	for (i = 0; i < LOCKHASH_SIZE; i++)
		INIT_HLIST_HEAD(lockhash_table + i);

	argc = parse_options_subcommand(argc, argv, lock_options, lock_subcommands,
					lock_usage, PARSE_OPT_STOP_AT_NON_OPTION);
	if (!argc)
		usage_with_options(lock_usage, lock_options);

	if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
		return __cmd_record(argc, argv);
	} else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
		trace_handler = &report_lock_ops;
		if (argc) {
			argc = parse_options(argc, argv,
					     report_options, report_usage, 0);
			if (argc)
				usage_with_options(report_usage, report_options);
		}
		rc = __cmd_report(false);
	} else if (!strcmp(argv[0], "script")) {
		/* Aliased to 'perf script' */
		return cmd_script(argc, argv);
	} else if (!strcmp(argv[0], "info")) {
		if (argc) {
			argc = parse_options(argc, argv,
					     info_options, info_usage, 0);
			if (argc)
				usage_with_options(info_usage, info_options);
		}
		/* recycling report_lock_ops */
		trace_handler = &report_lock_ops;
		rc = __cmd_report(true);
	} else if (strlen(argv[0]) > 2 && strstarts("contention", argv[0])) {
		trace_handler = &contention_lock_ops;
		sort_key = "wait_total";
		output_fields = "contended,wait_total,wait_max,avg_wait";

#ifndef HAVE_BPF_SKEL
		set_option_nobuild(contention_options, 'b', "use-bpf",
				   "no BUILD_BPF_SKEL=1", false);
#endif
		if (argc) {
			argc = parse_options(argc, argv, contention_options,
					     contention_usage, 0);
		}

		if (check_lock_contention_options(contention_options,
						  contention_usage) < 0)
			return -1;

		rc = __cmd_contention(argc, argv);
	} else {
		usage_with_options(lock_usage, lock_options);
	}

	return rc;
}
