diff options
Diffstat (limited to 'block/blktrace.c')
| -rw-r--r-- | block/blktrace.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/block/blktrace.c b/block/blktrace.c index b2cbb4e5d767..8d3a27780260 100644 --- a/block/blktrace.c +++ b/block/blktrace.c | |||
| @@ -75,6 +75,24 @@ static void trace_note_time(struct blk_trace *bt) | |||
| 75 | local_irq_restore(flags); | 75 | local_irq_restore(flags); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) | ||
| 79 | { | ||
| 80 | int n; | ||
| 81 | va_list args; | ||
| 82 | unsigned long flags; | ||
| 83 | char *buf; | ||
| 84 | |||
| 85 | local_irq_save(flags); | ||
| 86 | buf = per_cpu_ptr(bt->msg_data, smp_processor_id()); | ||
| 87 | va_start(args, fmt); | ||
| 88 | n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args); | ||
| 89 | va_end(args); | ||
| 90 | |||
| 91 | trace_note(bt, 0, BLK_TN_MESSAGE, buf, n); | ||
| 92 | local_irq_restore(flags); | ||
| 93 | } | ||
| 94 | EXPORT_SYMBOL_GPL(__trace_note_message); | ||
| 95 | |||
| 78 | static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, | 96 | static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, |
| 79 | pid_t pid) | 97 | pid_t pid) |
| 80 | { | 98 | { |
| @@ -141,10 +159,7 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, | |||
| 141 | /* | 159 | /* |
| 142 | * A word about the locking here - we disable interrupts to reserve | 160 | * A word about the locking here - we disable interrupts to reserve |
| 143 | * some space in the relay per-cpu buffer, to prevent an irq | 161 | * some space in the relay per-cpu buffer, to prevent an irq |
| 144 | * from coming in and stepping on our toes. Once reserved, it's | 162 | * from coming in and stepping on our toes. |
| 145 | * enough to get preemption disabled to prevent read of this data | ||
| 146 | * before we are through filling it. get_cpu()/put_cpu() does this | ||
| 147 | * for us | ||
| 148 | */ | 163 | */ |
| 149 | local_irq_save(flags); | 164 | local_irq_save(flags); |
| 150 | 165 | ||
| @@ -232,6 +247,7 @@ static void blk_trace_cleanup(struct blk_trace *bt) | |||
| 232 | debugfs_remove(bt->dropped_file); | 247 | debugfs_remove(bt->dropped_file); |
| 233 | blk_remove_tree(bt->dir); | 248 | blk_remove_tree(bt->dir); |
| 234 | free_percpu(bt->sequence); | 249 | free_percpu(bt->sequence); |
| 250 | free_percpu(bt->msg_data); | ||
| 235 | kfree(bt); | 251 | kfree(bt); |
| 236 | } | 252 | } |
| 237 | 253 | ||
| @@ -346,6 +362,10 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
| 346 | if (!bt->sequence) | 362 | if (!bt->sequence) |
| 347 | goto err; | 363 | goto err; |
| 348 | 364 | ||
| 365 | bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG); | ||
| 366 | if (!bt->msg_data) | ||
| 367 | goto err; | ||
| 368 | |||
| 349 | ret = -ENOENT; | 369 | ret = -ENOENT; |
| 350 | dir = blk_create_tree(buts->name); | 370 | dir = blk_create_tree(buts->name); |
| 351 | if (!dir) | 371 | if (!dir) |
| @@ -392,6 +412,7 @@ err: | |||
| 392 | if (bt->dropped_file) | 412 | if (bt->dropped_file) |
| 393 | debugfs_remove(bt->dropped_file); | 413 | debugfs_remove(bt->dropped_file); |
| 394 | free_percpu(bt->sequence); | 414 | free_percpu(bt->sequence); |
| 415 | free_percpu(bt->msg_data); | ||
| 395 | if (bt->rchan) | 416 | if (bt->rchan) |
| 396 | relay_close(bt->rchan); | 417 | relay_close(bt->rchan); |
| 397 | kfree(bt); | 418 | kfree(bt); |
