]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - block/blktrace.c
block: make blktrace use per-cpu buffers for message notes
[linux-2.6-omap-h63xx.git] / block / blktrace.c
index 9b4da4ae3c7dcce3dc9964adb5ecf2c570017e8a..7ae87cc4a163fc0dfcae0f65e6d25e9b185c4b91 100644 (file)
@@ -75,6 +75,23 @@ static void trace_note_time(struct blk_trace *bt)
        local_irq_restore(flags);
 }
 
+void __trace_note_message(struct blk_trace *bt, const char *fmt, ...)
+{
+       int n;
+       va_list args;
+       char *buf;
+
+       preempt_disable();
+       buf = per_cpu_ptr(bt->msg_data, smp_processor_id());
+       va_start(args, fmt);
+       n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args);
+       va_end(args);
+
+       trace_note(bt, 0, BLK_TN_MESSAGE, buf, n);
+       preempt_enable();
+}
+EXPORT_SYMBOL_GPL(__trace_note_message);
+
 static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
                         pid_t pid)
 {
@@ -232,10 +249,11 @@ 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);
 }
 
-static int blk_trace_remove(struct request_queue *q)
+int blk_trace_remove(struct request_queue *q)
 {
        struct blk_trace *bt;
 
@@ -249,6 +267,7 @@ static int blk_trace_remove(struct request_queue *q)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(blk_trace_remove);
 
 static int blk_dropped_open(struct inode *inode, struct file *filp)
 {
@@ -316,18 +335,17 @@ static struct rchan_callbacks blk_relay_callbacks = {
 /*
  * Setup everything required to start tracing
  */
-int do_blk_trace_setup(struct request_queue *q, struct block_device *bdev,
+int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
                        struct blk_user_trace_setup *buts)
 {
        struct blk_trace *old_bt, *bt = NULL;
        struct dentry *dir = NULL;
-       char b[BDEVNAME_SIZE];
        int ret, i;
 
        if (!buts->buf_size || !buts->buf_nr)
                return -EINVAL;
 
-       strcpy(buts->name, bdevname(bdev, b));
+       strcpy(buts->name, name);
 
        /*
         * some device names have larger paths - convert the slashes
@@ -346,13 +364,17 @@ int do_blk_trace_setup(struct request_queue *q, struct block_device *bdev,
        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)
                goto err;
 
        bt->dir = dir;
-       bt->dev = bdev->bd_dev;
+       bt->dev = dev;
        atomic_set(&bt->dropped, 0);
 
        ret = -EIO;
@@ -392,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);
@@ -399,8 +422,8 @@ err:
        return ret;
 }
 
-static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
-                          char __user *arg)
+int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+                   char __user *arg)
 {
        struct blk_user_trace_setup buts;
        int ret;
@@ -409,7 +432,7 @@ static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
        if (ret)
                return -EFAULT;
 
-       ret = do_blk_trace_setup(q, bdev, &buts);
+       ret = do_blk_trace_setup(q, name, dev, &buts);
        if (ret)
                return ret;
 
@@ -418,8 +441,9 @@ static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(blk_trace_setup);
 
-static int blk_trace_startstop(struct request_queue *q, int start)
+int blk_trace_startstop(struct request_queue *q, int start)
 {
        struct blk_trace *bt;
        int ret;
@@ -452,6 +476,7 @@ static int blk_trace_startstop(struct request_queue *q, int start)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(blk_trace_startstop);
 
 /**
  * blk_trace_ioctl: - handle the ioctls associated with tracing
@@ -464,6 +489,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
 {
        struct request_queue *q;
        int ret, start = 0;
+       char b[BDEVNAME_SIZE];
 
        q = bdev_get_queue(bdev);
        if (!q)
@@ -473,7 +499,8 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
 
        switch (cmd) {
        case BLKTRACESETUP:
-               ret = blk_trace_setup(q, bdev, arg);
+               bdevname(bdev, b);
+               ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
                break;
        case BLKTRACESTART:
                start = 1;