Commit 2062501a authored by Frederic Weisbecker's avatar Frederic Weisbecker Committed by Ingo Molnar

tracing/lockdep: report the time waited for a lock

While trying to optimize the new lock on reiserfs to replace
the bkl, I find the lock tracing very useful though it lacks
something important for performance (and latency) instrumentation:
the time a task waits for a lock.

That's what this patch implements:

  bash-4816  [000]   202.652815: lock_contended: lock_contended: &sb->s_type->i_mutex_key
  bash-4816  [000]   202.652819: lock_acquired: &rq->lock (0.000 us)
 <...>-4787  [000]   202.652825: lock_acquired: &rq->lock (0.000 us)
 <...>-4787  [000]   202.652829: lock_acquired: &rq->lock (0.000 us)
  bash-4816  [000]   202.652833: lock_acquired: &sb->s_type->i_mutex_key (16.005 us)

As shown above, the "lock acquired" field is followed by the time
it has been waiting for the lock. Usually, a lock contended entry
is followed by a near lock_acquired entry with a non-zero time waited.
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1238975373-15739-1-git-send-email-fweisbec@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 1cad1252
...@@ -32,11 +32,24 @@ TRACE_FORMAT(lock_contended, ...@@ -32,11 +32,24 @@ TRACE_FORMAT(lock_contended,
TP_FMT("%s", lock->name) TP_FMT("%s", lock->name)
); );
TRACE_FORMAT(lock_acquired, TRACE_EVENT(lock_acquired,
TP_PROTO(struct lockdep_map *lock, unsigned long ip), TP_PROTO(struct lockdep_map *lock, unsigned long ip, s64 waittime),
TP_ARGS(lock, ip),
TP_FMT("%s", lock->name) TP_ARGS(lock, ip, waittime),
);
TP_STRUCT__entry(
__field(const char *, name)
__field(unsigned long, wait_usec)
__field(unsigned long, wait_nsec_rem)
),
TP_fast_assign(
__entry->name = lock->name;
__entry->wait_nsec_rem = do_div(waittime, NSEC_PER_USEC);
__entry->wait_usec = (unsigned long) waittime;
),
TP_printk("%s (%lu.%03lu us)", __entry->name, __entry->wait_usec,
__entry->wait_nsec_rem)
);
#endif #endif
#endif #endif
......
...@@ -3061,6 +3061,8 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip) ...@@ -3061,6 +3061,8 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip)
put_lock_stats(stats); put_lock_stats(stats);
} }
DEFINE_TRACE(lock_acquired);
static void static void
__lock_acquired(struct lockdep_map *lock, unsigned long ip) __lock_acquired(struct lockdep_map *lock, unsigned long ip)
{ {
...@@ -3099,6 +3101,8 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip) ...@@ -3099,6 +3101,8 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip)
hlock->holdtime_stamp = now; hlock->holdtime_stamp = now;
} }
trace_lock_acquired(lock, ip, waittime);
stats = get_lock_stats(hlock_class(hlock)); stats = get_lock_stats(hlock_class(hlock));
if (waittime) { if (waittime) {
if (hlock->read) if (hlock->read)
...@@ -3137,14 +3141,10 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip) ...@@ -3137,14 +3141,10 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
} }
EXPORT_SYMBOL_GPL(lock_contended); EXPORT_SYMBOL_GPL(lock_contended);
DEFINE_TRACE(lock_acquired);
void lock_acquired(struct lockdep_map *lock, unsigned long ip) void lock_acquired(struct lockdep_map *lock, unsigned long ip)
{ {
unsigned long flags; unsigned long flags;
trace_lock_acquired(lock, ip);
if (unlikely(!lock_stat)) if (unlikely(!lock_stat))
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment