Skip to content

Commit 07b8b10

Browse files
committed
ring-buffer: Make resize disable per cpu buffer instead of total buffer
When the ring buffer becomes writable for even when the trace file is read, it must still not be resized. But since tracers can be activated while the trace file is being read, the irqsoff tracer can modify the per CPU buffers, and this can cause the reader of the trace file to update the wrong buffer's resize disable bit, as the irqsoff tracer swaps out cpu buffers. By making the resize disable per cpu_buffer, it makes the update follow the per cpu_buffer even if it's swapped out with the snapshot buffer and keeps the release of the trace file modifying the same data as the open did. Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 153368c commit 07b8b10

File tree

1 file changed

+30
-13
lines changed

1 file changed

+30
-13
lines changed

kernel/trace/ring_buffer.c

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ enum {
441441
struct ring_buffer_per_cpu {
442442
int cpu;
443443
atomic_t record_disabled;
444+
atomic_t resize_disabled;
444445
struct trace_buffer *buffer;
445446
raw_spinlock_t reader_lock; /* serialize readers */
446447
arch_spinlock_t lock;
@@ -484,7 +485,6 @@ struct trace_buffer {
484485
unsigned flags;
485486
int cpus;
486487
atomic_t record_disabled;
487-
atomic_t resize_disabled;
488488
cpumask_var_t cpumask;
489489

490490
struct lock_class_key *reader_lock_key;
@@ -1740,18 +1740,24 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
17401740

17411741
size = nr_pages * BUF_PAGE_SIZE;
17421742

1743-
/*
1744-
* Don't succeed if resizing is disabled, as a reader might be
1745-
* manipulating the ring buffer and is expecting a sane state while
1746-
* this is true.
1747-
*/
1748-
if (atomic_read(&buffer->resize_disabled))
1749-
return -EBUSY;
1750-
17511743
/* prevent another thread from changing buffer sizes */
17521744
mutex_lock(&buffer->mutex);
17531745

1746+
17541747
if (cpu_id == RING_BUFFER_ALL_CPUS) {
1748+
/*
1749+
* Don't succeed if resizing is disabled, as a reader might be
1750+
* manipulating the ring buffer and is expecting a sane state while
1751+
* this is true.
1752+
*/
1753+
for_each_buffer_cpu(buffer, cpu) {
1754+
cpu_buffer = buffer->buffers[cpu];
1755+
if (atomic_read(&cpu_buffer->resize_disabled)) {
1756+
err = -EBUSY;
1757+
goto out_err_unlock;
1758+
}
1759+
}
1760+
17551761
/* calculate the pages to update */
17561762
for_each_buffer_cpu(buffer, cpu) {
17571763
cpu_buffer = buffer->buffers[cpu];
@@ -1819,6 +1825,16 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
18191825
if (nr_pages == cpu_buffer->nr_pages)
18201826
goto out;
18211827

1828+
/*
1829+
* Don't succeed if resizing is disabled, as a reader might be
1830+
* manipulating the ring buffer and is expecting a sane state while
1831+
* this is true.
1832+
*/
1833+
if (atomic_read(&cpu_buffer->resize_disabled)) {
1834+
err = -EBUSY;
1835+
goto out_err_unlock;
1836+
}
1837+
18221838
cpu_buffer->nr_pages_to_update = nr_pages -
18231839
cpu_buffer->nr_pages;
18241840

@@ -1888,6 +1904,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
18881904
free_buffer_page(bpage);
18891905
}
18901906
}
1907+
out_err_unlock:
18911908
mutex_unlock(&buffer->mutex);
18921909
return err;
18931910
}
@@ -4294,7 +4311,7 @@ ring_buffer_read_prepare(struct trace_buffer *buffer, int cpu, gfp_t flags)
42944311

42954312
iter->cpu_buffer = cpu_buffer;
42964313

4297-
atomic_inc(&buffer->resize_disabled);
4314+
atomic_inc(&cpu_buffer->resize_disabled);
42984315
atomic_inc(&cpu_buffer->record_disabled);
42994316

43004317
return iter;
@@ -4369,7 +4386,7 @@ ring_buffer_read_finish(struct ring_buffer_iter *iter)
43694386
raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
43704387

43714388
atomic_dec(&cpu_buffer->record_disabled);
4372-
atomic_dec(&cpu_buffer->buffer->resize_disabled);
4389+
atomic_dec(&cpu_buffer->resize_disabled);
43734390
kfree(iter->event);
43744391
kfree(iter);
43754392
}
@@ -4474,7 +4491,7 @@ void ring_buffer_reset_cpu(struct trace_buffer *buffer, int cpu)
44744491
if (!cpumask_test_cpu(cpu, buffer->cpumask))
44754492
return;
44764493

4477-
atomic_inc(&buffer->resize_disabled);
4494+
atomic_inc(&cpu_buffer->resize_disabled);
44784495
atomic_inc(&cpu_buffer->record_disabled);
44794496

44804497
/* Make sure all commits have finished */
@@ -4495,7 +4512,7 @@ void ring_buffer_reset_cpu(struct trace_buffer *buffer, int cpu)
44954512
raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
44964513

44974514
atomic_dec(&cpu_buffer->record_disabled);
4498-
atomic_dec(&buffer->resize_disabled);
4515+
atomic_dec(&cpu_buffer->resize_disabled);
44994516
}
45004517
EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu);
45014518

0 commit comments

Comments
 (0)