1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 #ifndef PERF_LOCK_CONTENTION_H 2 #ifndef PERF_LOCK_CONTENTION_H 3 #define PERF_LOCK_CONTENTION_H 3 #define PERF_LOCK_CONTENTION_H 4 4 5 #include <linux/list.h> 5 #include <linux/list.h> 6 #include <linux/rbtree.h> 6 #include <linux/rbtree.h> 7 7 8 struct lock_filter { 8 struct lock_filter { 9 int nr_types; 9 int nr_types; 10 int nr_addrs; 10 int nr_addrs; 11 int nr_syms; 11 int nr_syms; 12 int nr_cgrps; 12 int nr_cgrps; 13 unsigned int *types; 13 unsigned int *types; 14 unsigned long *addrs; 14 unsigned long *addrs; 15 char **syms; 15 char **syms; 16 u64 *cgrps; 16 u64 *cgrps; 17 }; 17 }; 18 18 19 struct lock_stat { 19 struct lock_stat { 20 struct hlist_node hash_entry; 20 struct hlist_node hash_entry; 21 struct rb_node rb; 21 struct rb_node rb; /* used for sorting */ 22 22 23 u64 addr; 23 u64 addr; /* address of lockdep_map, used as ID */ 24 char *name; 24 char *name; /* for strcpy(), we cannot use const */ 25 u64 *callstack; 25 u64 *callstack; 26 26 27 unsigned int nr_acquire; 27 unsigned int nr_acquire; 28 unsigned int nr_acquired; 28 unsigned int nr_acquired; 29 unsigned int nr_contended; 29 unsigned int nr_contended; 30 unsigned int nr_release; 30 unsigned int nr_release; 31 31 32 union { 32 union { 33 unsigned int nr_readlock; 33 unsigned int nr_readlock; 34 unsigned int flags; 34 unsigned int flags; 35 }; 35 }; 36 unsigned int nr_trylock; 36 unsigned int nr_trylock; 37 37 38 /* these times are in nano sec. */ 38 /* these times are in nano sec. */ 39 u64 avg_wait_time; 39 u64 avg_wait_time; 40 u64 wait_time_tota 40 u64 wait_time_total; 41 u64 wait_time_min; 41 u64 wait_time_min; 42 u64 wait_time_max; 42 u64 wait_time_max; 43 43 44 int broken; /* fla 44 int broken; /* flag of blacklist */ 45 int combined; 45 int combined; 46 }; 46 }; 47 47 48 /* 48 /* 49 * States of lock_seq_stat 49 * States of lock_seq_stat 50 * 50 * 51 * UNINITIALIZED is required for detecting fir 51 * UNINITIALIZED is required for detecting first event of acquire. 52 * As the nature of lock events, there is no g 52 * As the nature of lock events, there is no guarantee 53 * that the first event for the locks are acqu 53 * that the first event for the locks are acquire, 54 * it can be acquired, contended or release. 54 * it can be acquired, contended or release. 55 */ 55 */ 56 #define SEQ_STATE_UNINITIALIZED 0 56 #define SEQ_STATE_UNINITIALIZED 0 /* initial state */ 57 #define SEQ_STATE_RELEASED 1 57 #define SEQ_STATE_RELEASED 1 58 #define SEQ_STATE_ACQUIRING 2 58 #define SEQ_STATE_ACQUIRING 2 59 #define SEQ_STATE_ACQUIRED 3 59 #define SEQ_STATE_ACQUIRED 3 60 #define SEQ_STATE_READ_ACQUIRED 4 60 #define SEQ_STATE_READ_ACQUIRED 4 61 #define SEQ_STATE_CONTENDED 5 61 #define SEQ_STATE_CONTENDED 5 62 62 63 /* 63 /* 64 * MAX_LOCK_DEPTH 64 * MAX_LOCK_DEPTH 65 * Imported from include/linux/sched.h. 65 * Imported from include/linux/sched.h. 66 * Should this be synchronized? 66 * Should this be synchronized? 67 */ 67 */ 68 #define MAX_LOCK_DEPTH 48 68 #define MAX_LOCK_DEPTH 48 69 69 70 struct lock_stat *lock_stat_find(u64 addr); 70 struct lock_stat *lock_stat_find(u64 addr); 71 struct lock_stat *lock_stat_findnew(u64 addr, 71 struct lock_stat *lock_stat_findnew(u64 addr, const char *name, int flags); 72 72 73 bool match_callstack_filter(struct machine *ma 73 bool match_callstack_filter(struct machine *machine, u64 *callstack); 74 74 75 /* 75 /* 76 * struct lock_seq_stat: 76 * struct lock_seq_stat: 77 * Place to put on state of one lock sequence 77 * Place to put on state of one lock sequence 78 * 1) acquire -> acquired -> release 78 * 1) acquire -> acquired -> release 79 * 2) acquire -> contended -> acquired -> rele 79 * 2) acquire -> contended -> acquired -> release 80 * 3) acquire (with read or try) -> release 80 * 3) acquire (with read or try) -> release 81 * 4) Are there other patterns? 81 * 4) Are there other patterns? 82 */ 82 */ 83 struct lock_seq_stat { 83 struct lock_seq_stat { 84 struct list_head list; 84 struct list_head list; 85 int state; 85 int state; 86 u64 prev_event_tim 86 u64 prev_event_time; 87 u64 addr; 87 u64 addr; 88 88 89 int read_count; 89 int read_count; 90 }; 90 }; 91 91 92 struct thread_stat { 92 struct thread_stat { 93 struct rb_node rb; 93 struct rb_node rb; 94 94 95 u32 tid; 95 u32 tid; 96 struct list_head seq_list; 96 struct list_head seq_list; 97 }; 97 }; 98 98 99 /* 99 /* 100 * CONTENTION_STACK_DEPTH 100 * CONTENTION_STACK_DEPTH 101 * Number of stack trace entries to find calle 101 * Number of stack trace entries to find callers 102 */ 102 */ 103 #define CONTENTION_STACK_DEPTH 8 103 #define CONTENTION_STACK_DEPTH 8 104 104 105 /* 105 /* 106 * CONTENTION_STACK_SKIP 106 * CONTENTION_STACK_SKIP 107 * Number of stack trace entries to skip when 107 * Number of stack trace entries to skip when finding callers. 108 * The first few entries belong to the locking 108 * The first few entries belong to the locking implementation itself. 109 */ 109 */ 110 #define CONTENTION_STACK_SKIP 4 110 #define CONTENTION_STACK_SKIP 4 111 111 112 /* 112 /* 113 * flags for lock:contention_begin 113 * flags for lock:contention_begin 114 * Imported from include/trace/events/lock.h. 114 * Imported from include/trace/events/lock.h. 115 */ 115 */ 116 #define LCB_F_SPIN (1U << 0) 116 #define LCB_F_SPIN (1U << 0) 117 #define LCB_F_READ (1U << 1) 117 #define LCB_F_READ (1U << 1) 118 #define LCB_F_WRITE (1U << 2) 118 #define LCB_F_WRITE (1U << 2) 119 #define LCB_F_RT (1U << 3) 119 #define LCB_F_RT (1U << 3) 120 #define LCB_F_PERCPU (1U << 4) 120 #define LCB_F_PERCPU (1U << 4) 121 #define LCB_F_MUTEX (1U << 5) 121 #define LCB_F_MUTEX (1U << 5) 122 122 123 struct evlist; 123 struct evlist; 124 struct machine; 124 struct machine; 125 struct target; 125 struct target; 126 126 127 struct lock_contention_fails { 127 struct lock_contention_fails { 128 int task; 128 int task; 129 int stack; 129 int stack; 130 int time; 130 int time; 131 int data; 131 int data; 132 }; 132 }; 133 133 134 struct lock_contention { 134 struct lock_contention { 135 struct evlist *evlist; 135 struct evlist *evlist; 136 struct target *target; 136 struct target *target; 137 struct machine *machine; 137 struct machine *machine; 138 struct hlist_head *result; 138 struct hlist_head *result; 139 struct lock_filter *filters; 139 struct lock_filter *filters; 140 struct lock_contention_fails fails; 140 struct lock_contention_fails fails; 141 struct rb_root cgroups; 141 struct rb_root cgroups; 142 unsigned long map_nr_entries; 142 unsigned long map_nr_entries; 143 int max_stack; 143 int max_stack; 144 int stack_skip; 144 int stack_skip; 145 int aggr_mode; 145 int aggr_mode; 146 int owner; 146 int owner; 147 int nr_filtered; 147 int nr_filtered; 148 bool save_callstack; 148 bool save_callstack; 149 }; 149 }; 150 150 151 #ifdef HAVE_BPF_SKEL 151 #ifdef HAVE_BPF_SKEL 152 152 153 int lock_contention_prepare(struct lock_conten 153 int lock_contention_prepare(struct lock_contention *con); 154 int lock_contention_start(void); 154 int lock_contention_start(void); 155 int lock_contention_stop(void); 155 int lock_contention_stop(void); 156 int lock_contention_read(struct lock_contentio 156 int lock_contention_read(struct lock_contention *con); 157 int lock_contention_finish(struct lock_content 157 int lock_contention_finish(struct lock_contention *con); 158 158 159 #else /* !HAVE_BPF_SKEL */ 159 #else /* !HAVE_BPF_SKEL */ 160 160 161 static inline int lock_contention_prepare(stru 161 static inline int lock_contention_prepare(struct lock_contention *con __maybe_unused) 162 { 162 { 163 return 0; 163 return 0; 164 } 164 } 165 165 166 static inline int lock_contention_start(void) 166 static inline int lock_contention_start(void) { return 0; } 167 static inline int lock_contention_stop(void) { 167 static inline int lock_contention_stop(void) { return 0; } 168 static inline int lock_contention_finish(struc 168 static inline int lock_contention_finish(struct lock_contention *con __maybe_unused) 169 { 169 { 170 return 0; 170 return 0; 171 } 171 } 172 172 173 static inline int lock_contention_read(struct 173 static inline int lock_contention_read(struct lock_contention *con __maybe_unused) 174 { 174 { 175 return 0; 175 return 0; 176 } 176 } 177 177 178 #endif /* HAVE_BPF_SKEL */ 178 #endif /* HAVE_BPF_SKEL */ 179 179 180 #endif /* PERF_LOCK_CONTENTION_H */ 180 #endif /* PERF_LOCK_CONTENTION_H */ 181 181
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.