diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/blktrace.c | 57 |
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 | ||
27 | static DEFINE_PER_CPU(unsigned long long, blk_trace_cpu_offset) = { 0, }; | 28 | static DEFINE_PER_CPU(unsigned long long, blk_trace_cpu_offset) = { 0, }; |
28 | static unsigned int blktrace_seq __read_mostly = 1; | 29 | static unsigned int blktrace_seq __read_mostly = 1; |
29 | 30 | ||
30 | /* | 31 | /* |
32 | * Send out a notify message. | ||
33 | */ | ||
34 | static 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 | */ |
34 | static void trace_note_tsk(struct blk_trace *bt, struct task_struct *tsk) | 60 | static 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)); | 67 | static 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 | ||
51 | static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, | 82 | static 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 { |