Skip to content

Commit b1e7a59

Browse files
committed
ring-buffer: Add helper functions for allocations
The allocation of the per CPU buffer descriptor, the buffer page descriptors and the buffer page data itself can be pretty ugly: kzalloc_node(ALIGN(sizeof(struct buffer_page), cache_line_size()), GFP_KERNEL, cpu_to_node(cpu)); And the data pages: page = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO, order); if (!page) return NULL; bpage->page = page_address(page); rb_init_page(bpage->page); Add helper functions to make the code easier to read. This does make all allocations of the data page (bpage->page) allocated with the __GFP_RETRY_MAYFAIL flag (and not just the bulk allocator). Which is actually better, as allocating the data page for the ring buffer tracing should try hard but not trigger the OOM killer. Link: https://lore.kernel.org/all/CAHk-=wjMMSAaqTjBSfYenfuzE1bMjLj+2DLtLWJuGt07UGCH_Q@mail.gmail.com/ Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://patch.msgid.link/20251125121153.35c07461@gandalf.local.home Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent dcb6fa3 commit b1e7a59

1 file changed

Lines changed: 53 additions & 44 deletions

File tree

kernel/trace/ring_buffer.c

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,41 @@ static void free_buffer_page(struct buffer_page *bpage)
401401
kfree(bpage);
402402
}
403403

404+
/*
405+
* For best performance, allocate cpu buffer data cache line sized
406+
* and per CPU.
407+
*/
408+
#define alloc_cpu_buffer(cpu) (struct ring_buffer_per_cpu *) \
409+
kzalloc_node(ALIGN(sizeof(struct ring_buffer_per_cpu), \
410+
cache_line_size()), GFP_KERNEL, cpu_to_node(cpu));
411+
412+
#define alloc_cpu_page(cpu) (struct buffer_page *) \
413+
kzalloc_node(ALIGN(sizeof(struct buffer_page), \
414+
cache_line_size()), GFP_KERNEL, cpu_to_node(cpu));
415+
416+
static struct buffer_data_page *alloc_cpu_data(int cpu, int order)
417+
{
418+
struct buffer_data_page *dpage;
419+
struct page *page;
420+
gfp_t mflags;
421+
422+
/*
423+
* __GFP_RETRY_MAYFAIL flag makes sure that the allocation fails
424+
* gracefully without invoking oom-killer and the system is not
425+
* destabilized.
426+
*/
427+
mflags = GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO;
428+
429+
page = alloc_pages_node(cpu_to_node(cpu), mflags, order);
430+
if (!page)
431+
return NULL;
432+
433+
dpage = page_address(page);
434+
rb_init_page(dpage);
435+
436+
return dpage;
437+
}
438+
404439
/*
405440
* We need to fit the time_stamp delta into 27 bits.
406441
*/
@@ -2204,7 +2239,6 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
22042239
struct ring_buffer_cpu_meta *meta = NULL;
22052240
struct buffer_page *bpage, *tmp;
22062241
bool user_thread = current->mm != NULL;
2207-
gfp_t mflags;
22082242
long i;
22092243

22102244
/*
@@ -2218,13 +2252,6 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
22182252
if (i < nr_pages)
22192253
return -ENOMEM;
22202254

2221-
/*
2222-
* __GFP_RETRY_MAYFAIL flag makes sure that the allocation fails
2223-
* gracefully without invoking oom-killer and the system is not
2224-
* destabilized.
2225-
*/
2226-
mflags = GFP_KERNEL | __GFP_RETRY_MAYFAIL;
2227-
22282255
/*
22292256
* If a user thread allocates too much, and si_mem_available()
22302257
* reports there's enough memory, even though there is not.
@@ -2241,10 +2268,8 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
22412268
meta = rb_range_meta(buffer, nr_pages, cpu_buffer->cpu);
22422269

22432270
for (i = 0; i < nr_pages; i++) {
2244-
struct page *page;
22452271

2246-
bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()),
2247-
mflags, cpu_to_node(cpu_buffer->cpu));
2272+
bpage = alloc_cpu_page(cpu_buffer->cpu);
22482273
if (!bpage)
22492274
goto free_pages;
22502275

@@ -2267,13 +2292,10 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
22672292
bpage->range = 1;
22682293
bpage->id = i + 1;
22692294
} else {
2270-
page = alloc_pages_node(cpu_to_node(cpu_buffer->cpu),
2271-
mflags | __GFP_COMP | __GFP_ZERO,
2272-
cpu_buffer->buffer->subbuf_order);
2273-
if (!page)
2295+
int order = cpu_buffer->buffer->subbuf_order;
2296+
bpage->page = alloc_cpu_data(cpu_buffer->cpu, order);
2297+
if (!bpage->page)
22742298
goto free_pages;
2275-
bpage->page = page_address(page);
2276-
rb_init_page(bpage->page);
22772299
}
22782300
bpage->order = cpu_buffer->buffer->subbuf_order;
22792301

@@ -2324,14 +2346,12 @@ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
23242346
static struct ring_buffer_per_cpu *
23252347
rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
23262348
{
2327-
struct ring_buffer_per_cpu *cpu_buffer __free(kfree) = NULL;
2349+
struct ring_buffer_per_cpu *cpu_buffer __free(kfree) =
2350+
alloc_cpu_buffer(cpu);
23282351
struct ring_buffer_cpu_meta *meta;
23292352
struct buffer_page *bpage;
2330-
struct page *page;
23312353
int ret;
23322354

2333-
cpu_buffer = kzalloc_node(ALIGN(sizeof(*cpu_buffer), cache_line_size()),
2334-
GFP_KERNEL, cpu_to_node(cpu));
23352355
if (!cpu_buffer)
23362356
return NULL;
23372357

@@ -2347,8 +2367,7 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
23472367
init_waitqueue_head(&cpu_buffer->irq_work.full_waiters);
23482368
mutex_init(&cpu_buffer->mapping_lock);
23492369

2350-
bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()),
2351-
GFP_KERNEL, cpu_to_node(cpu));
2370+
bpage = alloc_cpu_page(cpu);
23522371
if (!bpage)
23532372
return NULL;
23542373

@@ -2370,13 +2389,10 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
23702389
rb_meta_buffer_update(cpu_buffer, bpage);
23712390
bpage->range = 1;
23722391
} else {
2373-
page = alloc_pages_node(cpu_to_node(cpu),
2374-
GFP_KERNEL | __GFP_COMP | __GFP_ZERO,
2375-
cpu_buffer->buffer->subbuf_order);
2376-
if (!page)
2392+
int order = cpu_buffer->buffer->subbuf_order;
2393+
bpage->page = alloc_cpu_data(cpu, order);
2394+
if (!bpage->page)
23772395
goto fail_free_reader;
2378-
bpage->page = page_address(page);
2379-
rb_init_page(bpage->page);
23802396
}
23812397

23822398
INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
@@ -6464,7 +6480,6 @@ ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu)
64646480
struct ring_buffer_per_cpu *cpu_buffer;
64656481
struct buffer_data_read_page *bpage = NULL;
64666482
unsigned long flags;
6467-
struct page *page;
64686483

64696484
if (!cpumask_test_cpu(cpu, buffer->cpumask))
64706485
return ERR_PTR(-ENODEV);
@@ -6486,22 +6501,16 @@ ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu)
64866501
arch_spin_unlock(&cpu_buffer->lock);
64876502
local_irq_restore(flags);
64886503

6489-
if (bpage->data)
6490-
goto out;
6491-
6492-
page = alloc_pages_node(cpu_to_node(cpu),
6493-
GFP_KERNEL | __GFP_NORETRY | __GFP_COMP | __GFP_ZERO,
6494-
cpu_buffer->buffer->subbuf_order);
6495-
if (!page) {
6496-
kfree(bpage);
6497-
return ERR_PTR(-ENOMEM);
6504+
if (bpage->data) {
6505+
rb_init_page(bpage->data);
6506+
} else {
6507+
bpage->data = alloc_cpu_data(cpu, cpu_buffer->buffer->subbuf_order);
6508+
if (!bpage->data) {
6509+
kfree(bpage);
6510+
return ERR_PTR(-ENOMEM);
6511+
}
64986512
}
64996513

6500-
bpage->data = page_address(page);
6501-
6502-
out:
6503-
rb_init_page(bpage->data);
6504-
65056514
return bpage;
65066515
}
65076516
EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);

0 commit comments

Comments
 (0)