block: make blktrace use per-cpu buffers for message notes
authorJens Axboe <jens.axboe@oracle.com>
Wed, 28 May 2008 12:45:33 +0000 (14:45 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Wed, 28 May 2008 12:49:27 +0000 (14:49 +0200)
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>
block/blktrace.c
include/linux/blktrace_api.h

index 20e11f354f117d83e4c83356a99b09c70a87939e..7ae87cc4a163fc0dfcae0f65e6d25e9b185c4b91 100644 (file)
@@ -79,13 +79,16 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...)
 {
        int n;
        va_list args;
-       static char bt_msg_buf[BLK_TN_MAX_MSG];
+       char *buf;
 
+       preempt_disable();
+       buf = per_cpu_ptr(bt->msg_data, smp_processor_id());
        va_start(args, fmt);
-       n = vscnprintf(bt_msg_buf, BLK_TN_MAX_MSG, fmt, args);
+       n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args);
        va_end(args);
 
-       trace_note(bt, 0, BLK_TN_MESSAGE, bt_msg_buf, n);
+       trace_note(bt, 0, BLK_TN_MESSAGE, buf, n);
+       preempt_enable();
 }
 EXPORT_SYMBOL_GPL(__trace_note_message);
 
@@ -246,6 +249,7 @@ static void blk_trace_cleanup(struct blk_trace *bt)
        debugfs_remove(bt->dropped_file);
        blk_remove_tree(bt->dir);
        free_percpu(bt->sequence);
+       free_percpu(bt->msg_data);
        kfree(bt);
 }
 
@@ -360,6 +364,10 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
        if (!bt->sequence)
                goto err;
 
+       bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG);
+       if (!bt->msg_data)
+               goto err;
+
        ret = -ENOENT;
        dir = blk_create_tree(buts->name);
        if (!dir)
@@ -406,6 +414,7 @@ err:
                if (bt->dropped_file)
                        debugfs_remove(bt->dropped_file);
                free_percpu(bt->sequence);
+               free_percpu(bt->msg_data);
                if (bt->rchan)
                        relay_close(bt->rchan);
                kfree(bt);
index b7cd8f1eedbe423b0ce7faca7fe9979fd91463af..e3ef903aae88224fef2f43fa96b0e0f199baa09b 100644 (file)
@@ -121,6 +121,7 @@ struct blk_trace {
        int trace_state;
        struct rchan *rchan;
        unsigned long *sequence;
+       unsigned char *msg_data;
        u16 act_mask;
        u64 start_lba;
        u64 end_lba;
@@ -172,7 +173,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
                if (unlikely(bt))                                       \
                        __trace_note_message(bt, fmt, ##__VA_ARGS__);   \
        } while (0)
-#define BLK_TN_MAX_MSG         1024
+#define BLK_TN_MAX_MSG         128
 
 /**
  * blk_add_trace_rq - Add a trace for a request oriented action