Commit 64565911 authored by Jens Axboe's avatar Jens Axboe

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: default avatarJens Axboe <jens.axboe@oracle.com>
parent 4722dc52
...@@ -79,13 +79,16 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) ...@@ -79,13 +79,16 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...)
{ {
int n; int n;
va_list args; 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); 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); 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); EXPORT_SYMBOL_GPL(__trace_note_message);
...@@ -246,6 +249,7 @@ static void blk_trace_cleanup(struct blk_trace *bt) ...@@ -246,6 +249,7 @@ static void blk_trace_cleanup(struct blk_trace *bt)
debugfs_remove(bt->dropped_file); debugfs_remove(bt->dropped_file);
blk_remove_tree(bt->dir); blk_remove_tree(bt->dir);
free_percpu(bt->sequence); free_percpu(bt->sequence);
free_percpu(bt->msg_data);
kfree(bt); kfree(bt);
} }
...@@ -360,6 +364,10 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, ...@@ -360,6 +364,10 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (!bt->sequence) if (!bt->sequence)
goto err; goto err;
bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG);
if (!bt->msg_data)
goto err;
ret = -ENOENT; ret = -ENOENT;
dir = blk_create_tree(buts->name); dir = blk_create_tree(buts->name);
if (!dir) if (!dir)
...@@ -406,6 +414,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, ...@@ -406,6 +414,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (bt->dropped_file) if (bt->dropped_file)
debugfs_remove(bt->dropped_file); debugfs_remove(bt->dropped_file);
free_percpu(bt->sequence); free_percpu(bt->sequence);
free_percpu(bt->msg_data);
if (bt->rchan) if (bt->rchan)
relay_close(bt->rchan); relay_close(bt->rchan);
kfree(bt); kfree(bt);
......
...@@ -121,6 +121,7 @@ struct blk_trace { ...@@ -121,6 +121,7 @@ struct blk_trace {
int trace_state; int trace_state;
struct rchan *rchan; struct rchan *rchan;
unsigned long *sequence; unsigned long *sequence;
unsigned char *msg_data;
u16 act_mask; u16 act_mask;
u64 start_lba; u64 start_lba;
u64 end_lba; u64 end_lba;
...@@ -172,7 +173,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...); ...@@ -172,7 +173,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
if (unlikely(bt)) \ if (unlikely(bt)) \
__trace_note_message(bt, fmt, ##__VA_ARGS__); \ __trace_note_message(bt, fmt, ##__VA_ARGS__); \
} while (0) } 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 * blk_add_trace_rq - Add a trace for a request oriented action
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment