diff options
| author | Li Zefan <lizf@cn.fujitsu.com> | 2009-03-26 22:21:54 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-03-31 11:29:11 -0400 |
| commit | 18cea4591a98817697017bcb056a848bae1205df (patch) | |
| tree | 2a5d65642b5dfeefb8e688e2276ae0dbb2a12787 | |
| parent | b6a4b0c3ad4c09c1d37b1040ac8e3ebd1016e10b (diff) | |
blktrace: print out BLK_TN_MESSAGE properly
Impact: improve ftrace plugin output
Before this patch:
# cat trace
make-5383 [001] 741.240059: 8,7 P N [make]
__trace_note_message: cfq1074
# echo 1 > options/blk_classic
# cat trace
8,7 1 0.692221252 0 C W 130411392 + 1024 [0]
Bad pc action 6361
Bad pc action 283d
# echo 0 > options/blk_classic
# echo bin > trace_options
# cat trace_pipe | blkparse -i -
(can't parse messages generated by blk_add_trace_msg())
After this patch:
# cat trace
<idle>-0 [001] 187.600933: 8,7 C W 145220224 + 8 [0]
<idle>-0 [001] 187.600946: 8,7 m N cfq1076 complete
# echo 1 > options/blk_classic
# cat trace
8,7 1 0.256378996 238 I W 113190728 + 8 [pdflush]
8,7 1 0.256378998 238 m N cfq1076 insert_request
# echo 0 > options/blk_classic
# echo bin > trace_options
# cat trace_pipe | blkparse -i -
8,7 1 0 22.973250293 0 C W 102770576 + 8 [0]
8,7 1 0 22.973259213 0 m N cfq1076 complete
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | kernel/trace/blktrace.c | 80 |
1 files changed, 61 insertions, 19 deletions
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index c103b0c20022..947c5b3f90c4 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
| @@ -59,22 +59,39 @@ static void trace_note(struct blk_trace *bt, pid_t pid, int action, | |||
| 59 | const void *data, size_t len) | 59 | const void *data, size_t len) |
| 60 | { | 60 | { |
| 61 | struct blk_io_trace *t; | 61 | struct blk_io_trace *t; |
| 62 | struct ring_buffer_event *event = NULL; | ||
| 63 | int pc = 0; | ||
| 64 | int cpu = smp_processor_id(); | ||
| 65 | bool blk_tracer = blk_tracer_enabled; | ||
| 66 | |||
| 67 | if (blk_tracer) { | ||
| 68 | pc = preempt_count(); | ||
| 69 | event = trace_buffer_lock_reserve(blk_tr, TRACE_BLK, | ||
| 70 | sizeof(*t) + len, | ||
| 71 | 0, pc); | ||
| 72 | if (!event) | ||
| 73 | return; | ||
| 74 | t = ring_buffer_event_data(event); | ||
| 75 | goto record_it; | ||
| 76 | } | ||
| 62 | 77 | ||
| 63 | if (!bt->rchan) | 78 | if (!bt->rchan) |
| 64 | return; | 79 | return; |
| 65 | 80 | ||
| 66 | t = relay_reserve(bt->rchan, sizeof(*t) + len); | 81 | t = relay_reserve(bt->rchan, sizeof(*t) + len); |
| 67 | if (t) { | 82 | if (t) { |
| 68 | const int cpu = smp_processor_id(); | ||
| 69 | |||
| 70 | t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION; | 83 | t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION; |
| 71 | t->time = ktime_to_ns(ktime_get()); | 84 | t->time = ktime_to_ns(ktime_get()); |
| 85 | record_it: | ||
| 72 | t->device = bt->dev; | 86 | t->device = bt->dev; |
| 73 | t->action = action; | 87 | t->action = action; |
| 74 | t->pid = pid; | 88 | t->pid = pid; |
| 75 | t->cpu = cpu; | 89 | t->cpu = cpu; |
| 76 | t->pdu_len = len; | 90 | t->pdu_len = len; |
| 77 | memcpy((void *) t + sizeof(*t), data, len); | 91 | memcpy((void *) t + sizeof(*t), data, len); |
| 92 | |||
| 93 | if (blk_tracer) | ||
| 94 | trace_buffer_unlock_commit(blk_tr, event, 0, pc); | ||
| 78 | } | 95 | } |
| 79 | } | 96 | } |
| 80 | 97 | ||
| @@ -110,14 +127,8 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) | |||
| 110 | unsigned long flags; | 127 | unsigned long flags; |
| 111 | char *buf; | 128 | char *buf; |
| 112 | 129 | ||
| 113 | if (blk_tracer_enabled) { | 130 | if (unlikely(bt->trace_state != Blktrace_running && |
| 114 | va_start(args, fmt); | 131 | !blk_tracer_enabled)) |
| 115 | ftrace_vprintk(fmt, args); | ||
| 116 | va_end(args); | ||
| 117 | return; | ||
| 118 | } | ||
| 119 | |||
| 120 | if (!bt->msg_data) | ||
| 121 | return; | 132 | return; |
| 122 | 133 | ||
| 123 | local_irq_save(flags); | 134 | local_irq_save(flags); |
| @@ -168,9 +179,9 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, | |||
| 168 | unsigned long *sequence; | 179 | unsigned long *sequence; |
| 169 | pid_t pid; | 180 | pid_t pid; |
| 170 | int cpu, pc = 0; | 181 | int cpu, pc = 0; |
| 182 | bool blk_tracer = blk_tracer_enabled; | ||
| 171 | 183 | ||
| 172 | if (unlikely(bt->trace_state != Blktrace_running && | 184 | if (unlikely(bt->trace_state != Blktrace_running && !blk_tracer)) |
| 173 | !blk_tracer_enabled)) | ||
| 174 | return; | 185 | return; |
| 175 | 186 | ||
| 176 | what |= ddir_act[rw & WRITE]; | 187 | what |= ddir_act[rw & WRITE]; |
| @@ -185,7 +196,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, | |||
| 185 | return; | 196 | return; |
| 186 | cpu = raw_smp_processor_id(); | 197 | cpu = raw_smp_processor_id(); |
| 187 | 198 | ||
| 188 | if (blk_tracer_enabled) { | 199 | if (blk_tracer) { |
| 189 | tracing_record_cmdline(current); | 200 | tracing_record_cmdline(current); |
| 190 | 201 | ||
| 191 | pc = preempt_count(); | 202 | pc = preempt_count(); |
| @@ -235,7 +246,7 @@ record_it: | |||
| 235 | if (pdu_len) | 246 | if (pdu_len) |
| 236 | memcpy((void *) t + sizeof(*t), pdu_data, pdu_len); | 247 | memcpy((void *) t + sizeof(*t), pdu_data, pdu_len); |
| 237 | 248 | ||
| 238 | if (blk_tracer_enabled) { | 249 | if (blk_tracer) { |
| 239 | trace_buffer_unlock_commit(blk_tr, event, 0, pc); | 250 | trace_buffer_unlock_commit(blk_tr, event, 0, pc); |
| 240 | return; | 251 | return; |
| 241 | } | 252 | } |
| @@ -922,6 +933,11 @@ static void fill_rwbs(char *rwbs, const struct blk_io_trace *t) | |||
| 922 | int i = 0; | 933 | int i = 0; |
| 923 | int tc = t->action >> BLK_TC_SHIFT; | 934 | int tc = t->action >> BLK_TC_SHIFT; |
| 924 | 935 | ||
| 936 | if (t->action == BLK_TN_MESSAGE) { | ||
| 937 | rwbs[i++] = 'N'; | ||
| 938 | goto out; | ||
| 939 | } | ||
| 940 | |||
| 925 | if (tc & BLK_TC_DISCARD) | 941 | if (tc & BLK_TC_DISCARD) |
| 926 | rwbs[i++] = 'D'; | 942 | rwbs[i++] = 'D'; |
| 927 | else if (tc & BLK_TC_WRITE) | 943 | else if (tc & BLK_TC_WRITE) |
| @@ -939,7 +955,7 @@ static void fill_rwbs(char *rwbs, const struct blk_io_trace *t) | |||
| 939 | rwbs[i++] = 'S'; | 955 | rwbs[i++] = 'S'; |
| 940 | if (tc & BLK_TC_META) | 956 | if (tc & BLK_TC_META) |
| 941 | rwbs[i++] = 'M'; | 957 | rwbs[i++] = 'M'; |
| 942 | 958 | out: | |
| 943 | rwbs[i] = '\0'; | 959 | rwbs[i] = '\0'; |
| 944 | } | 960 | } |
| 945 | 961 | ||
| @@ -1074,6 +1090,17 @@ static int blk_log_split(struct trace_seq *s, const struct trace_entry *ent) | |||
| 1074 | get_pdu_int(ent), cmd); | 1090 | get_pdu_int(ent), cmd); |
| 1075 | } | 1091 | } |
| 1076 | 1092 | ||
| 1093 | static int blk_log_msg(struct trace_seq *s, const struct trace_entry *ent) | ||
| 1094 | { | ||
| 1095 | int ret; | ||
| 1096 | const struct blk_io_trace *t = te_blk_io_trace(ent); | ||
| 1097 | |||
| 1098 | ret = trace_seq_putmem(s, t + 1, t->pdu_len); | ||
| 1099 | if (ret) | ||
| 1100 | return trace_seq_putc(s, '\n'); | ||
| 1101 | return ret; | ||
| 1102 | } | ||
| 1103 | |||
| 1077 | /* | 1104 | /* |
| 1078 | * struct tracer operations | 1105 | * struct tracer operations |
| 1079 | */ | 1106 | */ |
| @@ -1146,6 +1173,13 @@ static enum print_line_t print_one_line(struct trace_iterator *iter, | |||
| 1146 | long_act = !!(trace_flags & TRACE_ITER_VERBOSE); | 1173 | long_act = !!(trace_flags & TRACE_ITER_VERBOSE); |
| 1147 | log_action = classic ? &blk_log_action_classic : &blk_log_action; | 1174 | log_action = classic ? &blk_log_action_classic : &blk_log_action; |
| 1148 | 1175 | ||
| 1176 | if (t->action == BLK_TN_MESSAGE) { | ||
| 1177 | ret = log_action(iter, long_act ? "message" : "m"); | ||
| 1178 | if (ret) | ||
| 1179 | ret = blk_log_msg(s, iter->ent); | ||
| 1180 | goto out; | ||
| 1181 | } | ||
| 1182 | |||
| 1149 | if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act))) | 1183 | if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act))) |
| 1150 | ret = trace_seq_printf(s, "Bad pc action %x\n", what); | 1184 | ret = trace_seq_printf(s, "Bad pc action %x\n", what); |
| 1151 | else { | 1185 | else { |
| @@ -1153,7 +1187,7 @@ static enum print_line_t print_one_line(struct trace_iterator *iter, | |||
| 1153 | if (ret) | 1187 | if (ret) |
| 1154 | ret = what2act[what].print(s, iter->ent); | 1188 | ret = what2act[what].print(s, iter->ent); |
| 1155 | } | 1189 | } |
| 1156 | 1190 | out: | |
| 1157 | return ret ? TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE; | 1191 | return ret ? TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE; |
| 1158 | } | 1192 | } |
| 1159 | 1193 | ||
| @@ -1253,11 +1287,16 @@ static int blk_trace_remove_queue(struct request_queue *q) | |||
| 1253 | static int blk_trace_setup_queue(struct request_queue *q, dev_t dev) | 1287 | static int blk_trace_setup_queue(struct request_queue *q, dev_t dev) |
| 1254 | { | 1288 | { |
| 1255 | struct blk_trace *old_bt, *bt = NULL; | 1289 | struct blk_trace *old_bt, *bt = NULL; |
| 1290 | int ret = -ENOMEM; | ||
| 1256 | 1291 | ||
| 1257 | bt = kzalloc(sizeof(*bt), GFP_KERNEL); | 1292 | bt = kzalloc(sizeof(*bt), GFP_KERNEL); |
| 1258 | if (!bt) | 1293 | if (!bt) |
| 1259 | return -ENOMEM; | 1294 | return -ENOMEM; |
| 1260 | 1295 | ||
| 1296 | bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG, __alignof__(char)); | ||
| 1297 | if (!bt->msg_data) | ||
| 1298 | goto free_bt; | ||
| 1299 | |||
| 1261 | bt->dev = dev; | 1300 | bt->dev = dev; |
| 1262 | bt->act_mask = (u16)-1; | 1301 | bt->act_mask = (u16)-1; |
| 1263 | bt->end_lba = -1ULL; | 1302 | bt->end_lba = -1ULL; |
| @@ -1265,14 +1304,17 @@ static int blk_trace_setup_queue(struct request_queue *q, dev_t dev) | |||
| 1265 | old_bt = xchg(&q->blk_trace, bt); | 1304 | old_bt = xchg(&q->blk_trace, bt); |
| 1266 | if (old_bt != NULL) { | 1305 | if (old_bt != NULL) { |
| 1267 | (void)xchg(&q->blk_trace, old_bt); | 1306 | (void)xchg(&q->blk_trace, old_bt); |
| 1268 | kfree(bt); | 1307 | ret = -EBUSY; |
| 1269 | return -EBUSY; | 1308 | goto free_bt; |
| 1270 | } | 1309 | } |
| 1271 | 1310 | ||
| 1272 | if (atomic_inc_return(&blk_probes_ref) == 1) | 1311 | if (atomic_inc_return(&blk_probes_ref) == 1) |
| 1273 | blk_register_tracepoints(); | 1312 | blk_register_tracepoints(); |
| 1274 | |||
| 1275 | return 0; | 1313 | return 0; |
| 1314 | |||
| 1315 | free_bt: | ||
| 1316 | blk_trace_free(bt); | ||
| 1317 | return ret; | ||
| 1276 | } | 1318 | } |
| 1277 | 1319 | ||
| 1278 | /* | 1320 | /* |
