The mmap_lock is acquired on most (all?) mmap / munmap / page fault operations, so a multi-threaded process which does a lot of these can experience significant contention. Sometimes we want to know where the lock is hold. And it's hard to locate without collecting ip. Here's an example: TP_printk("ip=%pS",ip) Log looks like this: "ip=do_user_addr_fault+0x274/0x640" We can find out who cause the contention amd make some improvements for it. Signed-off-by: Gang Li <ligang.bdlg@xxxxxxxxxxxxx> --- include/trace/events/mmap_lock.h | 27 +++++++++++++++++---------- mm/mmap_lock.c | 6 +++--- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/include/trace/events/mmap_lock.h b/include/trace/events/mmap_lock.h index b9dd66f9c226..8913a9f85894 100644 --- a/include/trace/events/mmap_lock.h +++ b/include/trace/events/mmap_lock.h @@ -15,35 +15,39 @@ extern void trace_mmap_lock_unreg(void); DECLARE_EVENT_CLASS(mmap_lock, - TP_PROTO(struct mm_struct *mm, const char *memcg_path, bool write), + TP_PROTO(struct mm_struct *mm, const char *memcg_path, bool write, + unsigned long ip), - TP_ARGS(mm, memcg_path, write), + TP_ARGS(mm, memcg_path, write, ip), TP_STRUCT__entry( __field(struct mm_struct *, mm) __string(memcg_path, memcg_path) __field(bool, write) + __field(void *, ip) ), TP_fast_assign( __entry->mm = mm; __assign_str(memcg_path, memcg_path); __entry->write = write; + __entry->ip = (void *)ip; ), TP_printk( - "mm=%p memcg_path=%s write=%s", + "mm=%p memcg_path=%s write=%s ip=%pS", __entry->mm, __get_str(memcg_path), - __entry->write ? "true" : "false" - ) + __entry->write ? "true" : "false", + __entry->ip + ) ); #define DEFINE_MMAP_LOCK_EVENT(name) \ DEFINE_EVENT_FN(mmap_lock, name, \ TP_PROTO(struct mm_struct *mm, const char *memcg_path, \ - bool write), \ - TP_ARGS(mm, memcg_path, write), \ + bool write, unsigned long ip), \ + TP_ARGS(mm, memcg_path, write, ip), \ trace_mmap_lock_reg, trace_mmap_lock_unreg) DEFINE_MMAP_LOCK_EVENT(mmap_lock_start_locking); @@ -52,14 +56,15 @@ DEFINE_MMAP_LOCK_EVENT(mmap_lock_released); TRACE_EVENT_FN(mmap_lock_acquire_returned, TP_PROTO(struct mm_struct *mm, const char *memcg_path, bool write, - bool success), + unsigned long ip, bool success), - TP_ARGS(mm, memcg_path, write, success), + TP_ARGS(mm, memcg_path, write, ip, success), TP_STRUCT__entry( __field(struct mm_struct *, mm) __string(memcg_path, memcg_path) __field(bool, write) + __field(void *, ip) __field(bool, success) ), @@ -67,14 +72,16 @@ TRACE_EVENT_FN(mmap_lock_acquire_returned, __entry->mm = mm; __assign_str(memcg_path, memcg_path); __entry->write = write; + __entry->ip = (void *)ip; __entry->success = success; ), TP_printk( - "mm=%p memcg_path=%s write=%s success=%s", + "mm=%p memcg_path=%s write=%s ip=%pS success=%s", __entry->mm, __get_str(memcg_path), __entry->write ? "true" : "false", + __entry->ip, __entry->success ? "true" : "false" ), diff --git a/mm/mmap_lock.c b/mm/mmap_lock.c index 1854850b4b89..f1100eae6f2f 100644 --- a/mm/mmap_lock.c +++ b/mm/mmap_lock.c @@ -227,20 +227,20 @@ static const char *get_mm_memcg_path(struct mm_struct *mm) void __mmap_lock_do_trace_start_locking(struct mm_struct *mm, bool write) { - TRACE_MMAP_LOCK_EVENT(start_locking, mm, write); + TRACE_MMAP_LOCK_EVENT(start_locking, mm, write, _RET_IP_); } EXPORT_SYMBOL(__mmap_lock_do_trace_start_locking); void __mmap_lock_do_trace_acquire_returned(struct mm_struct *mm, bool write, bool success) { - TRACE_MMAP_LOCK_EVENT(acquire_returned, mm, write, success); + TRACE_MMAP_LOCK_EVENT(acquire_returned, mm, write, _RET_IP_, success); } EXPORT_SYMBOL(__mmap_lock_do_trace_acquire_returned); void __mmap_lock_do_trace_released(struct mm_struct *mm, bool write) { - TRACE_MMAP_LOCK_EVENT(released, mm, write); + TRACE_MMAP_LOCK_EVENT(released, mm, write, _RET_IP_); } EXPORT_SYMBOL(__mmap_lock_do_trace_released); #endif /* CONFIG_TRACING */ -- 2.20.1