diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2008-05-28 08:45:33 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-05-28 08:49:27 -0400 |
commit | 64565911cdb57c2f512a9715b985b5617402cc67 (patch) | |
tree | 1c8a3d03fcb0e620c8f2244962fb249cff51fec4 /block/blktrace.c | |
parent | 4722dc52a891ab6cb2d637ddb87233e0ce277827 (diff) |
block: make blktrace use per-cpu buffers for message notes
Currently it uses a single static char array, but that risks
being corrupted when multiple users issue message notes at the
same time. Make the buffers dynamically allocated when the trace
is setup and make them per-cpu instead.
The default max message size of 1k is also very large, the
interface is mainly for small text notes. So shrink it to 128 bytes.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/blktrace.c')
-rw-r--r-- | block/blktrace.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/block/blktrace.c b/block/blktrace.c index 20e11f354f11..7ae87cc4a163 100644 --- a/block/blktrace.c +++ b/block/blktrace.c | |||
@@ -79,13 +79,16 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) | |||
79 | { | 79 | { |
80 | int n; | 80 | int n; |
81 | va_list args; | 81 | va_list args; |
82 | static char bt_msg_buf[BLK_TN_MAX_MSG]; | 82 | char *buf; |
83 | 83 | ||
84 | preempt_disable(); | ||
85 | buf = per_cpu_ptr(bt->msg_data, smp_processor_id()); | ||
84 | va_start(args, fmt); | 86 | va_start(args, fmt); |
85 | n = vscnprintf(bt_msg_buf, BLK_TN_MAX_MSG, fmt, args); | 87 | n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args); |
86 | va_end(args); | 88 | va_end(args); |
87 | 89 | ||
88 | trace_note(bt, 0, BLK_TN_MESSAGE, bt_msg_buf, n); | 90 | trace_note(bt, 0, BLK_TN_MESSAGE, buf, n); |
91 | preempt_enable(); | ||
89 | } | 92 | } |
90 | EXPORT_SYMBOL_GPL(__trace_note_message); | 93 | EXPORT_SYMBOL_GPL(__trace_note_message); |
91 | 94 | ||
@@ -246,6 +249,7 @@ static void blk_trace_cleanup(struct blk_trace *bt) | |||
246 | debugfs_remove(bt->dropped_file); | 249 | debugfs_remove(bt->dropped_file); |
247 | blk_remove_tree(bt->dir); | 250 | blk_remove_tree(bt->dir); |
248 | free_percpu(bt->sequence); | 251 | free_percpu(bt->sequence); |
252 | free_percpu(bt->msg_data); | ||
249 | kfree(bt); | 253 | kfree(bt); |
250 | } | 254 | } |
251 | 255 | ||
@@ -360,6 +364,10 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
360 | if (!bt->sequence) | 364 | if (!bt->sequence) |
361 | goto err; | 365 | goto err; |
362 | 366 | ||
367 | bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG); | ||
368 | if (!bt->msg_data) | ||
369 | goto err; | ||
370 | |||
363 | ret = -ENOENT; | 371 | ret = -ENOENT; |
364 | dir = blk_create_tree(buts->name); | 372 | dir = blk_create_tree(buts->name); |
365 | if (!dir) | 373 | if (!dir) |
@@ -406,6 +414,7 @@ err: | |||
406 | if (bt->dropped_file) | 414 | if (bt->dropped_file) |
407 | debugfs_remove(bt->dropped_file); | 415 | debugfs_remove(bt->dropped_file); |
408 | free_percpu(bt->sequence); | 416 | free_percpu(bt->sequence); |
417 | free_percpu(bt->msg_data); | ||
409 | if (bt->rchan) | 418 | if (bt->rchan) |
410 | relay_close(bt->rchan); | 419 | relay_close(bt->rchan); |
411 | kfree(bt); | 420 | kfree(bt); |