diff options
Diffstat (limited to 'kernel/trace/trace.c')
| -rw-r--r-- | kernel/trace/trace.c | 194 |
1 files changed, 82 insertions, 112 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 4a9079b9f082..62c6506d663f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -2036,7 +2036,8 @@ void trace_printk_init_buffers(void) | |||
| 2036 | 2036 | ||
| 2037 | /* trace_printk() is for debug use only. Don't use it in production. */ | 2037 | /* trace_printk() is for debug use only. Don't use it in production. */ |
| 2038 | 2038 | ||
| 2039 | pr_warning("\n**********************************************************\n"); | 2039 | pr_warning("\n"); |
| 2040 | pr_warning("**********************************************************\n"); | ||
| 2040 | pr_warning("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); | 2041 | pr_warning("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); |
| 2041 | pr_warning("** **\n"); | 2042 | pr_warning("** **\n"); |
| 2042 | pr_warning("** trace_printk() being used. Allocating extra memory. **\n"); | 2043 | pr_warning("** trace_printk() being used. Allocating extra memory. **\n"); |
| @@ -3352,12 +3353,12 @@ tracing_cpumask_read(struct file *filp, char __user *ubuf, | |||
| 3352 | 3353 | ||
| 3353 | mutex_lock(&tracing_cpumask_update_lock); | 3354 | mutex_lock(&tracing_cpumask_update_lock); |
| 3354 | 3355 | ||
| 3355 | len = cpumask_scnprintf(mask_str, count, tr->tracing_cpumask); | 3356 | len = snprintf(mask_str, count, "%*pb\n", |
| 3356 | if (count - len < 2) { | 3357 | cpumask_pr_args(tr->tracing_cpumask)); |
| 3358 | if (len >= count) { | ||
| 3357 | count = -EINVAL; | 3359 | count = -EINVAL; |
| 3358 | goto out_err; | 3360 | goto out_err; |
| 3359 | } | 3361 | } |
| 3360 | len += sprintf(mask_str + len, "\n"); | ||
| 3361 | count = simple_read_from_buffer(ubuf, count, ppos, mask_str, NR_CPUS+1); | 3362 | count = simple_read_from_buffer(ubuf, count, ppos, mask_str, NR_CPUS+1); |
| 3362 | 3363 | ||
| 3363 | out_err: | 3364 | out_err: |
| @@ -4140,6 +4141,12 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf) | |||
| 4140 | goto out; | 4141 | goto out; |
| 4141 | } | 4142 | } |
| 4142 | 4143 | ||
| 4144 | /* If trace pipe files are being read, we can't change the tracer */ | ||
| 4145 | if (tr->current_trace->ref) { | ||
| 4146 | ret = -EBUSY; | ||
| 4147 | goto out; | ||
| 4148 | } | ||
| 4149 | |||
| 4143 | trace_branch_disable(); | 4150 | trace_branch_disable(); |
| 4144 | 4151 | ||
| 4145 | tr->current_trace->enabled--; | 4152 | tr->current_trace->enabled--; |
| @@ -4326,17 +4333,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) | |||
| 4326 | } | 4333 | } |
| 4327 | 4334 | ||
| 4328 | trace_seq_init(&iter->seq); | 4335 | trace_seq_init(&iter->seq); |
| 4329 | 4336 | iter->trace = tr->current_trace; | |
| 4330 | /* | ||
| 4331 | * We make a copy of the current tracer to avoid concurrent | ||
| 4332 | * changes on it while we are reading. | ||
| 4333 | */ | ||
| 4334 | iter->trace = kmalloc(sizeof(*iter->trace), GFP_KERNEL); | ||
| 4335 | if (!iter->trace) { | ||
| 4336 | ret = -ENOMEM; | ||
| 4337 | goto fail; | ||
| 4338 | } | ||
| 4339 | *iter->trace = *tr->current_trace; | ||
| 4340 | 4337 | ||
| 4341 | if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) { | 4338 | if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) { |
| 4342 | ret = -ENOMEM; | 4339 | ret = -ENOMEM; |
| @@ -4363,6 +4360,8 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) | |||
| 4363 | iter->trace->pipe_open(iter); | 4360 | iter->trace->pipe_open(iter); |
| 4364 | 4361 | ||
| 4365 | nonseekable_open(inode, filp); | 4362 | nonseekable_open(inode, filp); |
| 4363 | |||
| 4364 | tr->current_trace->ref++; | ||
| 4366 | out: | 4365 | out: |
| 4367 | mutex_unlock(&trace_types_lock); | 4366 | mutex_unlock(&trace_types_lock); |
| 4368 | return ret; | 4367 | return ret; |
| @@ -4382,6 +4381,8 @@ static int tracing_release_pipe(struct inode *inode, struct file *file) | |||
| 4382 | 4381 | ||
| 4383 | mutex_lock(&trace_types_lock); | 4382 | mutex_lock(&trace_types_lock); |
| 4384 | 4383 | ||
| 4384 | tr->current_trace->ref--; | ||
| 4385 | |||
| 4385 | if (iter->trace->pipe_close) | 4386 | if (iter->trace->pipe_close) |
| 4386 | iter->trace->pipe_close(iter); | 4387 | iter->trace->pipe_close(iter); |
| 4387 | 4388 | ||
| @@ -4389,7 +4390,6 @@ static int tracing_release_pipe(struct inode *inode, struct file *file) | |||
| 4389 | 4390 | ||
| 4390 | free_cpumask_var(iter->started); | 4391 | free_cpumask_var(iter->started); |
| 4391 | mutex_destroy(&iter->mutex); | 4392 | mutex_destroy(&iter->mutex); |
| 4392 | kfree(iter->trace); | ||
| 4393 | kfree(iter); | 4393 | kfree(iter); |
| 4394 | 4394 | ||
| 4395 | trace_array_put(tr); | 4395 | trace_array_put(tr); |
| @@ -4422,7 +4422,7 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table) | |||
| 4422 | return trace_poll(iter, filp, poll_table); | 4422 | return trace_poll(iter, filp, poll_table); |
| 4423 | } | 4423 | } |
| 4424 | 4424 | ||
| 4425 | /* Must be called with trace_types_lock mutex held. */ | 4425 | /* Must be called with iter->mutex held. */ |
| 4426 | static int tracing_wait_pipe(struct file *filp) | 4426 | static int tracing_wait_pipe(struct file *filp) |
| 4427 | { | 4427 | { |
| 4428 | struct trace_iterator *iter = filp->private_data; | 4428 | struct trace_iterator *iter = filp->private_data; |
| @@ -4467,7 +4467,6 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, | |||
| 4467 | size_t cnt, loff_t *ppos) | 4467 | size_t cnt, loff_t *ppos) |
| 4468 | { | 4468 | { |
| 4469 | struct trace_iterator *iter = filp->private_data; | 4469 | struct trace_iterator *iter = filp->private_data; |
| 4470 | struct trace_array *tr = iter->tr; | ||
| 4471 | ssize_t sret; | 4470 | ssize_t sret; |
| 4472 | 4471 | ||
| 4473 | /* return any leftover data */ | 4472 | /* return any leftover data */ |
| @@ -4477,12 +4476,6 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, | |||
| 4477 | 4476 | ||
| 4478 | trace_seq_init(&iter->seq); | 4477 | trace_seq_init(&iter->seq); |
| 4479 | 4478 | ||
| 4480 | /* copy the tracer to avoid using a global lock all around */ | ||
| 4481 | mutex_lock(&trace_types_lock); | ||
| 4482 | if (unlikely(iter->trace->name != tr->current_trace->name)) | ||
| 4483 | *iter->trace = *tr->current_trace; | ||
| 4484 | mutex_unlock(&trace_types_lock); | ||
| 4485 | |||
| 4486 | /* | 4479 | /* |
| 4487 | * Avoid more than one consumer on a single file descriptor | 4480 | * Avoid more than one consumer on a single file descriptor |
| 4488 | * This is just a matter of traces coherency, the ring buffer itself | 4481 | * This is just a matter of traces coherency, the ring buffer itself |
| @@ -4642,7 +4635,6 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
| 4642 | .ops = &tracing_pipe_buf_ops, | 4635 | .ops = &tracing_pipe_buf_ops, |
| 4643 | .spd_release = tracing_spd_release_pipe, | 4636 | .spd_release = tracing_spd_release_pipe, |
| 4644 | }; | 4637 | }; |
| 4645 | struct trace_array *tr = iter->tr; | ||
| 4646 | ssize_t ret; | 4638 | ssize_t ret; |
| 4647 | size_t rem; | 4639 | size_t rem; |
| 4648 | unsigned int i; | 4640 | unsigned int i; |
| @@ -4650,12 +4642,6 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
| 4650 | if (splice_grow_spd(pipe, &spd)) | 4642 | if (splice_grow_spd(pipe, &spd)) |
| 4651 | return -ENOMEM; | 4643 | return -ENOMEM; |
| 4652 | 4644 | ||
| 4653 | /* copy the tracer to avoid using a global lock all around */ | ||
| 4654 | mutex_lock(&trace_types_lock); | ||
| 4655 | if (unlikely(iter->trace->name != tr->current_trace->name)) | ||
| 4656 | *iter->trace = *tr->current_trace; | ||
| 4657 | mutex_unlock(&trace_types_lock); | ||
| 4658 | |||
| 4659 | mutex_lock(&iter->mutex); | 4645 | mutex_lock(&iter->mutex); |
| 4660 | 4646 | ||
| 4661 | if (iter->trace->splice_read) { | 4647 | if (iter->trace->splice_read) { |
| @@ -4942,7 +4928,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, | |||
| 4942 | *fpos += written; | 4928 | *fpos += written; |
| 4943 | 4929 | ||
| 4944 | out_unlock: | 4930 | out_unlock: |
| 4945 | for (i = 0; i < nr_pages; i++){ | 4931 | for (i = nr_pages - 1; i >= 0; i--) { |
| 4946 | kunmap_atomic(map_page[i]); | 4932 | kunmap_atomic(map_page[i]); |
| 4947 | put_page(pages[i]); | 4933 | put_page(pages[i]); |
| 4948 | } | 4934 | } |
| @@ -5331,6 +5317,8 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) | |||
| 5331 | 5317 | ||
| 5332 | filp->private_data = info; | 5318 | filp->private_data = info; |
| 5333 | 5319 | ||
| 5320 | tr->current_trace->ref++; | ||
| 5321 | |||
| 5334 | mutex_unlock(&trace_types_lock); | 5322 | mutex_unlock(&trace_types_lock); |
| 5335 | 5323 | ||
| 5336 | ret = nonseekable_open(inode, filp); | 5324 | ret = nonseekable_open(inode, filp); |
| @@ -5361,21 +5349,16 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, | |||
| 5361 | if (!count) | 5349 | if (!count) |
| 5362 | return 0; | 5350 | return 0; |
| 5363 | 5351 | ||
| 5364 | mutex_lock(&trace_types_lock); | ||
| 5365 | |||
| 5366 | #ifdef CONFIG_TRACER_MAX_TRACE | 5352 | #ifdef CONFIG_TRACER_MAX_TRACE |
| 5367 | if (iter->snapshot && iter->tr->current_trace->use_max_tr) { | 5353 | if (iter->snapshot && iter->tr->current_trace->use_max_tr) |
| 5368 | size = -EBUSY; | 5354 | return -EBUSY; |
| 5369 | goto out_unlock; | ||
| 5370 | } | ||
| 5371 | #endif | 5355 | #endif |
| 5372 | 5356 | ||
| 5373 | if (!info->spare) | 5357 | if (!info->spare) |
| 5374 | info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer, | 5358 | info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer, |
| 5375 | iter->cpu_file); | 5359 | iter->cpu_file); |
| 5376 | size = -ENOMEM; | ||
| 5377 | if (!info->spare) | 5360 | if (!info->spare) |
| 5378 | goto out_unlock; | 5361 | return -ENOMEM; |
| 5379 | 5362 | ||
| 5380 | /* Do we have previous read data to read? */ | 5363 | /* Do we have previous read data to read? */ |
| 5381 | if (info->read < PAGE_SIZE) | 5364 | if (info->read < PAGE_SIZE) |
| @@ -5391,21 +5374,16 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, | |||
| 5391 | 5374 | ||
| 5392 | if (ret < 0) { | 5375 | if (ret < 0) { |
| 5393 | if (trace_empty(iter)) { | 5376 | if (trace_empty(iter)) { |
| 5394 | if ((filp->f_flags & O_NONBLOCK)) { | 5377 | if ((filp->f_flags & O_NONBLOCK)) |
| 5395 | size = -EAGAIN; | 5378 | return -EAGAIN; |
| 5396 | goto out_unlock; | 5379 | |
| 5397 | } | ||
| 5398 | mutex_unlock(&trace_types_lock); | ||
| 5399 | ret = wait_on_pipe(iter, false); | 5380 | ret = wait_on_pipe(iter, false); |
| 5400 | mutex_lock(&trace_types_lock); | 5381 | if (ret) |
| 5401 | if (ret) { | 5382 | return ret; |
| 5402 | size = ret; | 5383 | |
| 5403 | goto out_unlock; | ||
| 5404 | } | ||
| 5405 | goto again; | 5384 | goto again; |
| 5406 | } | 5385 | } |
| 5407 | size = 0; | 5386 | return 0; |
| 5408 | goto out_unlock; | ||
| 5409 | } | 5387 | } |
| 5410 | 5388 | ||
| 5411 | info->read = 0; | 5389 | info->read = 0; |
| @@ -5415,18 +5393,14 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, | |||
| 5415 | size = count; | 5393 | size = count; |
| 5416 | 5394 | ||
| 5417 | ret = copy_to_user(ubuf, info->spare + info->read, size); | 5395 | ret = copy_to_user(ubuf, info->spare + info->read, size); |
| 5418 | if (ret == size) { | 5396 | if (ret == size) |
| 5419 | size = -EFAULT; | 5397 | return -EFAULT; |
| 5420 | goto out_unlock; | 5398 | |
| 5421 | } | ||
| 5422 | size -= ret; | 5399 | size -= ret; |
| 5423 | 5400 | ||
| 5424 | *ppos += size; | 5401 | *ppos += size; |
| 5425 | info->read += size; | 5402 | info->read += size; |
| 5426 | 5403 | ||
| 5427 | out_unlock: | ||
| 5428 | mutex_unlock(&trace_types_lock); | ||
| 5429 | |||
| 5430 | return size; | 5404 | return size; |
| 5431 | } | 5405 | } |
| 5432 | 5406 | ||
| @@ -5437,6 +5411,8 @@ static int tracing_buffers_release(struct inode *inode, struct file *file) | |||
| 5437 | 5411 | ||
| 5438 | mutex_lock(&trace_types_lock); | 5412 | mutex_lock(&trace_types_lock); |
| 5439 | 5413 | ||
| 5414 | iter->tr->current_trace->ref--; | ||
| 5415 | |||
| 5440 | __trace_array_put(iter->tr); | 5416 | __trace_array_put(iter->tr); |
| 5441 | 5417 | ||
| 5442 | if (info->spare) | 5418 | if (info->spare) |
| @@ -5522,30 +5498,20 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
| 5522 | int entries, size, i; | 5498 | int entries, size, i; |
| 5523 | ssize_t ret = 0; | 5499 | ssize_t ret = 0; |
| 5524 | 5500 | ||
| 5525 | mutex_lock(&trace_types_lock); | ||
| 5526 | |||
| 5527 | #ifdef CONFIG_TRACER_MAX_TRACE | 5501 | #ifdef CONFIG_TRACER_MAX_TRACE |
| 5528 | if (iter->snapshot && iter->tr->current_trace->use_max_tr) { | 5502 | if (iter->snapshot && iter->tr->current_trace->use_max_tr) |
| 5529 | ret = -EBUSY; | 5503 | return -EBUSY; |
| 5530 | goto out; | ||
| 5531 | } | ||
| 5532 | #endif | 5504 | #endif |
| 5533 | 5505 | ||
| 5534 | if (splice_grow_spd(pipe, &spd)) { | 5506 | if (splice_grow_spd(pipe, &spd)) |
| 5535 | ret = -ENOMEM; | 5507 | return -ENOMEM; |
| 5536 | goto out; | ||
| 5537 | } | ||
| 5538 | 5508 | ||
| 5539 | if (*ppos & (PAGE_SIZE - 1)) { | 5509 | if (*ppos & (PAGE_SIZE - 1)) |
| 5540 | ret = -EINVAL; | 5510 | return -EINVAL; |
| 5541 | goto out; | ||
| 5542 | } | ||
| 5543 | 5511 | ||
| 5544 | if (len & (PAGE_SIZE - 1)) { | 5512 | if (len & (PAGE_SIZE - 1)) { |
| 5545 | if (len < PAGE_SIZE) { | 5513 | if (len < PAGE_SIZE) |
| 5546 | ret = -EINVAL; | 5514 | return -EINVAL; |
| 5547 | goto out; | ||
| 5548 | } | ||
| 5549 | len &= PAGE_MASK; | 5515 | len &= PAGE_MASK; |
| 5550 | } | 5516 | } |
| 5551 | 5517 | ||
| @@ -5606,25 +5572,20 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
| 5606 | /* did we read anything? */ | 5572 | /* did we read anything? */ |
| 5607 | if (!spd.nr_pages) { | 5573 | if (!spd.nr_pages) { |
| 5608 | if (ret) | 5574 | if (ret) |
| 5609 | goto out; | 5575 | return ret; |
| 5576 | |||
| 5577 | if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) | ||
| 5578 | return -EAGAIN; | ||
| 5610 | 5579 | ||
| 5611 | if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) { | ||
| 5612 | ret = -EAGAIN; | ||
| 5613 | goto out; | ||
| 5614 | } | ||
| 5615 | mutex_unlock(&trace_types_lock); | ||
| 5616 | ret = wait_on_pipe(iter, true); | 5580 | ret = wait_on_pipe(iter, true); |
| 5617 | mutex_lock(&trace_types_lock); | ||
| 5618 | if (ret) | 5581 | if (ret) |
| 5619 | goto out; | 5582 | return ret; |
| 5620 | 5583 | ||
| 5621 | goto again; | 5584 | goto again; |
| 5622 | } | 5585 | } |
| 5623 | 5586 | ||
| 5624 | ret = splice_to_pipe(pipe, &spd); | 5587 | ret = splice_to_pipe(pipe, &spd); |
| 5625 | splice_shrink_spd(&spd); | 5588 | splice_shrink_spd(&spd); |
| 5626 | out: | ||
| 5627 | mutex_unlock(&trace_types_lock); | ||
| 5628 | 5589 | ||
| 5629 | return ret; | 5590 | return ret; |
| 5630 | } | 5591 | } |
| @@ -5854,28 +5815,11 @@ static __init int register_snapshot_cmd(void) | |||
| 5854 | static inline __init int register_snapshot_cmd(void) { return 0; } | 5815 | static inline __init int register_snapshot_cmd(void) { return 0; } |
| 5855 | #endif /* defined(CONFIG_TRACER_SNAPSHOT) && defined(CONFIG_DYNAMIC_FTRACE) */ | 5816 | #endif /* defined(CONFIG_TRACER_SNAPSHOT) && defined(CONFIG_DYNAMIC_FTRACE) */ |
| 5856 | 5817 | ||
| 5857 | struct dentry *tracing_init_dentry_tr(struct trace_array *tr) | 5818 | static struct dentry *tracing_get_dentry(struct trace_array *tr) |
| 5858 | { | 5819 | { |
| 5859 | if (tr->dir) | ||
| 5860 | return tr->dir; | ||
| 5861 | |||
| 5862 | if (!debugfs_initialized()) | ||
| 5863 | return NULL; | ||
| 5864 | |||
| 5865 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL) | ||
| 5866 | tr->dir = debugfs_create_dir("tracing", NULL); | ||
| 5867 | |||
| 5868 | if (!tr->dir) | ||
| 5869 | pr_warn_once("Could not create debugfs directory 'tracing'\n"); | ||
| 5870 | |||
| 5871 | return tr->dir; | 5820 | return tr->dir; |
| 5872 | } | 5821 | } |
| 5873 | 5822 | ||
| 5874 | struct dentry *tracing_init_dentry(void) | ||
| 5875 | { | ||
| 5876 | return tracing_init_dentry_tr(&global_trace); | ||
| 5877 | } | ||
| 5878 | |||
| 5879 | static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu) | 5823 | static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu) |
| 5880 | { | 5824 | { |
| 5881 | struct dentry *d_tracer; | 5825 | struct dentry *d_tracer; |
| @@ -5883,8 +5827,8 @@ static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu) | |||
| 5883 | if (tr->percpu_dir) | 5827 | if (tr->percpu_dir) |
| 5884 | return tr->percpu_dir; | 5828 | return tr->percpu_dir; |
| 5885 | 5829 | ||
| 5886 | d_tracer = tracing_init_dentry_tr(tr); | 5830 | d_tracer = tracing_get_dentry(tr); |
| 5887 | if (!d_tracer) | 5831 | if (IS_ERR(d_tracer)) |
| 5888 | return NULL; | 5832 | return NULL; |
| 5889 | 5833 | ||
| 5890 | tr->percpu_dir = debugfs_create_dir("per_cpu", d_tracer); | 5834 | tr->percpu_dir = debugfs_create_dir("per_cpu", d_tracer); |
| @@ -6086,8 +6030,8 @@ static struct dentry *trace_options_init_dentry(struct trace_array *tr) | |||
| 6086 | if (tr->options) | 6030 | if (tr->options) |
| 6087 | return tr->options; | 6031 | return tr->options; |
| 6088 | 6032 | ||
| 6089 | d_tracer = tracing_init_dentry_tr(tr); | 6033 | d_tracer = tracing_get_dentry(tr); |
| 6090 | if (!d_tracer) | 6034 | if (IS_ERR(d_tracer)) |
| 6091 | return NULL; | 6035 | return NULL; |
| 6092 | 6036 | ||
| 6093 | tr->options = debugfs_create_dir("options", d_tracer); | 6037 | tr->options = debugfs_create_dir("options", d_tracer); |
| @@ -6416,7 +6360,7 @@ static int instance_delete(const char *name) | |||
| 6416 | goto out_unlock; | 6360 | goto out_unlock; |
| 6417 | 6361 | ||
| 6418 | ret = -EBUSY; | 6362 | ret = -EBUSY; |
| 6419 | if (tr->ref) | 6363 | if (tr->ref || (tr->current_trace && tr->current_trace->ref)) |
| 6420 | goto out_unlock; | 6364 | goto out_unlock; |
| 6421 | 6365 | ||
| 6422 | list_del(&tr->list); | 6366 | list_del(&tr->list); |
| @@ -6571,6 +6515,33 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) | |||
| 6571 | 6515 | ||
| 6572 | } | 6516 | } |
| 6573 | 6517 | ||
| 6518 | /** | ||
| 6519 | * tracing_init_dentry - initialize top level trace array | ||
| 6520 | * | ||
| 6521 | * This is called when creating files or directories in the tracing | ||
| 6522 | * directory. It is called via fs_initcall() by any of the boot up code | ||
| 6523 | * and expects to return the dentry of the top level tracing directory. | ||
| 6524 | */ | ||
| 6525 | struct dentry *tracing_init_dentry(void) | ||
| 6526 | { | ||
| 6527 | struct trace_array *tr = &global_trace; | ||
| 6528 | |||
| 6529 | if (tr->dir) | ||
| 6530 | return tr->dir; | ||
| 6531 | |||
| 6532 | if (WARN_ON(!debugfs_initialized())) | ||
| 6533 | return ERR_PTR(-ENODEV); | ||
| 6534 | |||
| 6535 | tr->dir = debugfs_create_dir("tracing", NULL); | ||
| 6536 | |||
| 6537 | if (!tr->dir) { | ||
| 6538 | pr_warn_once("Could not create debugfs directory 'tracing'\n"); | ||
| 6539 | return ERR_PTR(-ENOMEM); | ||
| 6540 | } | ||
| 6541 | |||
| 6542 | return tr->dir; | ||
| 6543 | } | ||
| 6544 | |||
| 6574 | static __init int tracer_init_debugfs(void) | 6545 | static __init int tracer_init_debugfs(void) |
| 6575 | { | 6546 | { |
| 6576 | struct dentry *d_tracer; | 6547 | struct dentry *d_tracer; |
| @@ -6578,7 +6549,7 @@ static __init int tracer_init_debugfs(void) | |||
| 6578 | trace_access_lock_init(); | 6549 | trace_access_lock_init(); |
| 6579 | 6550 | ||
| 6580 | d_tracer = tracing_init_dentry(); | 6551 | d_tracer = tracing_init_dentry(); |
| 6581 | if (!d_tracer) | 6552 | if (IS_ERR(d_tracer)) |
| 6582 | return 0; | 6553 | return 0; |
| 6583 | 6554 | ||
| 6584 | init_tracer_debugfs(&global_trace, d_tracer); | 6555 | init_tracer_debugfs(&global_trace, d_tracer); |
| @@ -6811,7 +6782,6 @@ __init static int tracer_alloc_buffers(void) | |||
| 6811 | int ring_buf_size; | 6782 | int ring_buf_size; |
| 6812 | int ret = -ENOMEM; | 6783 | int ret = -ENOMEM; |
| 6813 | 6784 | ||
| 6814 | |||
| 6815 | if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL)) | 6785 | if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL)) |
| 6816 | goto out; | 6786 | goto out; |
| 6817 | 6787 | ||
