aboutsummaryrefslogtreecommitdiffstats
path: root/block/blktrace.c
diff options
context:
space:
mode:
authorOlaf Kirch <okir@suse.de>2006-12-01 04:39:12 -0500
committerJens Axboe <jens.axboe@oracle.com>2006-12-01 04:39:12 -0500
commitbe1c63411addba3ad750eb4fdfc50b97bc82825e (patch)
treed00c889873310a5c6ee0caf79f2b70e64a382796 /block/blktrace.c
parent0215ffb08ce99e2bb59eca114a99499a4d06e704 (diff)
[PATCH] blktrace: add timestamp message
This adds a new timestamp message to blktrace, giving the timeofday when we starting tracing. This helps user space correlate block trace events with eg an application strace. This requires a (compatible) update to blkparse. The changed blkparse is still able to process traces generated by older kernels, and older versions of blkparse should silently ignore the new records (because they have a pid of 0). Signed-off-by: Olaf Kirch <okir@suse.de> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/blktrace.c')
-rw-r--r--block/blktrace.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/block/blktrace.c b/block/blktrace.c
index 135593c8e45b..562ca7cbf858 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -22,30 +22,61 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/debugfs.h> 24#include <linux/debugfs.h>
25#include <linux/time.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26 27
27static DEFINE_PER_CPU(unsigned long long, blk_trace_cpu_offset) = { 0, }; 28static DEFINE_PER_CPU(unsigned long long, blk_trace_cpu_offset) = { 0, };
28static unsigned int blktrace_seq __read_mostly = 1; 29static unsigned int blktrace_seq __read_mostly = 1;
29 30
30/* 31/*
32 * Send out a notify message.
33 */
34static inline unsigned int trace_note(struct blk_trace *bt,
35 pid_t pid, int action,
36 const void *data, size_t len)
37{
38 struct blk_io_trace *t;
39 int cpu = smp_processor_id();
40
41 t = relay_reserve(bt->rchan, sizeof(*t) + len);
42 if (t == NULL)
43 return 0;
44
45 t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
46 t->time = sched_clock() - per_cpu(blk_trace_cpu_offset, cpu);
47 t->device = bt->dev;
48 t->action = action;
49 t->pid = pid;
50 t->cpu = cpu;
51 t->pdu_len = len;
52 memcpy((void *) t + sizeof(*t), data, len);
53 return blktrace_seq;
54}
55
56/*
31 * Send out a notify for this process, if we haven't done so since a trace 57 * Send out a notify for this process, if we haven't done so since a trace
32 * started 58 * started
33 */ 59 */
34static void trace_note_tsk(struct blk_trace *bt, struct task_struct *tsk) 60static void trace_note_tsk(struct blk_trace *bt, struct task_struct *tsk)
35{ 61{
36 struct blk_io_trace *t; 62 tsk->btrace_seq = trace_note(bt, tsk->pid,
63 BLK_TN_PROCESS,
64 tsk->comm, sizeof(tsk->comm));
65}
37 66
38 t = relay_reserve(bt->rchan, sizeof(*t) + sizeof(tsk->comm)); 67static void trace_note_time(struct blk_trace *bt)
39 if (t) { 68{
40 t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION; 69 struct timespec now;
41 t->device = bt->dev; 70 unsigned long flags;
42 t->action = BLK_TC_ACT(BLK_TC_NOTIFY); 71 u32 words[2];
43 t->pid = tsk->pid; 72
44 t->cpu = smp_processor_id(); 73 getnstimeofday(&now);
45 t->pdu_len = sizeof(tsk->comm); 74 words[0] = now.tv_sec;
46 memcpy((void *) t + sizeof(*t), tsk->comm, t->pdu_len); 75 words[1] = now.tv_nsec;
47 tsk->btrace_seq = blktrace_seq; 76
48 } 77 local_irq_save(flags);
78 trace_note(bt, 0, BLK_TN_TIMESTAMP, words, sizeof(words));
79 local_irq_restore(flags);
49} 80}
50 81
51static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, 82static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
@@ -394,6 +425,8 @@ static int blk_trace_startstop(request_queue_t *q, int start)
394 blktrace_seq++; 425 blktrace_seq++;
395 smp_mb(); 426 smp_mb();
396 bt->trace_state = Blktrace_running; 427 bt->trace_state = Blktrace_running;
428
429 trace_note_time(bt);
397 ret = 0; 430 ret = 0;
398 } 431 }
399 } else { 432 } else {