aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ring_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/ring_buffer.c')
-rw-r--r--kernel/trace/ring_buffer.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index ca47a4fa2986..4ae268e687fe 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -438,6 +438,7 @@ struct ring_buffer_per_cpu {
438 raw_spinlock_t reader_lock; /* serialize readers */ 438 raw_spinlock_t reader_lock; /* serialize readers */
439 arch_spinlock_t lock; 439 arch_spinlock_t lock;
440 struct lock_class_key lock_key; 440 struct lock_class_key lock_key;
441 struct buffer_data_page *free_page;
441 unsigned long nr_pages; 442 unsigned long nr_pages;
442 unsigned int current_context; 443 unsigned int current_context;
443 struct list_head *pages; 444 struct list_head *pages;
@@ -4389,9 +4390,25 @@ EXPORT_SYMBOL_GPL(ring_buffer_swap_cpu);
4389 */ 4390 */
4390void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu) 4391void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu)
4391{ 4392{
4392 struct buffer_data_page *bpage; 4393 struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
4394 struct buffer_data_page *bpage = NULL;
4395 unsigned long flags;
4393 struct page *page; 4396 struct page *page;
4394 4397
4398 local_irq_save(flags);
4399 arch_spin_lock(&cpu_buffer->lock);
4400
4401 if (cpu_buffer->free_page) {
4402 bpage = cpu_buffer->free_page;
4403 cpu_buffer->free_page = NULL;
4404 }
4405
4406 arch_spin_unlock(&cpu_buffer->lock);
4407 local_irq_restore(flags);
4408
4409 if (bpage)
4410 goto out;
4411
4395 page = alloc_pages_node(cpu_to_node(cpu), 4412 page = alloc_pages_node(cpu_to_node(cpu),
4396 GFP_KERNEL | __GFP_NORETRY, 0); 4413 GFP_KERNEL | __GFP_NORETRY, 0);
4397 if (!page) 4414 if (!page)
@@ -4399,6 +4416,7 @@ void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu)
4399 4416
4400 bpage = page_address(page); 4417 bpage = page_address(page);
4401 4418
4419 out:
4402 rb_init_page(bpage); 4420 rb_init_page(bpage);
4403 4421
4404 return bpage; 4422 return bpage;
@@ -4408,13 +4426,29 @@ EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);
4408/** 4426/**
4409 * ring_buffer_free_read_page - free an allocated read page 4427 * ring_buffer_free_read_page - free an allocated read page
4410 * @buffer: the buffer the page was allocate for 4428 * @buffer: the buffer the page was allocate for
4429 * @cpu: the cpu buffer the page came from
4411 * @data: the page to free 4430 * @data: the page to free
4412 * 4431 *
4413 * Free a page allocated from ring_buffer_alloc_read_page. 4432 * Free a page allocated from ring_buffer_alloc_read_page.
4414 */ 4433 */
4415void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data) 4434void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data)
4416{ 4435{
4417 free_page((unsigned long)data); 4436 struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
4437 struct buffer_data_page *bpage = data;
4438 unsigned long flags;
4439
4440 local_irq_save(flags);
4441 arch_spin_lock(&cpu_buffer->lock);
4442
4443 if (!cpu_buffer->free_page) {
4444 cpu_buffer->free_page = bpage;
4445 bpage = NULL;
4446 }
4447
4448 arch_spin_unlock(&cpu_buffer->lock);
4449 local_irq_restore(flags);
4450
4451 free_page((unsigned long)bpage);
4418} 4452}
4419EXPORT_SYMBOL_GPL(ring_buffer_free_read_page); 4453EXPORT_SYMBOL_GPL(ring_buffer_free_read_page);
4420 4454