xref: /openbmc/linux/tools/perf/builtin-lock.c (revision 69c5c993)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <errno.h>
3 #include <inttypes.h>
4 #include "builtin.h"
5 #include "perf.h"
6 
7 #include "util/evlist.h" // for struct evsel_str_handler
8 #include "util/evsel.h"
9 #include "util/symbol.h"
10 #include "util/thread.h"
11 #include "util/header.h"
12 #include "util/target.h"
13 #include "util/callchain.h"
14 #include "util/lock-contention.h"
15 #include "util/bpf_skel/lock_data.h"
16 
17 #include <subcmd/pager.h>
18 #include <subcmd/parse-options.h>
19 #include "util/trace-event.h"
20 #include "util/tracepoint.h"
21 
22 #include "util/debug.h"
23 #include "util/session.h"
24 #include "util/tool.h"
25 #include "util/data.h"
26 #include "util/string2.h"
27 #include "util/map.h"
28 #include "util/util.h"
29 
30 #include <sys/types.h>
31 #include <sys/prctl.h>
32 #include <semaphore.h>
33 #include <math.h>
34 #include <limits.h>
35 #include <ctype.h>
36 
37 #include <linux/list.h>
38 #include <linux/hash.h>
39 #include <linux/kernel.h>
40 #include <linux/zalloc.h>
41 #include <linux/err.h>
42 #include <linux/stringify.h>
43 
44 static struct perf_session *session;
45 static struct target target;
46 
47 /* based on kernel/lockdep.c */
48 #define LOCKHASH_BITS		12
49 #define LOCKHASH_SIZE		(1UL << LOCKHASH_BITS)
50 
51 static struct hlist_head *lockhash_table;
52 
53 #define __lockhashfn(key)	hash_long((unsigned long)key, LOCKHASH_BITS)
54 #define lockhashentry(key)	(lockhash_table + __lockhashfn((key)))
55 
56 static struct rb_root		thread_stats;
57 
58 static bool combine_locks;
59 static bool show_thread_stats;
60 static bool show_lock_addrs;
61 static bool show_lock_owner;
62 static bool use_bpf;
63 static unsigned long bpf_map_entries = MAX_ENTRIES;
64 static int max_stack_depth = CONTENTION_STACK_DEPTH;
65 static int stack_skip = CONTENTION_STACK_SKIP;
66 static int print_nr_entries = INT_MAX / 2;
67 static LIST_HEAD(callstack_filters);
68 
69 struct callstack_filter {
70 	struct list_head list;
71 	char name[];
72 };
73 
74 static struct lock_filter filters;
75 
76 static enum lock_aggr_mode aggr_mode = LOCK_AGGR_ADDR;
77 
78 static bool needs_callstack(void)
79 {
80 	return !list_empty(&callstack_filters);
81 }
82 
83 static struct thread_stat *thread_stat_find(u32 tid)
84 {
85 	struct rb_node *node;
86 	struct thread_stat *st;
87 
88 	node = thread_stats.rb_node;
89 	while (node) {
90 		st = container_of(node, struct thread_stat, rb);
91 		if (st->tid == tid)
92 			return st;
93 		else if (tid < st->tid)
94 			node = node->rb_left;
95 		else
96 			node = node->rb_right;
97 	}
98 
99 	return NULL;
100 }
101 
102 static void thread_stat_insert(struct thread_stat *new)
103 {
104 	struct rb_node **rb = &thread_stats.rb_node;
105 	struct rb_node *parent = NULL;
106 	struct thread_stat *p;
107 
108 	while (*rb) {
109 		p = container_of(*rb, struct thread_stat, rb);
110 		parent = *rb;
111 
112 		if (new->tid < p->tid)
113 			rb = &(*rb)->rb_left;
114 		else if (new->tid > p->tid)
115 			rb = &(*rb)->rb_right;
116 		else
117 			BUG_ON("inserting invalid thread_stat\n");
118 	}
119 
120 	rb_link_node(&new->rb, parent, rb);
121 	rb_insert_color(&new->rb, &thread_stats);
122 }
123 
124 static struct thread_stat *thread_stat_findnew_after_first(u32 tid)
125 {
126 	struct thread_stat *st;
127 
128 	st = thread_stat_find(tid);
129 	if (st)
130 		return st;
131 
132 	st = zalloc(sizeof(struct thread_stat));
133 	if (!st) {
134 		pr_err("memory allocation failed\n");
135 		return NULL;
136 	}
137 
138 	st->tid = tid;
139 	INIT_LIST_HEAD(&st->seq_list);
140 
141 	thread_stat_insert(st);
142 
143 	return st;
144 }
145 
146 static struct thread_stat *thread_stat_findnew_first(u32 tid);
147 static struct thread_stat *(*thread_stat_findnew)(u32 tid) =
148 	thread_stat_findnew_first;
149 
150 static struct thread_stat *thread_stat_findnew_first(u32 tid)
151 {
152 	struct thread_stat *st;
153 
154 	st = zalloc(sizeof(struct thread_stat));
155 	if (!st) {
156 		pr_err("memory allocation failed\n");
157 		return NULL;
158 	}
159 	st->tid = tid;
160 	INIT_LIST_HEAD(&st->seq_list);
161 
162 	rb_link_node(&st->rb, NULL, &thread_stats.rb_node);
163 	rb_insert_color(&st->rb, &thread_stats);
164 
165 	thread_stat_findnew = thread_stat_findnew_after_first;
166 	return st;
167 }
168 
169 /* build simple key function one is bigger than two */
170 #define SINGLE_KEY(member)						\
171 	static int lock_stat_key_ ## member(struct lock_stat *one,	\
172 					 struct lock_stat *two)		\
173 	{								\
174 		return one->member > two->member;			\
175 	}
176 
177 SINGLE_KEY(nr_acquired)
178 SINGLE_KEY(nr_contended)
179 SINGLE_KEY(avg_wait_time)
180 SINGLE_KEY(wait_time_total)
181 SINGLE_KEY(wait_time_max)
182 
183 static int lock_stat_key_wait_time_min(struct lock_stat *one,
184 					struct lock_stat *two)
185 {
186 	u64 s1 = one->wait_time_min;
187 	u64 s2 = two->wait_time_min;
188 	if (s1 == ULLONG_MAX)
189 		s1 = 0;
190 	if (s2 == ULLONG_MAX)
191 		s2 = 0;
192 	return s1 > s2;
193 }
194 
195 struct lock_key {
196 	/*
197 	 * name: the value for specify by user
198 	 * this should be simpler than raw name of member
199 	 * e.g. nr_acquired -> acquired, wait_time_total -> wait_total
200 	 */
201 	const char		*name;
202 	/* header: the string printed on the header line */
203 	const char		*header;
204 	/* len: the printing width of the field */
205 	int			len;
206 	/* key: a pointer to function to compare two lock stats for sorting */
207 	int			(*key)(struct lock_stat*, struct lock_stat*);
208 	/* print: a pointer to function to print a given lock stats */
209 	void			(*print)(struct lock_key*, struct lock_stat*);
210 	/* list: list entry to link this */
211 	struct list_head	list;
212 };
213 
214 static void lock_stat_key_print_time(unsigned long long nsec, int len)
215 {
216 	static const struct {
217 		float base;
218 		const char *unit;
219 	} table[] = {
220 		{ 1e9 * 3600, "h " },
221 		{ 1e9 * 60, "m " },
222 		{ 1e9, "s " },
223 		{ 1e6, "ms" },
224 		{ 1e3, "us" },
225 		{ 0, NULL },
226 	};
227 
228 	/* for CSV output */
229 	if (len == 0) {
230 		pr_info("%llu", nsec);
231 		return;
232 	}
233 
234 	for (int i = 0; table[i].unit; i++) {
235 		if (nsec < table[i].base)
236 			continue;
237 
238 		pr_info("%*.2f %s", len - 3, nsec / table[i].base, table[i].unit);
239 		return;
240 	}
241 
242 	pr_info("%*llu %s", len - 3, nsec, "ns");
243 }
244 
245 #define PRINT_KEY(member)						\
246 static void lock_stat_key_print_ ## member(struct lock_key *key,	\
247 					   struct lock_stat *ls)	\
248 {									\
249 	pr_info("%*llu", key->len, (unsigned long long)ls->member);	\
250 }
251 
252 #define PRINT_TIME(member)						\
253 static void lock_stat_key_print_ ## member(struct lock_key *key,	\
254 					   struct lock_stat *ls)	\
255 {									\
256 	lock_stat_key_print_time((unsigned long long)ls->member, key->len);	\
257 }
258 
259 PRINT_KEY(nr_acquired)
260 PRINT_KEY(nr_contended)
261 PRINT_TIME(avg_wait_time)
262 PRINT_TIME(wait_time_total)
263 PRINT_TIME(wait_time_max)
264 
265 static void lock_stat_key_print_wait_time_min(struct lock_key *key,
266 					      struct lock_stat *ls)
267 {
268 	u64 wait_time = ls->wait_time_min;
269 
270 	if (wait_time == ULLONG_MAX)
271 		wait_time = 0;
272 
273 	lock_stat_key_print_time(wait_time, key->len);
274 }
275 
276 
277 static const char		*sort_key = "acquired";
278 
279 static int			(*compare)(struct lock_stat *, struct lock_stat *);
280 
281 static struct rb_root		sorted; /* place to store intermediate data */
282 static struct rb_root		result;	/* place to store sorted data */
283 
284 static LIST_HEAD(lock_keys);
285 static const char		*output_fields;
286 
287 #define DEF_KEY_LOCK(name, header, fn_suffix, len)			\
288 	{ #name, header, len, lock_stat_key_ ## fn_suffix, lock_stat_key_print_ ## fn_suffix, {} }
289 static struct lock_key report_keys[] = {
290 	DEF_KEY_LOCK(acquired, "acquired", nr_acquired, 10),
291 	DEF_KEY_LOCK(contended, "contended", nr_contended, 10),
292 	DEF_KEY_LOCK(avg_wait, "avg wait", avg_wait_time, 12),
293 	DEF_KEY_LOCK(wait_total, "total wait", wait_time_total, 12),
294 	DEF_KEY_LOCK(wait_max, "max wait", wait_time_max, 12),
295 	DEF_KEY_LOCK(wait_min, "min wait", wait_time_min, 12),
296 
297 	/* extra comparisons much complicated should be here */
298 	{ }
299 };
300 
301 static struct lock_key contention_keys[] = {
302 	DEF_KEY_LOCK(contended, "contended", nr_contended, 10),
303 	DEF_KEY_LOCK(wait_total, "total wait", wait_time_total, 12),
304 	DEF_KEY_LOCK(wait_max, "max wait", wait_time_max, 12),
305 	DEF_KEY_LOCK(wait_min, "min wait", wait_time_min, 12),
306 	DEF_KEY_LOCK(avg_wait, "avg wait", avg_wait_time, 12),
307 
308 	/* extra comparisons much complicated should be here */
309 	{ }
310 };
311 
312 static int select_key(bool contention)
313 {
314 	int i;
315 	struct lock_key *keys = report_keys;
316 
317 	if (contention)
318 		keys = contention_keys;
319 
320 	for (i = 0; keys[i].name; i++) {
321 		if (!strcmp(keys[i].name, sort_key)) {
322 			compare = keys[i].key;
323 
324 			/* selected key should be in the output fields */
325 			if (list_empty(&keys[i].list))
326 				list_add_tail(&keys[i].list, &lock_keys);
327 
328 			return 0;
329 		}
330 	}
331 
332 	pr_err("Unknown compare key: %s\n", sort_key);
333 	return -1;
334 }
335 
336 static int add_output_field(bool contention, char *name)
337 {
338 	int i;
339 	struct lock_key *keys = report_keys;
340 
341 	if (contention)
342 		keys = contention_keys;
343 
344 	for (i = 0; keys[i].name; i++) {
345 		if (strcmp(keys[i].name, name))
346 			continue;
347 
348 		/* prevent double link */
349 		if (list_empty(&keys[i].list))
350 			list_add_tail(&keys[i].list, &lock_keys);
351 
352 		return 0;
353 	}
354 
355 	pr_err("Unknown output field: %s\n", name);
356 	return -1;
357 }
358 
359 static int setup_output_field(bool contention, const char *str)
360 {
361 	char *tok, *tmp, *orig;
362 	int i, ret = 0;
363 	struct lock_key *keys = report_keys;
364 
365 	if (contention)
366 		keys = contention_keys;
367 
368 	/* no output field given: use all of them */
369 	if (str == NULL) {
370 		for (i = 0; keys[i].name; i++)
371 			list_add_tail(&keys[i].list, &lock_keys);
372 		return 0;
373 	}
374 
375 	for (i = 0; keys[i].name; i++)
376 		INIT_LIST_HEAD(&keys[i].list);
377 
378 	orig = tmp = strdup(str);
379 	if (orig == NULL)
380 		return -ENOMEM;
381 
382 	while ((tok = strsep(&tmp, ",")) != NULL){
383 		ret = add_output_field(contention, tok);
384 		if (ret < 0)
385 			break;
386 	}
387 	free(orig);
388 
389 	return ret;
390 }
391 
392 static void combine_lock_stats(struct lock_stat *st)
393 {
394 	struct rb_node **rb = &sorted.rb_node;
395 	struct rb_node *parent = NULL;
396 	struct lock_stat *p;
397 	int ret;
398 
399 	while (*rb) {
400 		p = container_of(*rb, struct lock_stat, rb);
401 		parent = *rb;
402 
403 		if (st->name && p->name)
404 			ret = strcmp(st->name, p->name);
405 		else
406 			ret = !!st->name - !!p->name;
407 
408 		if (ret == 0) {
409 			p->nr_acquired += st->nr_acquired;
410 			p->nr_contended += st->nr_contended;
411 			p->wait_time_total += st->wait_time_total;
412 
413 			if (p->nr_contended)
414 				p->avg_wait_time = p->wait_time_total / p->nr_contended;
415 
416 			if (p->wait_time_min > st->wait_time_min)
417 				p->wait_time_min = st->wait_time_min;
418 			if (p->wait_time_max < st->wait_time_max)
419 				p->wait_time_max = st->wait_time_max;
420 
421 			p->broken |= st->broken;
422 			st->combined = 1;
423 			return;
424 		}
425 
426 		if (ret < 0)
427 			rb = &(*rb)->rb_left;
428 		else
429 			rb = &(*rb)->rb_right;
430 	}
431 
432 	rb_link_node(&st->rb, parent, rb);
433 	rb_insert_color(&st->rb, &sorted);
434 }
435 
436 static void insert_to_result(struct lock_stat *st,
437 			     int (*bigger)(struct lock_stat *, struct lock_stat *))
438 {
439 	struct rb_node **rb = &result.rb_node;
440 	struct rb_node *parent = NULL;
441 	struct lock_stat *p;
442 
443 	if (combine_locks && st->combined)
444 		return;
445 
446 	while (*rb) {
447 		p = container_of(*rb, struct lock_stat, rb);
448 		parent = *rb;
449 
450 		if (bigger(st, p))
451 			rb = &(*rb)->rb_left;
452 		else
453 			rb = &(*rb)->rb_right;
454 	}
455 
456 	rb_link_node(&st->rb, parent, rb);
457 	rb_insert_color(&st->rb, &result);
458 }
459 
460 /* returns left most element of result, and erase it */
461 static struct lock_stat *pop_from_result(void)
462 {
463 	struct rb_node *node = result.rb_node;
464 
465 	if (!node)
466 		return NULL;
467 
468 	while (node->rb_left)
469 		node = node->rb_left;
470 
471 	rb_erase(node, &result);
472 	return container_of(node, struct lock_stat, rb);
473 }
474 
475 struct lock_stat *lock_stat_find(u64 addr)
476 {
477 	struct hlist_head *entry = lockhashentry(addr);
478 	struct lock_stat *ret;
479 
480 	hlist_for_each_entry(ret, entry, hash_entry) {
481 		if (ret->addr == addr)
482 			return ret;
483 	}
484 	return NULL;
485 }
486 
487 struct lock_stat *lock_stat_findnew(u64 addr, const char *name, int flags)
488 {
489 	struct hlist_head *entry = lockhashentry(addr);
490 	struct lock_stat *ret, *new;
491 
492 	hlist_for_each_entry(ret, entry, hash_entry) {
493 		if (ret->addr == addr)
494 			return ret;
495 	}
496 
497 	new = zalloc(sizeof(struct lock_stat));
498 	if (!new)
499 		goto alloc_failed;
500 
501 	new->addr = addr;
502 	new->name = strdup(name);
503 	if (!new->name) {
504 		free(new);
505 		goto alloc_failed;
506 	}
507 
508 	new->flags = flags;
509 	new->wait_time_min = ULLONG_MAX;
510 
511 	hlist_add_head(&new->hash_entry, entry);
512 	return new;
513 
514 alloc_failed:
515 	pr_err("memory allocation failed\n");
516 	return NULL;
517 }
518 
519 bool match_callstack_filter(struct machine *machine, u64 *callstack)
520 {
521 	struct map *kmap;
522 	struct symbol *sym;
523 	u64 ip;
524 
525 	if (list_empty(&callstack_filters))
526 		return true;
527 
528 	for (int i = 0; i < max_stack_depth; i++) {
529 		struct callstack_filter *filter;
530 
531 		if (!callstack || !callstack[i])
532 			break;
533 
534 		ip = callstack[i];
535 		sym = machine__find_kernel_symbol(machine, ip, &kmap);
536 		if (sym == NULL)
537 			continue;
538 
539 		list_for_each_entry(filter, &callstack_filters, list) {
540 			if (strstr(sym->name, filter->name))
541 				return true;
542 		}
543 	}
544 	return false;
545 }
546 
547 struct trace_lock_handler {
548 	/* it's used on CONFIG_LOCKDEP */
549 	int (*acquire_event)(struct evsel *evsel,
550 			     struct perf_sample *sample);
551 
552 	/* it's used on CONFIG_LOCKDEP && CONFIG_LOCK_STAT */
553 	int (*acquired_event)(struct evsel *evsel,
554 			      struct perf_sample *sample);
555 
556 	/* it's used on CONFIG_LOCKDEP && CONFIG_LOCK_STAT */
557 	int (*contended_event)(struct evsel *evsel,
558 			       struct perf_sample *sample);
559 
560 	/* it's used on CONFIG_LOCKDEP */
561 	int (*release_event)(struct evsel *evsel,
562 			     struct perf_sample *sample);
563 
564 	/* it's used when CONFIG_LOCKDEP is off */
565 	int (*contention_begin_event)(struct evsel *evsel,
566 				      struct perf_sample *sample);
567 
568 	/* it's used when CONFIG_LOCKDEP is off */
569 	int (*contention_end_event)(struct evsel *evsel,
570 				    struct perf_sample *sample);
571 };
572 
573 static struct lock_seq_stat *get_seq(struct thread_stat *ts, u64 addr)
574 {
575 	struct lock_seq_stat *seq;
576 
577 	list_for_each_entry(seq, &ts->seq_list, list) {
578 		if (seq->addr == addr)
579 			return seq;
580 	}
581 
582 	seq = zalloc(sizeof(struct lock_seq_stat));
583 	if (!seq) {
584 		pr_err("memory allocation failed\n");
585 		return NULL;
586 	}
587 	seq->state = SEQ_STATE_UNINITIALIZED;
588 	seq->addr = addr;
589 
590 	list_add(&seq->list, &ts->seq_list);
591 	return seq;
592 }
593 
594 enum broken_state {
595 	BROKEN_ACQUIRE,
596 	BROKEN_ACQUIRED,
597 	BROKEN_CONTENDED,
598 	BROKEN_RELEASE,
599 	BROKEN_MAX,
600 };
601 
602 static int bad_hist[BROKEN_MAX];
603 
604 enum acquire_flags {
605 	TRY_LOCK = 1,
606 	READ_LOCK = 2,
607 };
608 
609 static int get_key_by_aggr_mode_simple(u64 *key, u64 addr, u32 tid)
610 {
611 	switch (aggr_mode) {
612 	case LOCK_AGGR_ADDR:
613 		*key = addr;
614 		break;
615 	case LOCK_AGGR_TASK:
616 		*key = tid;
617 		break;
618 	case LOCK_AGGR_CALLER:
619 	default:
620 		pr_err("Invalid aggregation mode: %d\n", aggr_mode);
621 		return -EINVAL;
622 	}
623 	return 0;
624 }
625 
626 static u64 callchain_id(struct evsel *evsel, struct perf_sample *sample);
627 
628 static int get_key_by_aggr_mode(u64 *key, u64 addr, struct evsel *evsel,
629 				 struct perf_sample *sample)
630 {
631 	if (aggr_mode == LOCK_AGGR_CALLER) {
632 		*key = callchain_id(evsel, sample);
633 		return 0;
634 	}
635 	return get_key_by_aggr_mode_simple(key, addr, sample->tid);
636 }
637 
638 static int report_lock_acquire_event(struct evsel *evsel,
639 				     struct perf_sample *sample)
640 {
641 	struct lock_stat *ls;
642 	struct thread_stat *ts;
643 	struct lock_seq_stat *seq;
644 	const char *name = evsel__strval(evsel, sample, "name");
645 	u64 addr = evsel__intval(evsel, sample, "lockdep_addr");
646 	int flag = evsel__intval(evsel, sample, "flags");
647 	u64 key;
648 	int ret;
649 
650 	ret = get_key_by_aggr_mode_simple(&key, addr, sample->tid);
651 	if (ret < 0)
652 		return ret;
653 
654 	ls = lock_stat_findnew(key, name, 0);
655 	if (!ls)
656 		return -ENOMEM;
657 
658 	ts = thread_stat_findnew(sample->tid);
659 	if (!ts)
660 		return -ENOMEM;
661 
662 	seq = get_seq(ts, addr);
663 	if (!seq)
664 		return -ENOMEM;
665 
666 	switch (seq->state) {
667 	case SEQ_STATE_UNINITIALIZED:
668 	case SEQ_STATE_RELEASED:
669 		if (!flag) {
670 			seq->state = SEQ_STATE_ACQUIRING;
671 		} else {
672 			if (flag & TRY_LOCK)
673 				ls->nr_trylock++;
674 			if (flag & READ_LOCK)
675 				ls->nr_readlock++;
676 			seq->state = SEQ_STATE_READ_ACQUIRED;
677 			seq->read_count = 1;
678 			ls->nr_acquired++;
679 		}
680 		break;
681 	case SEQ_STATE_READ_ACQUIRED:
682 		if (flag & READ_LOCK) {
683 			seq->read_count++;
684 			ls->nr_acquired++;
685 			goto end;
686 		} else {
687 			goto broken;
688 		}
689 		break;
690 	case SEQ_STATE_ACQUIRED:
691 	case SEQ_STATE_ACQUIRING:
692 	case SEQ_STATE_CONTENDED:
693 broken:
694 		/* broken lock sequence */
695 		if (!ls->broken) {
696 			ls->broken = 1;
697 			bad_hist[BROKEN_ACQUIRE]++;
698 		}
699 		list_del_init(&seq->list);
700 		free(seq);
701 		goto end;
702 	default:
703 		BUG_ON("Unknown state of lock sequence found!\n");
704 		break;
705 	}
706 
707 	ls->nr_acquire++;
708 	seq->prev_event_time = sample->time;
709 end:
710 	return 0;
711 }
712 
713 static int report_lock_acquired_event(struct evsel *evsel,
714 				      struct perf_sample *sample)
715 {
716 	struct lock_stat *ls;
717 	struct thread_stat *ts;
718 	struct lock_seq_stat *seq;
719 	u64 contended_term;
720 	const char *name = evsel__strval(evsel, sample, "name");
721 	u64 addr = evsel__intval(evsel, sample, "lockdep_addr");
722 	u64 key;
723 	int ret;
724 
725 	ret = get_key_by_aggr_mode_simple(&key, addr, sample->tid);
726 	if (ret < 0)
727 		return ret;
728 
729 	ls = lock_stat_findnew(key, name, 0);
730 	if (!ls)
731 		return -ENOMEM;
732 
733 	ts = thread_stat_findnew(sample->tid);
734 	if (!ts)
735 		return -ENOMEM;
736 
737 	seq = get_seq(ts, addr);
738 	if (!seq)
739 		return -ENOMEM;
740 
741 	switch (seq->state) {
742 	case SEQ_STATE_UNINITIALIZED:
743 		/* orphan event, do nothing */
744 		return 0;
745 	case SEQ_STATE_ACQUIRING:
746 		break;
747 	case SEQ_STATE_CONTENDED:
748 		contended_term = sample->time - seq->prev_event_time;
749 		ls->wait_time_total += contended_term;
750 		if (contended_term < ls->wait_time_min)
751 			ls->wait_time_min = contended_term;
752 		if (ls->wait_time_max < contended_term)
753 			ls->wait_time_max = contended_term;
754 		break;
755 	case SEQ_STATE_RELEASED:
756 	case SEQ_STATE_ACQUIRED:
757 	case SEQ_STATE_READ_ACQUIRED:
758 		/* broken lock sequence */
759 		if (!ls->broken) {
760 			ls->broken = 1;
761 			bad_hist[BROKEN_ACQUIRED]++;
762 		}
763 		list_del_init(&seq->list);
764 		free(seq);
765 		goto end;
766 	default:
767 		BUG_ON("Unknown state of lock sequence found!\n");
768 		break;
769 	}
770 
771 	seq->state = SEQ_STATE_ACQUIRED;
772 	ls->nr_acquired++;
773 	ls->avg_wait_time = ls->nr_contended ? ls->wait_time_total/ls->nr_contended : 0;
774 	seq->prev_event_time = sample->time;
775 end:
776 	return 0;
777 }
778 
779 static int report_lock_contended_event(struct evsel *evsel,
780 				       struct perf_sample *sample)
781 {
782 	struct lock_stat *ls;
783 	struct thread_stat *ts;
784 	struct lock_seq_stat *seq;
785 	const char *name = evsel__strval(evsel, sample, "name");
786 	u64 addr = evsel__intval(evsel, sample, "lockdep_addr");
787 	u64 key;
788 	int ret;
789 
790 	ret = get_key_by_aggr_mode_simple(&key, addr, sample->tid);
791 	if (ret < 0)
792 		return ret;
793 
794 	ls = lock_stat_findnew(key, name, 0);
795 	if (!ls)
796 		return -ENOMEM;
797 
798 	ts = thread_stat_findnew(sample->tid);
799 	if (!ts)
800 		return -ENOMEM;
801 
802 	seq = get_seq(ts, addr);
803 	if (!seq)
804 		return -ENOMEM;
805 
806 	switch (seq->state) {
807 	case SEQ_STATE_UNINITIALIZED:
808 		/* orphan event, do nothing */
809 		return 0;
810 	case SEQ_STATE_ACQUIRING:
811 		break;
812 	case SEQ_STATE_RELEASED:
813 	case SEQ_STATE_ACQUIRED:
814 	case SEQ_STATE_READ_ACQUIRED:
815 	case SEQ_STATE_CONTENDED:
816 		/* broken lock sequence */
817 		if (!ls->broken) {
818 			ls->broken = 1;
819 			bad_hist[BROKEN_CONTENDED]++;
820 		}
821 		list_del_init(&seq->list);
822 		free(seq);
823 		goto end;
824 	default:
825 		BUG_ON("Unknown state of lock sequence found!\n");
826 		break;
827 	}
828 
829 	seq->state = SEQ_STATE_CONTENDED;
830 	ls->nr_contended++;
831 	ls->avg_wait_time = ls->wait_time_total/ls->nr_contended;
832 	seq->prev_event_time = sample->time;
833 end:
834 	return 0;
835 }
836 
837 static int report_lock_release_event(struct evsel *evsel,
838 				     struct perf_sample *sample)
839 {
840 	struct lock_stat *ls;
841 	struct thread_stat *ts;
842 	struct lock_seq_stat *seq;
843 	const char *name = evsel__strval(evsel, sample, "name");
844 	u64 addr = evsel__intval(evsel, sample, "lockdep_addr");
845 	u64 key;
846 	int ret;
847 
848 	ret = get_key_by_aggr_mode_simple(&key, addr, sample->tid);
849 	if (ret < 0)
850 		return ret;
851 
852 	ls = lock_stat_findnew(key, name, 0);
853 	if (!ls)
854 		return -ENOMEM;
855 
856 	ts = thread_stat_findnew(sample->tid);
857 	if (!ts)
858 		return -ENOMEM;
859 
860 	seq = get_seq(ts, addr);
861 	if (!seq)
862 		return -ENOMEM;
863 
864 	switch (seq->state) {
865 	case SEQ_STATE_UNINITIALIZED:
866 		goto end;
867 	case SEQ_STATE_ACQUIRED:
868 		break;
869 	case SEQ_STATE_READ_ACQUIRED:
870 		seq->read_count--;
871 		BUG_ON(seq->read_count < 0);
872 		if (seq->read_count) {
873 			ls->nr_release++;
874 			goto end;
875 		}
876 		break;
877 	case SEQ_STATE_ACQUIRING:
878 	case SEQ_STATE_CONTENDED:
879 	case SEQ_STATE_RELEASED:
880 		/* broken lock sequence */
881 		if (!ls->broken) {
882 			ls->broken = 1;
883 			bad_hist[BROKEN_RELEASE]++;
884 		}
885 		goto free_seq;
886 	default:
887 		BUG_ON("Unknown state of lock sequence found!\n");
888 		break;
889 	}
890 
891 	ls->nr_release++;
892 free_seq:
893 	list_del_init(&seq->list);
894 	free(seq);
895 end:
896 	return 0;
897 }
898 
899 static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip,
900 				  char *buf, int size)
901 {
902 	u64 offset;
903 
904 	if (map == NULL || sym == NULL) {
905 		buf[0] = '\0';
906 		return 0;
907 	}
908 
909 	offset = map__map_ip(map, ip) - sym->start;
910 
911 	if (offset)
912 		return scnprintf(buf, size, "%s+%#lx", sym->name, offset);
913 	else
914 		return strlcpy(buf, sym->name, size);
915 }
916 static int lock_contention_caller(struct evsel *evsel, struct perf_sample *sample,
917 				  char *buf, int size)
918 {
919 	struct thread *thread;
920 	struct callchain_cursor *cursor;
921 	struct machine *machine = &session->machines.host;
922 	struct symbol *sym;
923 	int skip = 0;
924 	int ret;
925 
926 	/* lock names will be replaced to task name later */
927 	if (show_thread_stats)
928 		return -1;
929 
930 	thread = machine__findnew_thread(machine, -1, sample->pid);
931 	if (thread == NULL)
932 		return -1;
933 
934 	cursor = get_tls_callchain_cursor();
935 
936 	/* use caller function name from the callchain */
937 	ret = thread__resolve_callchain(thread, cursor, evsel, sample,
938 					NULL, NULL, max_stack_depth);
939 	if (ret != 0) {
940 		thread__put(thread);
941 		return -1;
942 	}
943 
944 	callchain_cursor_commit(cursor);
945 	thread__put(thread);
946 
947 	while (true) {
948 		struct callchain_cursor_node *node;
949 
950 		node = callchain_cursor_current(cursor);
951 		if (node == NULL)
952 			break;
953 
954 		/* skip first few entries - for lock functions */
955 		if (++skip <= stack_skip)
956 			goto next;
957 
958 		sym = node->ms.sym;
959 		if (sym && !machine__is_lock_function(machine, node->ip)) {
960 			get_symbol_name_offset(node->ms.map, sym, node->ip,
961 					       buf, size);
962 			return 0;
963 		}
964 
965 next:
966 		callchain_cursor_advance(cursor);
967 	}
968 	return -1;
969 }
970 
971 static u64 callchain_id(struct evsel *evsel, struct perf_sample *sample)
972 {
973 	struct callchain_cursor *cursor;
974 	struct machine *machine = &session->machines.host;
975 	struct thread *thread;
976 	u64 hash = 0;
977 	int skip = 0;
978 	int ret;
979 
980 	thread = machine__findnew_thread(machine, -1, sample->pid);
981 	if (thread == NULL)
982 		return -1;
983 
984 	cursor = get_tls_callchain_cursor();
985 	/* use caller function name from the callchain */
986 	ret = thread__resolve_callchain(thread, cursor, evsel, sample,
987 					NULL, NULL, max_stack_depth);
988 	thread__put(thread);
989 
990 	if (ret != 0)
991 		return -1;
992 
993 	callchain_cursor_commit(cursor);
994 
995 	while (true) {
996 		struct callchain_cursor_node *node;
997 
998 		node = callchain_cursor_current(cursor);
999 		if (node == NULL)
1000 			break;
1001 
1002 		/* skip first few entries - for lock functions */
1003 		if (++skip <= stack_skip)
1004 			goto next;
1005 
1006 		if (node->ms.sym && machine__is_lock_function(machine, node->ip))
1007 			goto next;
1008 
1009 		hash ^= hash_long((unsigned long)node->ip, 64);
1010 
1011 next:
1012 		callchain_cursor_advance(cursor);
1013 	}
1014 	return hash;
1015 }
1016 
1017 static u64 *get_callstack(struct perf_sample *sample, int max_stack)
1018 {
1019 	u64 *callstack;
1020 	u64 i;
1021 	int c;
1022 
1023 	callstack = calloc(max_stack, sizeof(*callstack));
1024 	if (callstack == NULL)
1025 		return NULL;
1026 
1027 	for (i = 0, c = 0; i < sample->callchain->nr && c < max_stack; i++) {
1028 		u64 ip = sample->callchain->ips[i];
1029 
1030 		if (ip >= PERF_CONTEXT_MAX)
1031 			continue;
1032 
1033 		callstack[c++] = ip;
1034 	}
1035 	return callstack;
1036 }
1037 
1038 static int report_lock_contention_begin_event(struct evsel *evsel,
1039 					      struct perf_sample *sample)
1040 {
1041 	struct lock_stat *ls;
1042 	struct thread_stat *ts;
1043 	struct lock_seq_stat *seq;
1044 	u64 addr = evsel__intval(evsel, sample, "lock_addr");
1045 	unsigned int flags = evsel__intval(evsel, sample, "flags");
1046 	u64 key;
1047 	int i, ret;
1048 	static bool kmap_loaded;
1049 	struct machine *machine = &session->machines.host;
1050 	struct map *kmap;
1051 	struct symbol *sym;
1052 
1053 	ret = get_key_by_aggr_mode(&key, addr, evsel, sample);
1054 	if (ret < 0)
1055 		return ret;
1056 
1057 	if (!kmap_loaded) {
1058 		unsigned long *addrs;
1059 
1060 		/* make sure it loads the kernel map to find lock symbols */
1061 		map__load(machine__kernel_map(machine));
1062 		kmap_loaded = true;
1063 
1064 		/* convert (kernel) symbols to addresses */
1065 		for (i = 0; i < filters.nr_syms; i++) {
1066 			sym = machine__find_kernel_symbol_by_name(machine,
1067 								  filters.syms[i],
1068 								  &kmap);
1069 			if (sym == NULL) {
1070 				pr_warning("ignore unknown symbol: %s\n",
1071 					   filters.syms[i]);
1072 				continue;
1073 			}
1074 
1075 			addrs = realloc(filters.addrs,
1076 					(filters.nr_addrs + 1) * sizeof(*addrs));
1077 			if (addrs == NULL) {
1078 				pr_warning("memory allocation failure\n");
1079 				return -ENOMEM;
1080 			}
1081 
1082 			addrs[filters.nr_addrs++] = map__unmap_ip(kmap, sym->start);
1083 			filters.addrs = addrs;
1084 		}
1085 	}
1086 
1087 	ls = lock_stat_find(key);
1088 	if (!ls) {
1089 		char buf[128];
1090 		const char *name = "";
1091 
1092 		switch (aggr_mode) {
1093 		case LOCK_AGGR_ADDR:
1094 			sym = machine__find_kernel_symbol(machine, key, &kmap);
1095 			if (sym)
1096 				name = sym->name;
1097 			break;
1098 		case LOCK_AGGR_CALLER:
1099 			name = buf;
1100 			if (lock_contention_caller(evsel, sample, buf, sizeof(buf)) < 0)
1101 				name = "Unknown";
1102 			break;
1103 		case LOCK_AGGR_TASK:
1104 		default:
1105 			break;
1106 		}
1107 
1108 		ls = lock_stat_findnew(key, name, flags);
1109 		if (!ls)
1110 			return -ENOMEM;
1111 	}
1112 
1113 	if (filters.nr_types) {
1114 		bool found = false;
1115 
1116 		for (i = 0; i < filters.nr_types; i++) {
1117 			if (flags == filters.types[i]) {
1118 				found = true;
1119 				break;
1120 			}
1121 		}
1122 
1123 		if (!found)
1124 			return 0;
1125 	}
1126 
1127 	if (filters.nr_addrs) {
1128 		bool found = false;
1129 
1130 		for (i = 0; i < filters.nr_addrs; i++) {
1131 			if (addr == filters.addrs[i]) {
1132 				found = true;
1133 				break;
1134 			}
1135 		}
1136 
1137 		if (!found)
1138 			return 0;
1139 	}
1140 
1141 	if (needs_callstack()) {
1142 		u64 *callstack = get_callstack(sample, max_stack_depth);
1143 		if (callstack == NULL)
1144 			return -ENOMEM;
1145 
1146 		if (!match_callstack_filter(machine, callstack)) {
1147 			free(callstack);
1148 			return 0;
1149 		}
1150 
1151 		if (ls->callstack == NULL)
1152 			ls->callstack = callstack;
1153 		else
1154 			free(callstack);
1155 	}
1156 
1157 	ts = thread_stat_findnew(sample->tid);
1158 	if (!ts)
1159 		return -ENOMEM;
1160 
1161 	seq = get_seq(ts, addr);
1162 	if (!seq)
1163 		return -ENOMEM;
1164 
1165 	switch (seq->state) {
1166 	case SEQ_STATE_UNINITIALIZED:
1167 	case SEQ_STATE_ACQUIRED:
1168 		break;
1169 	case SEQ_STATE_CONTENDED:
1170 		/*
1171 		 * It can have nested contention begin with mutex spinning,
1172 		 * then we would use the original contention begin event and
1173 		 * ignore the second one.
1174 		 */
1175 		goto end;
1176 	case SEQ_STATE_ACQUIRING:
1177 	case SEQ_STATE_READ_ACQUIRED:
1178 	case SEQ_STATE_RELEASED:
1179 		/* broken lock sequence */
1180 		if (!ls->broken) {
1181 			ls->broken = 1;
1182 			bad_hist[BROKEN_CONTENDED]++;
1183 		}
1184 		list_del_init(&seq->list);
1185 		free(seq);
1186 		goto end;
1187 	default:
1188 		BUG_ON("Unknown state of lock sequence found!\n");
1189 		break;
1190 	}
1191 
1192 	if (seq->state != SEQ_STATE_CONTENDED) {
1193 		seq->state = SEQ_STATE_CONTENDED;
1194 		seq->prev_event_time = sample->time;
1195 		ls->nr_contended++;
1196 	}
1197 end:
1198 	return 0;
1199 }
1200 
1201 static int report_lock_contention_end_event(struct evsel *evsel,
1202 					    struct perf_sample *sample)
1203 {
1204 	struct lock_stat *ls;
1205 	struct thread_stat *ts;
1206 	struct lock_seq_stat *seq;
1207 	u64 contended_term;
1208 	u64 addr = evsel__intval(evsel, sample, "lock_addr");
1209 	u64 key;
1210 	int ret;
1211 
1212 	ret = get_key_by_aggr_mode(&key, addr, evsel, sample);
1213 	if (ret < 0)
1214 		return ret;
1215 
1216 	ls = lock_stat_find(key);
1217 	if (!ls)
1218 		return 0;
1219 
1220 	ts = thread_stat_find(sample->tid);
1221 	if (!ts)
1222 		return 0;
1223 
1224 	seq = get_seq(ts, addr);
1225 	if (!seq)
1226 		return -ENOMEM;
1227 
1228 	switch (seq->state) {
1229 	case SEQ_STATE_UNINITIALIZED:
1230 		goto end;
1231 	case SEQ_STATE_CONTENDED:
1232 		contended_term = sample->time - seq->prev_event_time;
1233 		ls->wait_time_total += contended_term;
1234 		if (contended_term < ls->wait_time_min)
1235 			ls->wait_time_min = contended_term;
1236 		if (ls->wait_time_max < contended_term)
1237 			ls->wait_time_max = contended_term;
1238 		break;
1239 	case SEQ_STATE_ACQUIRING:
1240 	case SEQ_STATE_ACQUIRED:
1241 	case SEQ_STATE_READ_ACQUIRED:
1242 	case SEQ_STATE_RELEASED:
1243 		/* broken lock sequence */
1244 		if (!ls->broken) {
1245 			ls->broken = 1;
1246 			bad_hist[BROKEN_ACQUIRED]++;
1247 		}
1248 		list_del_init(&seq->list);
1249 		free(seq);
1250 		goto end;
1251 	default:
1252 		BUG_ON("Unknown state of lock sequence found!\n");
1253 		break;
1254 	}
1255 
1256 	seq->state = SEQ_STATE_ACQUIRED;
1257 	ls->nr_acquired++;
1258 	ls->avg_wait_time = ls->wait_time_total/ls->nr_acquired;
1259 end:
1260 	return 0;
1261 }
1262 
1263 /* lock oriented handlers */
1264 /* TODO: handlers for CPU oriented, thread oriented */
1265 static struct trace_lock_handler report_lock_ops  = {
1266 	.acquire_event		= report_lock_acquire_event,
1267 	.acquired_event		= report_lock_acquired_event,
1268 	.contended_event	= report_lock_contended_event,
1269 	.release_event		= report_lock_release_event,
1270 	.contention_begin_event	= report_lock_contention_begin_event,
1271 	.contention_end_event	= report_lock_contention_end_event,
1272 };
1273 
1274 static struct trace_lock_handler contention_lock_ops  = {
1275 	.contention_begin_event	= report_lock_contention_begin_event,
1276 	.contention_end_event	= report_lock_contention_end_event,
1277 };
1278 
1279 
1280 static struct trace_lock_handler *trace_handler;
1281 
1282 static int evsel__process_lock_acquire(struct evsel *evsel, struct perf_sample *sample)
1283 {
1284 	if (trace_handler->acquire_event)
1285 		return trace_handler->acquire_event(evsel, sample);
1286 	return 0;
1287 }
1288 
1289 static int evsel__process_lock_acquired(struct evsel *evsel, struct perf_sample *sample)
1290 {
1291 	if (trace_handler->acquired_event)
1292 		return trace_handler->acquired_event(evsel, sample);
1293 	return 0;
1294 }
1295 
1296 static int evsel__process_lock_contended(struct evsel *evsel, struct perf_sample *sample)
1297 {
1298 	if (trace_handler->contended_event)
1299 		return trace_handler->contended_event(evsel, sample);
1300 	return 0;
1301 }
1302 
1303 static int evsel__process_lock_release(struct evsel *evsel, struct perf_sample *sample)
1304 {
1305 	if (trace_handler->release_event)
1306 		return trace_handler->release_event(evsel, sample);
1307 	return 0;
1308 }
1309 
1310 static int evsel__process_contention_begin(struct evsel *evsel, struct perf_sample *sample)
1311 {
1312 	if (trace_handler->contention_begin_event)
1313 		return trace_handler->contention_begin_event(evsel, sample);
1314 	return 0;
1315 }
1316 
1317 static int evsel__process_contention_end(struct evsel *evsel, struct perf_sample *sample)
1318 {
1319 	if (trace_handler->contention_end_event)
1320 		return trace_handler->contention_end_event(evsel, sample);
1321 	return 0;
1322 }
1323 
1324 static void print_bad_events(int bad, int total)
1325 {
1326 	/* Output for debug, this have to be removed */
1327 	int i;
1328 	int broken = 0;
1329 	const char *name[4] =
1330 		{ "acquire", "acquired", "contended", "release" };
1331 
1332 	for (i = 0; i < BROKEN_MAX; i++)
1333 		broken += bad_hist[i];
1334 
1335 	if (quiet || total == 0 || (broken == 0 && verbose <= 0))
1336 		return;
1337 
1338 	pr_info("\n=== output for debug ===\n\n");
1339 	pr_info("bad: %d, total: %d\n", bad, total);
1340 	pr_info("bad rate: %.2f %%\n", (double)bad / (double)total * 100);
1341 	pr_info("histogram of events caused bad sequence\n");
1342 	for (i = 0; i < BROKEN_MAX; i++)
1343 		pr_info(" %10s: %d\n", name[i], bad_hist[i]);
1344 }
1345 
1346 /* TODO: various way to print, coloring, nano or milli sec */
1347 static void print_result(void)
1348 {
1349 	struct lock_stat *st;
1350 	struct lock_key *key;
1351 	char cut_name[20];
1352 	int bad, total, printed;
1353 
1354 	if (!quiet) {
1355 		pr_info("%20s ", "Name");
1356 		list_for_each_entry(key, &lock_keys, list)
1357 			pr_info("%*s ", key->len, key->header);
1358 		pr_info("\n\n");
1359 	}
1360 
1361 	bad = total = printed = 0;
1362 	while ((st = pop_from_result())) {
1363 		total++;
1364 		if (st->broken)
1365 			bad++;
1366 		if (!st->nr_acquired)
1367 			continue;
1368 
1369 		bzero(cut_name, 20);
1370 
1371 		if (strlen(st->name) < 20) {
1372 			/* output raw name */
1373 			const char *name = st->name;
1374 
1375 			if (show_thread_stats) {
1376 				struct thread *t;
1377 
1378 				/* st->addr contains tid of thread */
1379 				t = perf_session__findnew(session, st->addr);
1380 				name = thread__comm_str(t);
1381 			}
1382 
1383 			pr_info("%20s ", name);
1384 		} else {
1385 			strncpy(cut_name, st->name, 16);
1386 			cut_name[16] = '.';
1387 			cut_name[17] = '.';
1388 			cut_name[18] = '.';
1389 			cut_name[19] = '\0';
1390 			/* cut off name for saving output style */
1391 			pr_info("%20s ", cut_name);
1392 		}
1393 
1394 		list_for_each_entry(key, &lock_keys, list) {
1395 			key->print(key, st);
1396 			pr_info(" ");
1397 		}
1398 		pr_info("\n");
1399 
1400 		if (++printed >= print_nr_entries)
1401 			break;
1402 	}
1403 
1404 	print_bad_events(bad, total);
1405 }
1406 
1407 static bool info_threads, info_map;
1408 
1409 static void dump_threads(void)
1410 {
1411 	struct thread_stat *st;
1412 	struct rb_node *node;
1413 	struct thread *t;
1414 
1415 	pr_info("%10s: comm\n", "Thread ID");
1416 
1417 	node = rb_first(&thread_stats);
1418 	while (node) {
1419 		st = container_of(node, struct thread_stat, rb);
1420 		t = perf_session__findnew(session, st->tid);
1421 		pr_info("%10d: %s\n", st->tid, thread__comm_str(t));
1422 		node = rb_next(node);
1423 		thread__put(t);
1424 	}
1425 }
1426 
1427 static int compare_maps(struct lock_stat *a, struct lock_stat *b)
1428 {
1429 	int ret;
1430 
1431 	if (a->name && b->name)
1432 		ret = strcmp(a->name, b->name);
1433 	else
1434 		ret = !!a->name - !!b->name;
1435 
1436 	if (!ret)
1437 		return a->addr < b->addr;
1438 	else
1439 		return ret < 0;
1440 }
1441 
1442 static void dump_map(void)
1443 {
1444 	unsigned int i;
1445 	struct lock_stat *st;
1446 
1447 	pr_info("Address of instance: name of class\n");
1448 	for (i = 0; i < LOCKHASH_SIZE; i++) {
1449 		hlist_for_each_entry(st, &lockhash_table[i], hash_entry) {
1450 			insert_to_result(st, compare_maps);
1451 		}
1452 	}
1453 
1454 	while ((st = pop_from_result()))
1455 		pr_info(" %#llx: %s\n", (unsigned long long)st->addr, st->name);
1456 }
1457 
1458 static int dump_info(void)
1459 {
1460 	int rc = 0;
1461 
1462 	if (info_threads)
1463 		dump_threads();
1464 	else if (info_map)
1465 		dump_map();
1466 	else {
1467 		rc = -1;
1468 		pr_err("Unknown type of information\n");
1469 	}
1470 
1471 	return rc;
1472 }
1473 
1474 static const struct evsel_str_handler lock_tracepoints[] = {
1475 	{ "lock:lock_acquire",	 evsel__process_lock_acquire,   }, /* CONFIG_LOCKDEP */
1476 	{ "lock:lock_acquired",	 evsel__process_lock_acquired,  }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
1477 	{ "lock:lock_contended", evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
1478 	{ "lock:lock_release",	 evsel__process_lock_release,   }, /* CONFIG_LOCKDEP */
1479 };
1480 
1481 static const struct evsel_str_handler contention_tracepoints[] = {
1482 	{ "lock:contention_begin", evsel__process_contention_begin, },
1483 	{ "lock:contention_end",   evsel__process_contention_end,   },
1484 };
1485 
1486 static int process_event_update(struct perf_tool *tool,
1487 				union perf_event *event,
1488 				struct evlist **pevlist)
1489 {
1490 	int ret;
1491 
1492 	ret = perf_event__process_event_update(tool, event, pevlist);
1493 	if (ret < 0)
1494 		return ret;
1495 
1496 	/* this can return -EEXIST since we call it for each evsel */
1497 	perf_session__set_tracepoints_handlers(session, lock_tracepoints);
1498 	perf_session__set_tracepoints_handlers(session, contention_tracepoints);
1499 	return 0;
1500 }
1501 
1502 typedef int (*tracepoint_handler)(struct evsel *evsel,
1503 				  struct perf_sample *sample);
1504 
1505 static int process_sample_event(struct perf_tool *tool __maybe_unused,
1506 				union perf_event *event,
1507 				struct perf_sample *sample,
1508 				struct evsel *evsel,
1509 				struct machine *machine)
1510 {
1511 	int err = 0;
1512 	struct thread *thread = machine__findnew_thread(machine, sample->pid,
1513 							sample->tid);
1514 
1515 	if (thread == NULL) {
1516 		pr_debug("problem processing %d event, skipping it.\n",
1517 			event->header.type);
1518 		return -1;
1519 	}
1520 
1521 	if (evsel->handler != NULL) {
1522 		tracepoint_handler f = evsel->handler;
1523 		err = f(evsel, sample);
1524 	}
1525 
1526 	thread__put(thread);
1527 
1528 	return err;
1529 }
1530 
1531 static void combine_result(void)
1532 {
1533 	unsigned int i;
1534 	struct lock_stat *st;
1535 
1536 	if (!combine_locks)
1537 		return;
1538 
1539 	for (i = 0; i < LOCKHASH_SIZE; i++) {
1540 		hlist_for_each_entry(st, &lockhash_table[i], hash_entry) {
1541 			combine_lock_stats(st);
1542 		}
1543 	}
1544 }
1545 
1546 static void sort_result(void)
1547 {
1548 	unsigned int i;
1549 	struct lock_stat *st;
1550 
1551 	for (i = 0; i < LOCKHASH_SIZE; i++) {
1552 		hlist_for_each_entry(st, &lockhash_table[i], hash_entry) {
1553 			insert_to_result(st, compare);
1554 		}
1555 	}
1556 }
1557 
1558 static const struct {
1559 	unsigned int flags;
1560 	const char *str;
1561 	const char *name;
1562 } lock_type_table[] = {
1563 	{ 0,				"semaphore",	"semaphore" },
1564 	{ LCB_F_SPIN,			"spinlock",	"spinlock" },
1565 	{ LCB_F_SPIN | LCB_F_READ,	"rwlock:R",	"rwlock" },
1566 	{ LCB_F_SPIN | LCB_F_WRITE,	"rwlock:W",	"rwlock" },
1567 	{ LCB_F_READ,			"rwsem:R",	"rwsem" },
1568 	{ LCB_F_WRITE,			"rwsem:W",	"rwsem" },
1569 	{ LCB_F_RT,			"rt-mutex",	"rt-mutex" },
1570 	{ LCB_F_RT | LCB_F_READ,	"rwlock-rt:R",	"rwlock-rt" },
1571 	{ LCB_F_RT | LCB_F_WRITE,	"rwlock-rt:W",	"rwlock-rt" },
1572 	{ LCB_F_PERCPU | LCB_F_READ,	"pcpu-sem:R",	"percpu-rwsem" },
1573 	{ LCB_F_PERCPU | LCB_F_WRITE,	"pcpu-sem:W",	"percpu-rwsem" },
1574 	{ LCB_F_MUTEX,			"mutex",	"mutex" },
1575 	{ LCB_F_MUTEX | LCB_F_SPIN,	"mutex",	"mutex" },
1576 	/* alias for get_type_flag() */
1577 	{ LCB_F_MUTEX | LCB_F_SPIN,	"mutex-spin",	"mutex" },
1578 };
1579 
1580 static const char *get_type_str(unsigned int flags)
1581 {
1582 	flags &= LCB_F_MAX_FLAGS - 1;
1583 
1584 	for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) {
1585 		if (lock_type_table[i].flags == flags)
1586 			return lock_type_table[i].str;
1587 	}
1588 	return "unknown";
1589 }
1590 
1591 static const char *get_type_name(unsigned int flags)
1592 {
1593 	flags &= LCB_F_MAX_FLAGS - 1;
1594 
1595 	for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) {
1596 		if (lock_type_table[i].flags == flags)
1597 			return lock_type_table[i].name;
1598 	}
1599 	return "unknown";
1600 }
1601 
1602 static unsigned int get_type_flag(const char *str)
1603 {
1604 	for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) {
1605 		if (!strcmp(lock_type_table[i].name, str))
1606 			return lock_type_table[i].flags;
1607 	}
1608 	for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) {
1609 		if (!strcmp(lock_type_table[i].str, str))
1610 			return lock_type_table[i].flags;
1611 	}
1612 	return UINT_MAX;
1613 }
1614 
1615 static void lock_filter_finish(void)
1616 {
1617 	zfree(&filters.types);
1618 	filters.nr_types = 0;
1619 
1620 	zfree(&filters.addrs);
1621 	filters.nr_addrs = 0;
1622 
1623 	for (int i = 0; i < filters.nr_syms; i++)
1624 		free(filters.syms[i]);
1625 
1626 	zfree(&filters.syms);
1627 	filters.nr_syms = 0;
1628 }
1629 
1630 static void sort_contention_result(void)
1631 {
1632 	sort_result();
1633 }
1634 
1635 static void print_header_stdio(void)
1636 {
1637 	struct lock_key *key;
1638 
1639 	list_for_each_entry(key, &lock_keys, list)
1640 		pr_info("%*s ", key->len, key->header);
1641 
1642 	switch (aggr_mode) {
1643 	case LOCK_AGGR_TASK:
1644 		pr_info("  %10s   %s\n\n", "pid",
1645 			show_lock_owner ? "owner" : "comm");
1646 		break;
1647 	case LOCK_AGGR_CALLER:
1648 		pr_info("  %10s   %s\n\n", "type", "caller");
1649 		break;
1650 	case LOCK_AGGR_ADDR:
1651 		pr_info("  %16s   %s\n\n", "address", "symbol");
1652 		break;
1653 	default:
1654 		break;
1655 	}
1656 }
1657 
1658 static void print_header_csv(const char *sep)
1659 {
1660 	struct lock_key *key;
1661 
1662 	pr_info("# output: ");
1663 	list_for_each_entry(key, &lock_keys, list)
1664 		pr_info("%s%s ", key->header, sep);
1665 
1666 	switch (aggr_mode) {
1667 	case LOCK_AGGR_TASK:
1668 		pr_info("%s%s %s\n", "pid", sep,
1669 			show_lock_owner ? "owner" : "comm");
1670 		break;
1671 	case LOCK_AGGR_CALLER:
1672 		pr_info("%s%s %s", "type", sep, "caller");
1673 		if (verbose > 0)
1674 			pr_info("%s %s", sep, "stacktrace");
1675 		pr_info("\n");
1676 		break;
1677 	case LOCK_AGGR_ADDR:
1678 		pr_info("%s%s %s%s %s\n", "address", sep, "symbol", sep, "type");
1679 		break;
1680 	default:
1681 		break;
1682 	}
1683 }
1684 
1685 static void print_header(void)
1686 {
1687 	if (!quiet) {
1688 		if (symbol_conf.field_sep)
1689 			print_header_csv(symbol_conf.field_sep);
1690 		else
1691 			print_header_stdio();
1692 	}
1693 }
1694 
1695 static void print_lock_stat_stdio(struct lock_contention *con, struct lock_stat *st)
1696 {
1697 	struct lock_key *key;
1698 	struct thread *t;
1699 	int pid;
1700 
1701 	list_for_each_entry(key, &lock_keys, list) {
1702 		key->print(key, st);
1703 		pr_info(" ");
1704 	}
1705 
1706 	switch (aggr_mode) {
1707 	case LOCK_AGGR_CALLER:
1708 		pr_info("  %10s   %s\n", get_type_str(st->flags), st->name);
1709 		break;
1710 	case LOCK_AGGR_TASK:
1711 		pid = st->addr;
1712 		t = perf_session__findnew(session, pid);
1713 		pr_info("  %10d   %s\n",
1714 			pid, pid == -1 ? "Unknown" : thread__comm_str(t));
1715 		break;
1716 	case LOCK_AGGR_ADDR:
1717 		pr_info("  %016llx   %s (%s)\n", (unsigned long long)st->addr,
1718 			st->name, get_type_name(st->flags));
1719 		break;
1720 	default:
1721 		break;
1722 	}
1723 
1724 	if (aggr_mode == LOCK_AGGR_CALLER && verbose > 0) {
1725 		struct map *kmap;
1726 		struct symbol *sym;
1727 		char buf[128];
1728 		u64 ip;
1729 
1730 		for (int i = 0; i < max_stack_depth; i++) {
1731 			if (!st->callstack || !st->callstack[i])
1732 				break;
1733 
1734 			ip = st->callstack[i];
1735 			sym = machine__find_kernel_symbol(con->machine, ip, &kmap);
1736 			get_symbol_name_offset(kmap, sym, ip, buf, sizeof(buf));
1737 			pr_info("\t\t\t%#lx  %s\n", (unsigned long)ip, buf);
1738 		}
1739 	}
1740 }
1741 
1742 static void print_lock_stat_csv(struct lock_contention *con, struct lock_stat *st,
1743 				const char *sep)
1744 {
1745 	struct lock_key *key;
1746 	struct thread *t;
1747 	int pid;
1748 
1749 	list_for_each_entry(key, &lock_keys, list) {
1750 		key->print(key, st);
1751 		pr_info("%s ", sep);
1752 	}
1753 
1754 	switch (aggr_mode) {
1755 	case LOCK_AGGR_CALLER:
1756 		pr_info("%s%s %s", get_type_str(st->flags), sep, st->name);
1757 		if (verbose <= 0)
1758 			pr_info("\n");
1759 		break;
1760 	case LOCK_AGGR_TASK:
1761 		pid = st->addr;
1762 		t = perf_session__findnew(session, pid);
1763 		pr_info("%d%s %s\n", pid, sep, pid == -1 ? "Unknown" : thread__comm_str(t));
1764 		break;
1765 	case LOCK_AGGR_ADDR:
1766 		pr_info("%llx%s %s%s %s\n", (unsigned long long)st->addr, sep,
1767 			st->name, sep, get_type_name(st->flags));
1768 		break;
1769 	default:
1770 		break;
1771 	}
1772 
1773 	if (aggr_mode == LOCK_AGGR_CALLER && verbose > 0) {
1774 		struct map *kmap;
1775 		struct symbol *sym;
1776 		char buf[128];
1777 		u64 ip;
1778 
1779 		for (int i = 0; i < max_stack_depth; i++) {
1780 			if (!st->callstack || !st->callstack[i])
1781 				break;
1782 
1783 			ip = st->callstack[i];
1784 			sym = machine__find_kernel_symbol(con->machine, ip, &kmap);
1785 			get_symbol_name_offset(kmap, sym, ip, buf, sizeof(buf));
1786 			pr_info("%s %#lx %s", i ? ":" : sep, (unsigned long) ip, buf);
1787 		}
1788 		pr_info("\n");
1789 	}
1790 }
1791 
1792 static void print_lock_stat(struct lock_contention *con, struct lock_stat *st)
1793 {
1794 	if (symbol_conf.field_sep)
1795 		print_lock_stat_csv(con, st, symbol_conf.field_sep);
1796 	else
1797 		print_lock_stat_stdio(con, st);
1798 }
1799 
1800 static void print_footer_stdio(int total, int bad, struct lock_contention_fails *fails)
1801 {
1802 	/* Output for debug, this have to be removed */
1803 	int broken = fails->task + fails->stack + fails->time + fails->data;
1804 
1805 	if (!use_bpf)
1806 		print_bad_events(bad, total);
1807 
1808 	if (quiet || total == 0 || (broken == 0 && verbose <= 0))
1809 		return;
1810 
1811 	total += broken;
1812 	pr_info("\n=== output for debug ===\n\n");
1813 	pr_info("bad: %d, total: %d\n", broken, total);
1814 	pr_info("bad rate: %.2f %%\n", (double)broken / (double)total * 100);
1815 
1816 	pr_info("histogram of failure reasons\n");
1817 	pr_info(" %10s: %d\n", "task", fails->task);
1818 	pr_info(" %10s: %d\n", "stack", fails->stack);
1819 	pr_info(" %10s: %d\n", "time", fails->time);
1820 	pr_info(" %10s: %d\n", "data", fails->data);
1821 }
1822 
1823 static void print_footer_csv(int total, int bad, struct lock_contention_fails *fails,
1824 			     const char *sep)
1825 {
1826 	/* Output for debug, this have to be removed */
1827 	if (use_bpf)
1828 		bad = fails->task + fails->stack + fails->time + fails->data;
1829 
1830 	if (quiet || total == 0 || (bad == 0 && verbose <= 0))
1831 		return;
1832 
1833 	total += bad;
1834 	pr_info("# debug: total=%d%s bad=%d", total, sep, bad);
1835 
1836 	if (use_bpf) {
1837 		pr_info("%s bad_%s=%d", sep, "task", fails->task);
1838 		pr_info("%s bad_%s=%d", sep, "stack", fails->stack);
1839 		pr_info("%s bad_%s=%d", sep, "time", fails->time);
1840 		pr_info("%s bad_%s=%d", sep, "data", fails->data);
1841 	} else {
1842 		int i;
1843 		const char *name[4] = { "acquire", "acquired", "contended", "release" };
1844 
1845 		for (i = 0; i < BROKEN_MAX; i++)
1846 			pr_info("%s bad_%s=%d", sep, name[i], bad_hist[i]);
1847 	}
1848 	pr_info("\n");
1849 }
1850 
1851 static void print_footer(int total, int bad, struct lock_contention_fails *fails)
1852 {
1853 	if (symbol_conf.field_sep)
1854 		print_footer_csv(total, bad, fails, symbol_conf.field_sep);
1855 	else
1856 		print_footer_stdio(total, bad, fails);
1857 }
1858 
1859 static void print_contention_result(struct lock_contention *con)
1860 {
1861 	struct lock_stat *st;
1862 	int bad, total, printed;
1863 
1864 	if (!quiet)
1865 		print_header();
1866 
1867 	bad = total = printed = 0;
1868 
1869 	while ((st = pop_from_result())) {
1870 		total += use_bpf ? st->nr_contended : 1;
1871 		if (st->broken)
1872 			bad++;
1873 
1874 		if (!st->wait_time_total)
1875 			continue;
1876 
1877 		print_lock_stat(con, st);
1878 
1879 		if (++printed >= print_nr_entries)
1880 			break;
1881 	}
1882 
1883 	if (print_nr_entries) {
1884 		/* update the total/bad stats */
1885 		while ((st = pop_from_result())) {
1886 			total += use_bpf ? st->nr_contended : 1;
1887 			if (st->broken)
1888 				bad++;
1889 		}
1890 	}
1891 	/* some entries are collected but hidden by the callstack filter */
1892 	total += con->nr_filtered;
1893 
1894 	print_footer(total, bad, &con->fails);
1895 }
1896 
1897 static bool force;
1898 
1899 static int __cmd_report(bool display_info)
1900 {
1901 	int err = -EINVAL;
1902 	struct perf_tool eops = {
1903 		.attr		 = perf_event__process_attr,
1904 		.event_update	 = process_event_update,
1905 		.sample		 = process_sample_event,
1906 		.comm		 = perf_event__process_comm,
1907 		.mmap		 = perf_event__process_mmap,
1908 		.namespaces	 = perf_event__process_namespaces,
1909 		.tracing_data	 = perf_event__process_tracing_data,
1910 		.ordered_events	 = true,
1911 	};
1912 	struct perf_data data = {
1913 		.path  = input_name,
1914 		.mode  = PERF_DATA_MODE_READ,
1915 		.force = force,
1916 	};
1917 
1918 	session = perf_session__new(&data, &eops);
1919 	if (IS_ERR(session)) {
1920 		pr_err("Initializing perf session failed\n");
1921 		return PTR_ERR(session);
1922 	}
1923 
1924 	symbol_conf.allow_aliases = true;
1925 	symbol__init(&session->header.env);
1926 
1927 	if (!data.is_pipe) {
1928 		if (!perf_session__has_traces(session, "lock record"))
1929 			goto out_delete;
1930 
1931 		if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) {
1932 			pr_err("Initializing perf session tracepoint handlers failed\n");
1933 			goto out_delete;
1934 		}
1935 
1936 		if (perf_session__set_tracepoints_handlers(session, contention_tracepoints)) {
1937 			pr_err("Initializing perf session tracepoint handlers failed\n");
1938 			goto out_delete;
1939 		}
1940 	}
1941 
1942 	if (setup_output_field(false, output_fields))
1943 		goto out_delete;
1944 
1945 	if (select_key(false))
1946 		goto out_delete;
1947 
1948 	if (show_thread_stats)
1949 		aggr_mode = LOCK_AGGR_TASK;
1950 
1951 	err = perf_session__process_events(session);
1952 	if (err)
1953 		goto out_delete;
1954 
1955 	setup_pager();
1956 	if (display_info) /* used for info subcommand */
1957 		err = dump_info();
1958 	else {
1959 		combine_result();
1960 		sort_result();
1961 		print_result();
1962 	}
1963 
1964 out_delete:
1965 	perf_session__delete(session);
1966 	return err;
1967 }
1968 
1969 static void sighandler(int sig __maybe_unused)
1970 {
1971 }
1972 
1973 static int check_lock_contention_options(const struct option *options,
1974 					 const char * const *usage)
1975 
1976 {
1977 	if (show_thread_stats && show_lock_addrs) {
1978 		pr_err("Cannot use thread and addr mode together\n");
1979 		parse_options_usage(usage, options, "threads", 0);
1980 		parse_options_usage(NULL, options, "lock-addr", 0);
1981 		return -1;
1982 	}
1983 
1984 	if (show_lock_owner && !use_bpf) {
1985 		pr_err("Lock owners are available only with BPF\n");
1986 		parse_options_usage(usage, options, "lock-owner", 0);
1987 		parse_options_usage(NULL, options, "use-bpf", 0);
1988 		return -1;
1989 	}
1990 
1991 	if (show_lock_owner && show_lock_addrs) {
1992 		pr_err("Cannot use owner and addr mode together\n");
1993 		parse_options_usage(usage, options, "lock-owner", 0);
1994 		parse_options_usage(NULL, options, "lock-addr", 0);
1995 		return -1;
1996 	}
1997 
1998 	if (symbol_conf.field_sep) {
1999 		if (strstr(symbol_conf.field_sep, ":") || /* part of type flags */
2000 		    strstr(symbol_conf.field_sep, "+") || /* part of caller offset */
2001 		    strstr(symbol_conf.field_sep, ".")) { /* can be in a symbol name */
2002 			pr_err("Cannot use the separator that is already used\n");
2003 			parse_options_usage(usage, options, "x", 1);
2004 			return -1;
2005 		}
2006 	}
2007 
2008 	if (show_lock_owner)
2009 		show_thread_stats = true;
2010 
2011 	return 0;
2012 }
2013 
2014 static int __cmd_contention(int argc, const char **argv)
2015 {
2016 	int err = -EINVAL;
2017 	struct perf_tool eops = {
2018 		.attr		 = perf_event__process_attr,
2019 		.event_update	 = process_event_update,
2020 		.sample		 = process_sample_event,
2021 		.comm		 = perf_event__process_comm,
2022 		.mmap		 = perf_event__process_mmap,
2023 		.tracing_data	 = perf_event__process_tracing_data,
2024 		.ordered_events	 = true,
2025 	};
2026 	struct perf_data data = {
2027 		.path  = input_name,
2028 		.mode  = PERF_DATA_MODE_READ,
2029 		.force = force,
2030 	};
2031 	struct lock_contention con = {
2032 		.target = &target,
2033 		.map_nr_entries = bpf_map_entries,
2034 		.max_stack = max_stack_depth,
2035 		.stack_skip = stack_skip,
2036 		.filters = &filters,
2037 		.save_callstack = needs_callstack(),
2038 		.owner = show_lock_owner,
2039 	};
2040 
2041 	lockhash_table = calloc(LOCKHASH_SIZE, sizeof(*lockhash_table));
2042 	if (!lockhash_table)
2043 		return -ENOMEM;
2044 
2045 	con.result = &lockhash_table[0];
2046 
2047 	session = perf_session__new(use_bpf ? NULL : &data, &eops);
2048 	if (IS_ERR(session)) {
2049 		pr_err("Initializing perf session failed\n");
2050 		err = PTR_ERR(session);
2051 		goto out_delete;
2052 	}
2053 
2054 	con.machine = &session->machines.host;
2055 
2056 	con.aggr_mode = aggr_mode = show_thread_stats ? LOCK_AGGR_TASK :
2057 		show_lock_addrs ? LOCK_AGGR_ADDR : LOCK_AGGR_CALLER;
2058 
2059 	if (con.aggr_mode == LOCK_AGGR_CALLER)
2060 		con.save_callstack = true;
2061 
2062 	symbol_conf.allow_aliases = true;
2063 	symbol__init(&session->header.env);
2064 
2065 	if (use_bpf) {
2066 		err = target__validate(&target);
2067 		if (err) {
2068 			char errbuf[512];
2069 
2070 			target__strerror(&target, err, errbuf, 512);
2071 			pr_err("%s\n", errbuf);
2072 			goto out_delete;
2073 		}
2074 
2075 		signal(SIGINT, sighandler);
2076 		signal(SIGCHLD, sighandler);
2077 		signal(SIGTERM, sighandler);
2078 
2079 		con.evlist = evlist__new();
2080 		if (con.evlist == NULL) {
2081 			err = -ENOMEM;
2082 			goto out_delete;
2083 		}
2084 
2085 		err = evlist__create_maps(con.evlist, &target);
2086 		if (err < 0)
2087 			goto out_delete;
2088 
2089 		if (argc) {
2090 			err = evlist__prepare_workload(con.evlist, &target,
2091 						       argv, false, NULL);
2092 			if (err < 0)
2093 				goto out_delete;
2094 		}
2095 
2096 		if (lock_contention_prepare(&con) < 0) {
2097 			pr_err("lock contention BPF setup failed\n");
2098 			goto out_delete;
2099 		}
2100 	} else if (!data.is_pipe) {
2101 		if (!perf_session__has_traces(session, "lock record"))
2102 			goto out_delete;
2103 
2104 		if (!evlist__find_evsel_by_str(session->evlist,
2105 					       "lock:contention_begin")) {
2106 			pr_err("lock contention evsel not found\n");
2107 			goto out_delete;
2108 		}
2109 
2110 		if (perf_session__set_tracepoints_handlers(session,
2111 						contention_tracepoints)) {
2112 			pr_err("Initializing perf session tracepoint handlers failed\n");
2113 			goto out_delete;
2114 		}
2115 	}
2116 
2117 	if (setup_output_field(true, output_fields))
2118 		goto out_delete;
2119 
2120 	if (select_key(true))
2121 		goto out_delete;
2122 
2123 	if (symbol_conf.field_sep) {
2124 		int i;
2125 		struct lock_key *keys = contention_keys;
2126 
2127 		/* do not align output in CSV format */
2128 		for (i = 0; keys[i].name; i++)
2129 			keys[i].len = 0;
2130 	}
2131 
2132 	if (use_bpf) {
2133 		lock_contention_start();
2134 		if (argc)
2135 			evlist__start_workload(con.evlist);
2136 
2137 		/* wait for signal */
2138 		pause();
2139 
2140 		lock_contention_stop();
2141 		lock_contention_read(&con);
2142 	} else {
2143 		err = perf_session__process_events(session);
2144 		if (err)
2145 			goto out_delete;
2146 	}
2147 
2148 	setup_pager();
2149 
2150 	sort_contention_result();
2151 	print_contention_result(&con);
2152 
2153 out_delete:
2154 	lock_filter_finish();
2155 	evlist__delete(con.evlist);
2156 	lock_contention_finish();
2157 	perf_session__delete(session);
2158 	zfree(&lockhash_table);
2159 	return err;
2160 }
2161 
2162 
2163 static int __cmd_record(int argc, const char **argv)
2164 {
2165 	const char *record_args[] = {
2166 		"record", "-R", "-m", "1024", "-c", "1", "--synth", "task",
2167 	};
2168 	const char *callgraph_args[] = {
2169 		"--call-graph", "fp," __stringify(CONTENTION_STACK_DEPTH),
2170 	};
2171 	unsigned int rec_argc, i, j, ret;
2172 	unsigned int nr_tracepoints;
2173 	unsigned int nr_callgraph_args = 0;
2174 	const char **rec_argv;
2175 	bool has_lock_stat = true;
2176 
2177 	for (i = 0; i < ARRAY_SIZE(lock_tracepoints); i++) {
2178 		if (!is_valid_tracepoint(lock_tracepoints[i].name)) {
2179 			pr_debug("tracepoint %s is not enabled. "
2180 				 "Are CONFIG_LOCKDEP and CONFIG_LOCK_STAT enabled?\n",
2181 				 lock_tracepoints[i].name);
2182 			has_lock_stat = false;
2183 			break;
2184 		}
2185 	}
2186 
2187 	if (has_lock_stat)
2188 		goto setup_args;
2189 
2190 	for (i = 0; i < ARRAY_SIZE(contention_tracepoints); i++) {
2191 		if (!is_valid_tracepoint(contention_tracepoints[i].name)) {
2192 			pr_err("tracepoint %s is not enabled.\n",
2193 			       contention_tracepoints[i].name);
2194 			return 1;
2195 		}
2196 	}
2197 
2198 	nr_callgraph_args = ARRAY_SIZE(callgraph_args);
2199 
2200 setup_args:
2201 	rec_argc = ARRAY_SIZE(record_args) + nr_callgraph_args + argc - 1;
2202 
2203 	if (has_lock_stat)
2204 		nr_tracepoints = ARRAY_SIZE(lock_tracepoints);
2205 	else
2206 		nr_tracepoints = ARRAY_SIZE(contention_tracepoints);
2207 
2208 	/* factor of 2 is for -e in front of each tracepoint */
2209 	rec_argc += 2 * nr_tracepoints;
2210 
2211 	rec_argv = calloc(rec_argc + 1, sizeof(char *));
2212 	if (!rec_argv)
2213 		return -ENOMEM;
2214 
2215 	for (i = 0; i < ARRAY_SIZE(record_args); i++)
2216 		rec_argv[i] = strdup(record_args[i]);
2217 
2218 	for (j = 0; j < nr_tracepoints; j++) {
2219 		const char *ev_name;
2220 
2221 		if (has_lock_stat)
2222 			ev_name = strdup(lock_tracepoints[j].name);
2223 		else
2224 			ev_name = strdup(contention_tracepoints[j].name);
2225 
2226 		if (!ev_name)
2227 			return -ENOMEM;
2228 
2229 		rec_argv[i++] = "-e";
2230 		rec_argv[i++] = ev_name;
2231 	}
2232 
2233 	for (j = 0; j < nr_callgraph_args; j++, i++)
2234 		rec_argv[i] = callgraph_args[j];
2235 
2236 	for (j = 1; j < (unsigned int)argc; j++, i++)
2237 		rec_argv[i] = argv[j];
2238 
2239 	BUG_ON(i != rec_argc);
2240 
2241 	ret = cmd_record(i, rec_argv);
2242 	free(rec_argv);
2243 	return ret;
2244 }
2245 
2246 static int parse_map_entry(const struct option *opt, const char *str,
2247 			    int unset __maybe_unused)
2248 {
2249 	unsigned long *len = (unsigned long *)opt->value;
2250 	unsigned long val;
2251 	char *endptr;
2252 
2253 	errno = 0;
2254 	val = strtoul(str, &endptr, 0);
2255 	if (*endptr != '\0' || errno != 0) {
2256 		pr_err("invalid BPF map length: %s\n", str);
2257 		return -1;
2258 	}
2259 
2260 	*len = val;
2261 	return 0;
2262 }
2263 
2264 static int parse_max_stack(const struct option *opt, const char *str,
2265 			   int unset __maybe_unused)
2266 {
2267 	unsigned long *len = (unsigned long *)opt->value;
2268 	long val;
2269 	char *endptr;
2270 
2271 	errno = 0;
2272 	val = strtol(str, &endptr, 0);
2273 	if (*endptr != '\0' || errno != 0) {
2274 		pr_err("invalid max stack depth: %s\n", str);
2275 		return -1;
2276 	}
2277 
2278 	if (val < 0 || val > sysctl__max_stack()) {
2279 		pr_err("invalid max stack depth: %ld\n", val);
2280 		return -1;
2281 	}
2282 
2283 	*len = val;
2284 	return 0;
2285 }
2286 
2287 static bool add_lock_type(unsigned int flags)
2288 {
2289 	unsigned int *tmp;
2290 
2291 	tmp = realloc(filters.types, (filters.nr_types + 1) * sizeof(*filters.types));
2292 	if (tmp == NULL)
2293 		return false;
2294 
2295 	tmp[filters.nr_types++] = flags;
2296 	filters.types = tmp;
2297 	return true;
2298 }
2299 
2300 static int parse_lock_type(const struct option *opt __maybe_unused, const char *str,
2301 			   int unset __maybe_unused)
2302 {
2303 	char *s, *tmp, *tok;
2304 	int ret = 0;
2305 
2306 	s = strdup(str);
2307 	if (s == NULL)
2308 		return -1;
2309 
2310 	for (tok = strtok_r(s, ", ", &tmp); tok; tok = strtok_r(NULL, ", ", &tmp)) {
2311 		unsigned int flags = get_type_flag(tok);
2312 
2313 		if (flags == -1U) {
2314 			pr_err("Unknown lock flags: %s\n", tok);
2315 			ret = -1;
2316 			break;
2317 		}
2318 
2319 		if (!add_lock_type(flags)) {
2320 			ret = -1;
2321 			break;
2322 		}
2323 	}
2324 
2325 	free(s);
2326 	return ret;
2327 }
2328 
2329 static bool add_lock_addr(unsigned long addr)
2330 {
2331 	unsigned long *tmp;
2332 
2333 	tmp = realloc(filters.addrs, (filters.nr_addrs + 1) * sizeof(*filters.addrs));
2334 	if (tmp == NULL) {
2335 		pr_err("Memory allocation failure\n");
2336 		return false;
2337 	}
2338 
2339 	tmp[filters.nr_addrs++] = addr;
2340 	filters.addrs = tmp;
2341 	return true;
2342 }
2343 
2344 static bool add_lock_sym(char *name)
2345 {
2346 	char **tmp;
2347 	char *sym = strdup(name);
2348 
2349 	if (sym == NULL) {
2350 		pr_err("Memory allocation failure\n");
2351 		return false;
2352 	}
2353 
2354 	tmp = realloc(filters.syms, (filters.nr_syms + 1) * sizeof(*filters.syms));
2355 	if (tmp == NULL) {
2356 		pr_err("Memory allocation failure\n");
2357 		free(sym);
2358 		return false;
2359 	}
2360 
2361 	tmp[filters.nr_syms++] = sym;
2362 	filters.syms = tmp;
2363 	return true;
2364 }
2365 
2366 static int parse_lock_addr(const struct option *opt __maybe_unused, const char *str,
2367 			   int unset __maybe_unused)
2368 {
2369 	char *s, *tmp, *tok;
2370 	int ret = 0;
2371 	u64 addr;
2372 
2373 	s = strdup(str);
2374 	if (s == NULL)
2375 		return -1;
2376 
2377 	for (tok = strtok_r(s, ", ", &tmp); tok; tok = strtok_r(NULL, ", ", &tmp)) {
2378 		char *end;
2379 
2380 		addr = strtoul(tok, &end, 16);
2381 		if (*end == '\0') {
2382 			if (!add_lock_addr(addr)) {
2383 				ret = -1;
2384 				break;
2385 			}
2386 			continue;
2387 		}
2388 
2389 		/*
2390 		 * At this moment, we don't have kernel symbols.  Save the symbols
2391 		 * in a separate list and resolve them to addresses later.
2392 		 */
2393 		if (!add_lock_sym(tok)) {
2394 			ret = -1;
2395 			break;
2396 		}
2397 	}
2398 
2399 	free(s);
2400 	return ret;
2401 }
2402 
2403 static int parse_call_stack(const struct option *opt __maybe_unused, const char *str,
2404 			   int unset __maybe_unused)
2405 {
2406 	char *s, *tmp, *tok;
2407 	int ret = 0;
2408 
2409 	s = strdup(str);
2410 	if (s == NULL)
2411 		return -1;
2412 
2413 	for (tok = strtok_r(s, ", ", &tmp); tok; tok = strtok_r(NULL, ", ", &tmp)) {
2414 		struct callstack_filter *entry;
2415 
2416 		entry = malloc(sizeof(*entry) + strlen(tok) + 1);
2417 		if (entry == NULL) {
2418 			pr_err("Memory allocation failure\n");
2419 			return -1;
2420 		}
2421 
2422 		strcpy(entry->name, tok);
2423 		list_add_tail(&entry->list, &callstack_filters);
2424 	}
2425 
2426 	free(s);
2427 	return ret;
2428 }
2429 
2430 int cmd_lock(int argc, const char **argv)
2431 {
2432 	const struct option lock_options[] = {
2433 	OPT_STRING('i', "input", &input_name, "file", "input file name"),
2434 	OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
2435 	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"),
2436 	OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
2437 	OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
2438 		   "file", "vmlinux pathname"),
2439 	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
2440 		   "file", "kallsyms pathname"),
2441 	OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any warnings or messages"),
2442 	OPT_END()
2443 	};
2444 
2445 	const struct option info_options[] = {
2446 	OPT_BOOLEAN('t', "threads", &info_threads,
2447 		    "dump thread list in perf.data"),
2448 	OPT_BOOLEAN('m', "map", &info_map,
2449 		    "map of lock instances (address:name table)"),
2450 	OPT_PARENT(lock_options)
2451 	};
2452 
2453 	const struct option report_options[] = {
2454 	OPT_STRING('k', "key", &sort_key, "acquired",
2455 		    "key for sorting (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"),
2456 	OPT_STRING('F', "field", &output_fields, NULL,
2457 		    "output fields (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"),
2458 	/* TODO: type */
2459 	OPT_BOOLEAN('c', "combine-locks", &combine_locks,
2460 		    "combine locks in the same class"),
2461 	OPT_BOOLEAN('t', "threads", &show_thread_stats,
2462 		    "show per-thread lock stats"),
2463 	OPT_INTEGER('E', "entries", &print_nr_entries, "display this many functions"),
2464 	OPT_PARENT(lock_options)
2465 	};
2466 
2467 	struct option contention_options[] = {
2468 	OPT_STRING('k', "key", &sort_key, "wait_total",
2469 		    "key for sorting (contended / wait_total / wait_max / wait_min / avg_wait)"),
2470 	OPT_STRING('F', "field", &output_fields, "contended,wait_total,wait_max,avg_wait",
2471 		    "output fields (contended / wait_total / wait_max / wait_min / avg_wait)"),
2472 	OPT_BOOLEAN('t', "threads", &show_thread_stats,
2473 		    "show per-thread lock stats"),
2474 	OPT_BOOLEAN('b', "use-bpf", &use_bpf, "use BPF program to collect lock contention stats"),
2475 	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
2476 		    "System-wide collection from all CPUs"),
2477 	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
2478 		    "List of cpus to monitor"),
2479 	OPT_STRING('p', "pid", &target.pid, "pid",
2480 		   "Trace on existing process id"),
2481 	OPT_STRING(0, "tid", &target.tid, "tid",
2482 		   "Trace on existing thread id (exclusive to --pid)"),
2483 	OPT_CALLBACK('M', "map-nr-entries", &bpf_map_entries, "num",
2484 		     "Max number of BPF map entries", parse_map_entry),
2485 	OPT_CALLBACK(0, "max-stack", &max_stack_depth, "num",
2486 		     "Set the maximum stack depth when collecting lopck contention, "
2487 		     "Default: " __stringify(CONTENTION_STACK_DEPTH), parse_max_stack),
2488 	OPT_INTEGER(0, "stack-skip", &stack_skip,
2489 		    "Set the number of stack depth to skip when finding a lock caller, "
2490 		    "Default: " __stringify(CONTENTION_STACK_SKIP)),
2491 	OPT_INTEGER('E', "entries", &print_nr_entries, "display this many functions"),
2492 	OPT_BOOLEAN('l', "lock-addr", &show_lock_addrs, "show lock stats by address"),
2493 	OPT_CALLBACK('Y', "type-filter", NULL, "FLAGS",
2494 		     "Filter specific type of locks", parse_lock_type),
2495 	OPT_CALLBACK('L', "lock-filter", NULL, "ADDRS/NAMES",
2496 		     "Filter specific address/symbol of locks", parse_lock_addr),
2497 	OPT_CALLBACK('S', "callstack-filter", NULL, "NAMES",
2498 		     "Filter specific function in the callstack", parse_call_stack),
2499 	OPT_BOOLEAN('o', "lock-owner", &show_lock_owner, "show lock owners instead of waiters"),
2500 	OPT_STRING_NOEMPTY('x', "field-separator", &symbol_conf.field_sep, "separator",
2501 		   "print result in CSV format with custom separator"),
2502 	OPT_PARENT(lock_options)
2503 	};
2504 
2505 	const char * const info_usage[] = {
2506 		"perf lock info [<options>]",
2507 		NULL
2508 	};
2509 	const char *const lock_subcommands[] = { "record", "report", "script",
2510 						 "info", "contention", NULL };
2511 	const char *lock_usage[] = {
2512 		NULL,
2513 		NULL
2514 	};
2515 	const char * const report_usage[] = {
2516 		"perf lock report [<options>]",
2517 		NULL
2518 	};
2519 	const char * const contention_usage[] = {
2520 		"perf lock contention [<options>]",
2521 		NULL
2522 	};
2523 	unsigned int i;
2524 	int rc = 0;
2525 
2526 	lockhash_table = calloc(LOCKHASH_SIZE, sizeof(*lockhash_table));
2527 	if (!lockhash_table)
2528 		return -ENOMEM;
2529 
2530 	for (i = 0; i < LOCKHASH_SIZE; i++)
2531 		INIT_HLIST_HEAD(lockhash_table + i);
2532 
2533 	argc = parse_options_subcommand(argc, argv, lock_options, lock_subcommands,
2534 					lock_usage, PARSE_OPT_STOP_AT_NON_OPTION);
2535 	if (!argc)
2536 		usage_with_options(lock_usage, lock_options);
2537 
2538 	if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
2539 		return __cmd_record(argc, argv);
2540 	} else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
2541 		trace_handler = &report_lock_ops;
2542 		if (argc) {
2543 			argc = parse_options(argc, argv,
2544 					     report_options, report_usage, 0);
2545 			if (argc)
2546 				usage_with_options(report_usage, report_options);
2547 		}
2548 		rc = __cmd_report(false);
2549 	} else if (!strcmp(argv[0], "script")) {
2550 		/* Aliased to 'perf script' */
2551 		rc = cmd_script(argc, argv);
2552 	} else if (!strcmp(argv[0], "info")) {
2553 		if (argc) {
2554 			argc = parse_options(argc, argv,
2555 					     info_options, info_usage, 0);
2556 			if (argc)
2557 				usage_with_options(info_usage, info_options);
2558 		}
2559 		/* recycling report_lock_ops */
2560 		trace_handler = &report_lock_ops;
2561 		rc = __cmd_report(true);
2562 	} else if (strlen(argv[0]) > 2 && strstarts("contention", argv[0])) {
2563 		trace_handler = &contention_lock_ops;
2564 		sort_key = "wait_total";
2565 		output_fields = "contended,wait_total,wait_max,avg_wait";
2566 
2567 #ifndef HAVE_BPF_SKEL
2568 		set_option_nobuild(contention_options, 'b', "use-bpf",
2569 				   "no BUILD_BPF_SKEL=1", false);
2570 #endif
2571 		if (argc) {
2572 			argc = parse_options(argc, argv, contention_options,
2573 					     contention_usage, 0);
2574 		}
2575 
2576 		if (check_lock_contention_options(contention_options,
2577 						  contention_usage) < 0)
2578 			return -1;
2579 
2580 		rc = __cmd_contention(argc, argv);
2581 	} else {
2582 		usage_with_options(lock_usage, lock_options);
2583 	}
2584 
2585 	zfree(&lockhash_table);
2586 	return rc;
2587 }
2588