[2/4] perf lock contention: Track and show siglock with address

Message ID 20230313204825.2665483-3-namhyung@kernel.org
State New
Headers
Series perf lock contention: Improve lock symbol display (v1) |

Commit Message

Namhyung Kim March 13, 2023, 8:48 p.m. UTC
  Likewise, we can display siglock by following the pointer like
current->sighand->siglock.

  $ sudo ./perf lock con -abl -- sleep 1
   contended   total wait     max wait     avg wait            address   symbol

          16      2.18 ms    305.35 us    136.34 us   ffffffff92e06080   tasklist_lock
          28    521.78 us     31.16 us     18.63 us   ffff8cc703783ec4
           7    119.03 us     23.55 us     17.00 us   ffff8ccb92479440
          15     88.29 us     10.06 us      5.89 us   ffff8cd560b5f380   siglock
           7     37.67 us      9.16 us      5.38 us   ffff8d053daf0c80
           5      8.81 us      4.92 us      1.76 us   ffff8d053d6b0c80

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/builtin-lock.c                      | 3 +--
 tools/perf/util/bpf_lock_contention.c          | 8 ++++++--
 tools/perf/util/bpf_skel/lock_contention.bpf.c | 5 +++++
 tools/perf/util/bpf_skel/lock_data.h           | 3 ++-
 4 files changed, 14 insertions(+), 5 deletions(-)
  

Patch

diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index c62f4d9363a6..c710a5d46638 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -1662,8 +1662,7 @@  static void print_contention_result(struct lock_contention *con)
 				pid, pid == -1 ? "Unknown" : thread__comm_str(t));
 			break;
 		case LOCK_AGGR_ADDR:
-			pr_info("  %016llx   %s\n", (unsigned long long)st->addr,
-				(st->flags & LCD_F_MMAP_LOCK) ? "mmap_lock" : st->name);
+			pr_info("  %016llx   %s\n", (unsigned long long)st->addr, st->name);
 			break;
 		default:
 			break;
diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c
index fadcacb9d501..51631af3b4d6 100644
--- a/tools/perf/util/bpf_lock_contention.c
+++ b/tools/perf/util/bpf_lock_contention.c
@@ -169,7 +169,7 @@  int lock_contention_stop(void)
 
 static const char *lock_contention_get_name(struct lock_contention *con,
 					    struct contention_key *key,
-					    u64 *stack_trace)
+					    u64 *stack_trace, u32 flags)
 {
 	int idx = 0;
 	u64 addr;
@@ -198,6 +198,10 @@  static const char *lock_contention_get_name(struct lock_contention *con,
 	}
 
 	if (con->aggr_mode == LOCK_AGGR_ADDR) {
+		if (flags & LCD_F_MMAP_LOCK)
+			return "mmap_lock";
+		if (flags & LCD_F_SIGHAND_LOCK)
+			return "siglock";
 		sym = machine__find_kernel_symbol(machine, key->lock_addr, &kmap);
 		if (sym)
 			name = sym->name;
@@ -301,7 +305,7 @@  int lock_contention_read(struct lock_contention *con)
 			goto next;
 		}
 
-		name = lock_contention_get_name(con, &key, stack_trace);
+		name = lock_contention_get_name(con, &key, stack_trace, data.flags);
 		st = lock_stat_findnew(ls_key, name, data.flags);
 		if (st == NULL)
 			break;
diff --git a/tools/perf/util/bpf_skel/lock_contention.bpf.c b/tools/perf/util/bpf_skel/lock_contention.bpf.c
index f092a78ae2b5..4ba34caf84eb 100644
--- a/tools/perf/util/bpf_skel/lock_contention.bpf.c
+++ b/tools/perf/util/bpf_skel/lock_contention.bpf.c
@@ -236,6 +236,11 @@  static inline __u32 check_lock_type(__u64 lock, __u32 flags)
 				return LCD_F_MMAP_LOCK;
 		}
 		break;
+	case LCB_F_SPIN:  /* spinlock */
+		curr = bpf_get_current_task_btf();
+		if (&curr->sighand->siglock == (void *)lock)
+			return LCD_F_SIGHAND_LOCK;
+		break;
 	default:
 		break;
 	}
diff --git a/tools/perf/util/bpf_skel/lock_data.h b/tools/perf/util/bpf_skel/lock_data.h
index 789f20833798..5ed1a0955015 100644
--- a/tools/perf/util/bpf_skel/lock_data.h
+++ b/tools/perf/util/bpf_skel/lock_data.h
@@ -19,7 +19,8 @@  struct contention_task_data {
  * Upper bits of the flags in the contention_data are used to identify
  * some well-known locks which do not have symbols (non-global locks).
  */
-#define LCD_F_MMAP_LOCK  (1U << 31)
+#define LCD_F_MMAP_LOCK		(1U << 31)
+#define LCD_F_SIGHAND_LOCK	(1U << 30)
 
 struct contention_data {
 	u64 total_time;