@@ -163,9 +163,70 @@ int lock_contention_stop(void)
163163 return 0 ;
164164}
165165
166+ static const char * lock_contention_get_name (struct lock_contention * con ,
167+ struct contention_key * key ,
168+ u64 * stack_trace )
169+ {
170+ int idx = 0 ;
171+ u64 addr ;
172+ const char * name = "" ;
173+ static char name_buf [KSYM_NAME_LEN ];
174+ struct symbol * sym ;
175+ struct map * kmap ;
176+ struct machine * machine = con -> machine ;
177+
178+ if (con -> aggr_mode == LOCK_AGGR_TASK ) {
179+ struct contention_task_data task ;
180+ int pid = key -> aggr_key ;
181+ int task_fd = bpf_map__fd (skel -> maps .task_data );
182+
183+ /* do not update idle comm which contains CPU number */
184+ if (pid ) {
185+ struct thread * t = __machine__findnew_thread (machine , /*pid=*/ -1 , pid );
186+
187+ if (t == NULL )
188+ return name ;
189+ if (!bpf_map_lookup_elem (task_fd , & pid , & task ) &&
190+ thread__set_comm (t , task .comm , /*timestamp=*/ 0 ))
191+ name = task .comm ;
192+ }
193+ return name ;
194+ }
195+
196+ if (con -> aggr_mode == LOCK_AGGR_ADDR ) {
197+ sym = machine__find_kernel_symbol (machine , key -> aggr_key , & kmap );
198+ if (sym )
199+ name = sym -> name ;
200+ return name ;
201+ }
202+
203+ /* LOCK_AGGR_CALLER: skip lock internal functions */
204+ while (machine__is_lock_function (machine , stack_trace [idx ]) &&
205+ idx < con -> max_stack - 1 )
206+ idx ++ ;
207+
208+ addr = stack_trace [idx ];
209+ sym = machine__find_kernel_symbol (machine , addr , & kmap );
210+
211+ if (sym ) {
212+ unsigned long offset ;
213+
214+ offset = kmap -> map_ip (kmap , addr ) - sym -> start ;
215+
216+ if (offset == 0 )
217+ return sym -> name ;
218+
219+ snprintf (name_buf , sizeof (name_buf ), "%s+%#lx" , sym -> name , offset );
220+ } else {
221+ snprintf (name_buf , sizeof (name_buf ), "%#lx" , (unsigned long )addr );
222+ }
223+
224+ return name_buf ;
225+ }
226+
166227int lock_contention_read (struct lock_contention * con )
167228{
168- int fd , stack , task_fd , err = 0 ;
229+ int fd , stack , err = 0 ;
169230 struct contention_key * prev_key , key ;
170231 struct contention_data data = {};
171232 struct lock_stat * st = NULL ;
@@ -175,7 +236,6 @@ int lock_contention_read(struct lock_contention *con)
175236
176237 fd = bpf_map__fd (skel -> maps .lock_stat );
177238 stack = bpf_map__fd (skel -> maps .stacks );
178- task_fd = bpf_map__fd (skel -> maps .task_data );
179239
180240 con -> lost = skel -> bss -> lost ;
181241
@@ -195,9 +255,6 @@ int lock_contention_read(struct lock_contention *con)
195255
196256 prev_key = NULL ;
197257 while (!bpf_map_get_next_key (fd , prev_key , & key )) {
198- struct map * kmap ;
199- struct symbol * sym ;
200- int idx = 0 ;
201258 s32 stack_id ;
202259
203260 /* to handle errors in the loop body */
@@ -219,61 +276,19 @@ int lock_contention_read(struct lock_contention *con)
219276 st -> flags = data .flags ;
220277 st -> addr = key .aggr_key ;
221278
222- if (con -> aggr_mode == LOCK_AGGR_TASK ) {
223- struct contention_task_data task ;
224- struct thread * t ;
225- int pid = key .aggr_key ;
226-
227- /* do not update idle comm which contains CPU number */
228- if (st -> addr ) {
229- bpf_map_lookup_elem (task_fd , & pid , & task );
230- t = __machine__findnew_thread (machine , /*pid=*/ -1 , pid );
231- thread__set_comm (t , task .comm , /*timestamp=*/ 0 );
232- }
233- goto next ;
234- }
235-
236- if (con -> aggr_mode == LOCK_AGGR_ADDR ) {
237- sym = machine__find_kernel_symbol (machine , st -> addr , & kmap );
238- if (sym )
239- st -> name = strdup (sym -> name );
240- goto next ;
241- }
242-
243279 stack_id = key .aggr_key ;
244280 bpf_map_lookup_elem (stack , & stack_id , stack_trace );
245281
246- /* skip lock internal functions */
247- while (machine__is_lock_function (machine , stack_trace [idx ]) &&
248- idx < con -> max_stack - 1 )
249- idx ++ ;
250-
251- st -> addr = stack_trace [idx ];
252- sym = machine__find_kernel_symbol (machine , st -> addr , & kmap );
253-
254- if (sym ) {
255- unsigned long offset ;
256- int ret = 0 ;
257-
258- offset = kmap -> map_ip (kmap , st -> addr ) - sym -> start ;
259-
260- if (offset )
261- ret = asprintf (& st -> name , "%s+%#lx" , sym -> name , offset );
262- else
263- st -> name = strdup (sym -> name );
264-
265- if (ret < 0 || st -> name == NULL )
266- break ;
267- } else if (asprintf (& st -> name , "%#lx" , (unsigned long )st -> addr ) < 0 ) {
282+ st -> name = strdup (lock_contention_get_name (con , & key , stack_trace ));
283+ if (st -> name == NULL )
268284 break ;
269- }
270285
271286 if (con -> save_callstack ) {
272287 st -> callstack = memdup (stack_trace , stack_size );
273288 if (st -> callstack == NULL )
274289 break ;
275290 }
276- next :
291+
277292 hlist_add_head (& st -> hash_entry , con -> result );
278293 prev_key = & key ;
279294
0 commit comments