aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-lock.c
diff options
context:
space:
mode:
authorHitoshi Mitake <mitake@dcl.info.waseda.ac.jp>2010-05-03 01:12:00 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2010-05-09 07:45:24 -0400
commit26242d859c9be9eea61f7f19514e9d272ae8ce26 (patch)
treeb1a69c955ec3eb6be804a90beb17b0cafd95d3c0 /tools/perf/builtin-lock.c
parentd6b17bebd79dae2e3577f2ea27a832af4991a5e6 (diff)
perf lock: Add "info" subcommand for dumping misc information
This adds the "info" subcommand to perf lock which can be used to dump metadata like threads or addresses of lock instances. "map" was removed because info should do the work for it. This will be useful not only for debugging but also for ordinary analyzing. v2: adding example of usage % sudo ./perf lock info -t | Thread ID: comm | 0: swapper | 1: init | 18: migration/5 | 29: events/2 | 32: events/5 | 33: events/6 ... % sudo ./perf lock info -m | Address of instance: name of class | 0xffff8800b95adae0: &(&sighand->siglock)->rlock | 0xffff8800bbb41ae0: &(&sighand->siglock)->rlock | 0xffff8800bf165ae0: &(&sighand->siglock)->rlock | 0xffff8800b9576a98: &p->cred_guard_mutex | 0xffff8800bb890a08: &(&p->alloc_lock)->rlock | 0xffff8800b9522a08: &(&p->alloc_lock)->rlock | 0xffff8800bb8aaa08: &(&p->alloc_lock)->rlock | 0xffff8800bba72a08: &(&p->alloc_lock)->rlock | 0xffff8800bf18ea08: &(&p->alloc_lock)->rlock | 0xffff8800b8a0d8a0: &(&ip->i_lock)->mr_lock | 0xffff88009bf818a0: &(&ip->i_lock)->mr_lock | 0xffff88004c66b8a0: &(&ip->i_lock)->mr_lock | 0xffff8800bb6478a0: &(shost->host_lock)->rlock v3: fixed some problems Frederic pointed out * better rbtree tracking in dump_threads() * removed printf() and used pr_info() and pr_debug() Signed-off-by: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jens Axboe <jens.axboe@oracle.com> Cc: Jason Baron <jbaron@redhat.com> Cc: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> LKML-Reference: <1272863520-16179-1-git-send-email-mitake@dcl.info.waseda.ac.jp> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'tools/perf/builtin-lock.c')
-rw-r--r--tools/perf/builtin-lock.c96
1 files changed, 73 insertions, 23 deletions
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 6605000ed73d..c4eb854ff7eb 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -720,15 +720,15 @@ static void print_result(void)
720 char cut_name[20]; 720 char cut_name[20];
721 int bad, total; 721 int bad, total;
722 722
723 printf("%20s ", "Name"); 723 pr_info("%20s ", "Name");
724 printf("%10s ", "acquired"); 724 pr_info("%10s ", "acquired");
725 printf("%10s ", "contended"); 725 pr_info("%10s ", "contended");
726 726
727 printf("%15s ", "total wait (ns)"); 727 pr_info("%15s ", "total wait (ns)");
728 printf("%15s ", "max wait (ns)"); 728 pr_info("%15s ", "max wait (ns)");
729 printf("%15s ", "min wait (ns)"); 729 pr_info("%15s ", "min wait (ns)");
730 730
731 printf("\n\n"); 731 pr_info("\n\n");
732 732
733 bad = total = 0; 733 bad = total = 0;
734 while ((st = pop_from_result())) { 734 while ((st = pop_from_result())) {
@@ -741,7 +741,7 @@ static void print_result(void)
741 741
742 if (strlen(st->name) < 16) { 742 if (strlen(st->name) < 16) {
743 /* output raw name */ 743 /* output raw name */
744 printf("%20s ", st->name); 744 pr_info("%20s ", st->name);
745 } else { 745 } else {
746 strncpy(cut_name, st->name, 16); 746 strncpy(cut_name, st->name, 16);
747 cut_name[16] = '.'; 747 cut_name[16] = '.';
@@ -749,17 +749,17 @@ static void print_result(void)
749 cut_name[18] = '.'; 749 cut_name[18] = '.';
750 cut_name[19] = '\0'; 750 cut_name[19] = '\0';
751 /* cut off name for saving output style */ 751 /* cut off name for saving output style */
752 printf("%20s ", cut_name); 752 pr_info("%20s ", cut_name);
753 } 753 }
754 754
755 printf("%10u ", st->nr_acquired); 755 pr_info("%10u ", st->nr_acquired);
756 printf("%10u ", st->nr_contended); 756 pr_info("%10u ", st->nr_contended);
757 757
758 printf("%15llu ", st->wait_time_total); 758 pr_info("%15llu ", st->wait_time_total);
759 printf("%15llu ", st->wait_time_max); 759 pr_info("%15llu ", st->wait_time_max);
760 printf("%15llu ", st->wait_time_min == ULLONG_MAX ? 760 pr_info("%15llu ", st->wait_time_min == ULLONG_MAX ?
761 0 : st->wait_time_min); 761 0 : st->wait_time_min);
762 printf("\n"); 762 pr_info("\n");
763 } 763 }
764 764
765 { 765 {
@@ -768,28 +768,59 @@ static void print_result(void)
768 const char *name[4] = 768 const char *name[4] =
769 { "acquire", "acquired", "contended", "release" }; 769 { "acquire", "acquired", "contended", "release" };
770 770
771 printf("\n=== output for debug===\n\n"); 771 pr_debug("\n=== output for debug===\n\n");
772 printf("bad:%d, total:%d\n", bad, total); 772 pr_debug("bad:%d, total:%d\n", bad, total);
773 printf("bad rate:%f\n", (double)(bad / total)); 773 pr_debug("bad rate:%f\n", (double)(bad / total));
774 774
775 printf("histogram of events caused bad sequence\n"); 775 pr_debug("histogram of events caused bad sequence\n");
776 for (i = 0; i < 4; i++) 776 for (i = 0; i < 4; i++)
777 printf(" %10s: %d\n", name[i], bad_hist[i]); 777 pr_debug(" %10s: %d\n", name[i], bad_hist[i]);
778 } 778 }
779} 779}
780 780
781static int info_threads;
782static int info_map;
783
784static void dump_threads(void)
785{
786 struct thread_stat *st;
787 struct rb_node *node;
788 struct thread *t;
789
790 pr_info("%10s: comm\n", "Thread ID");
791
792 node = rb_first(&thread_stats);
793 while (node) {
794 st = container_of(node, struct thread_stat, rb);
795 t = perf_session__findnew(session, st->tid);
796 pr_info("%10d: %s\n", st->tid, t->comm);
797 node = rb_next(node);
798 };
799}
800
781static void dump_map(void) 801static void dump_map(void)
782{ 802{
783 unsigned int i; 803 unsigned int i;
784 struct lock_stat *st; 804 struct lock_stat *st;
785 805
806 pr_info("Address of instance: name of class\n");
786 for (i = 0; i < LOCKHASH_SIZE; i++) { 807 for (i = 0; i < LOCKHASH_SIZE; i++) {
787 list_for_each_entry(st, &lockhash_table[i], hash_entry) { 808 list_for_each_entry(st, &lockhash_table[i], hash_entry) {
788 printf("%p: %s\n", st->addr, st->name); 809 pr_info(" %p: %s\n", st->addr, st->name);
789 } 810 }
790 } 811 }
791} 812}
792 813
814static void dump_info(void)
815{
816 if (info_threads)
817 dump_threads();
818 else if (info_map)
819 dump_map();
820 else
821 die("Unknown type of information\n");
822}
823
793static int process_sample_event(event_t *self, struct perf_session *s) 824static int process_sample_event(event_t *self, struct perf_session *s)
794{ 825{
795 struct sample_data data; 826 struct sample_data data;
@@ -858,6 +889,19 @@ static const struct option report_options[] = {
858 OPT_END() 889 OPT_END()
859}; 890};
860 891
892static const char * const info_usage[] = {
893 "perf lock info [<options>]",
894 NULL
895};
896
897static const struct option info_options[] = {
898 OPT_BOOLEAN('t', "threads", &info_threads,
899 "dump thread list in perf.data"),
900 OPT_BOOLEAN('m', "map", &info_map,
901 "map of lock instances (name:address table)"),
902 OPT_END()
903};
904
861static const char * const lock_usage[] = { 905static const char * const lock_usage[] = {
862 "perf lock [<options>] {record|trace|report}", 906 "perf lock [<options>] {record|trace|report}",
863 NULL 907 NULL
@@ -929,12 +973,18 @@ int cmd_lock(int argc, const char **argv, const char *prefix __used)
929 } else if (!strcmp(argv[0], "trace")) { 973 } else if (!strcmp(argv[0], "trace")) {
930 /* Aliased to 'perf trace' */ 974 /* Aliased to 'perf trace' */
931 return cmd_trace(argc, argv, prefix); 975 return cmd_trace(argc, argv, prefix);
932 } else if (!strcmp(argv[0], "map")) { 976 } else if (!strcmp(argv[0], "info")) {
977 if (argc) {
978 argc = parse_options(argc, argv,
979 info_options, info_usage, 0);
980 if (argc)
981 usage_with_options(info_usage, info_options);
982 }
933 /* recycling report_lock_ops */ 983 /* recycling report_lock_ops */
934 trace_handler = &report_lock_ops; 984 trace_handler = &report_lock_ops;
935 setup_pager(); 985 setup_pager();
936 read_events(); 986 read_events();
937 dump_map(); 987 dump_info();
938 } else { 988 } else {
939 usage_with_options(lock_usage, lock_options); 989 usage_with_options(lock_usage, lock_options);
940 } 990 }