Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tracing: load/unload page callbacks for simple_ring_buffer

Add load/unload callback used for each admitted page in the ring-buffer.
This will be later useful for the pKVM hypervisor which uses a different
VA space and need to dynamically map/unmap the ring-buffer pages.

Link: https://patch.msgid.link/20260309162516.2623589-18-vdonnefort@google.com
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Vincent Donnefort and committed by
Steven Rostedt (Google)
63592308 c88d5105

+112 -51
+8
include/linux/simple_ring_buffer.h
··· 54 54 55 55 int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buffer); 56 56 57 + int simple_ring_buffer_init_mm(struct simple_rb_per_cpu *cpu_buffer, 58 + struct simple_buffer_page *bpages, 59 + const struct ring_buffer_desc *desc, 60 + void *(*load_page)(unsigned long va), 61 + void (*unload_page)(void *va)); 62 + 63 + void simple_ring_buffer_unload_mm(struct simple_rb_per_cpu *cpu_buffer, 64 + void (*unload_page)(void *)); 57 65 #endif
+104 -51
kernel/trace/simple_ring_buffer.c
··· 71 71 local_set(&bpage->page->commit, 0); 72 72 } 73 73 74 - static void simple_bpage_init(struct simple_buffer_page *bpage, unsigned long page) 74 + static void simple_bpage_init(struct simple_buffer_page *bpage, void *page) 75 75 { 76 76 INIT_LIST_HEAD(&bpage->link); 77 77 bpage->page = (struct buffer_data_page *)page; ··· 372 372 } 373 373 EXPORT_SYMBOL_GPL(simple_ring_buffer_reset); 374 374 375 + int simple_ring_buffer_init_mm(struct simple_rb_per_cpu *cpu_buffer, 376 + struct simple_buffer_page *bpages, 377 + const struct ring_buffer_desc *desc, 378 + void *(*load_page)(unsigned long va), 379 + void (*unload_page)(void *va)) 380 + { 381 + struct simple_buffer_page *bpage = bpages; 382 + int ret = 0; 383 + void *page; 384 + int i; 385 + 386 + /* At least 1 reader page and two pages in the ring-buffer */ 387 + if (desc->nr_page_va < 3) 388 + return -EINVAL; 389 + 390 + memset(cpu_buffer, 0, sizeof(*cpu_buffer)); 391 + 392 + cpu_buffer->meta = load_page(desc->meta_va); 393 + if (!cpu_buffer->meta) 394 + return -EINVAL; 395 + 396 + memset(cpu_buffer->meta, 0, sizeof(*cpu_buffer->meta)); 397 + cpu_buffer->meta->meta_page_size = PAGE_SIZE; 398 + cpu_buffer->meta->nr_subbufs = cpu_buffer->nr_pages; 399 + 400 + /* The reader page is not part of the ring initially */ 401 + page = load_page(desc->page_va[0]); 402 + if (!page) { 403 + unload_page(cpu_buffer->meta); 404 + return -EINVAL; 405 + } 406 + 407 + simple_bpage_init(bpage, page); 408 + bpage->id = 0; 409 + 410 + cpu_buffer->nr_pages = 1; 411 + 412 + cpu_buffer->reader_page = bpage; 413 + cpu_buffer->tail_page = bpage + 1; 414 + cpu_buffer->head_page = bpage + 1; 415 + 416 + for (i = 1; i < desc->nr_page_va; i++) { 417 + page = load_page(desc->page_va[i]); 418 + if (!page) { 419 + ret = -EINVAL; 420 + break; 421 + } 422 + 423 + simple_bpage_init(++bpage, page); 424 + 425 + bpage->link.next = &(bpage + 1)->link; 426 + bpage->link.prev = &(bpage - 1)->link; 427 + bpage->id = i; 428 + 429 + cpu_buffer->nr_pages = i + 1; 430 + } 431 + 432 + if (ret) { 433 + for (i--; i >= 0; i--) 434 + unload_page((void *)desc->page_va[i]); 435 + unload_page(cpu_buffer->meta); 436 + 437 + return ret; 438 + } 439 + 440 + /* Close the ring */ 441 + bpage->link.next = &cpu_buffer->tail_page->link; 442 + cpu_buffer->tail_page->link.prev = &bpage->link; 443 + 444 + /* The last init'ed page points to the head page */ 445 + simple_bpage_set_head_link(bpage); 446 + 447 + cpu_buffer->bpages = bpages; 448 + 449 + return 0; 450 + } 451 + 452 + static void *__load_page(unsigned long page) 453 + { 454 + return (void *)page; 455 + } 456 + 457 + static void __unload_page(void *page) { } 458 + 375 459 /** 376 460 * simple_ring_buffer_init - Init @cpu_buffer based on @desc 377 461 * @cpu_buffer: A simple_rb_per_cpu buffer to init, allocated by the caller. ··· 467 383 int simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, struct simple_buffer_page *bpages, 468 384 const struct ring_buffer_desc *desc) 469 385 { 470 - struct simple_buffer_page *bpage = bpages; 471 - int i; 472 - 473 - /* At least 1 reader page and two pages in the ring-buffer */ 474 - if (desc->nr_page_va < 3) 475 - return -EINVAL; 476 - 477 - memset(cpu_buffer, 0, sizeof(*cpu_buffer)); 478 - 479 - cpu_buffer->bpages = bpages; 480 - 481 - cpu_buffer->meta = (void *)desc->meta_va; 482 - memset(cpu_buffer->meta, 0, sizeof(*cpu_buffer->meta)); 483 - cpu_buffer->meta->meta_page_size = PAGE_SIZE; 484 - cpu_buffer->meta->nr_subbufs = cpu_buffer->nr_pages; 485 - 486 - /* The reader page is not part of the ring initially */ 487 - simple_bpage_init(bpage, desc->page_va[0]); 488 - bpage->id = 0; 489 - 490 - cpu_buffer->nr_pages = 1; 491 - 492 - cpu_buffer->reader_page = bpage; 493 - cpu_buffer->tail_page = bpage + 1; 494 - cpu_buffer->head_page = bpage + 1; 495 - 496 - for (i = 1; i < desc->nr_page_va; i++) { 497 - simple_bpage_init(++bpage, desc->page_va[i]); 498 - 499 - bpage->link.next = &(bpage + 1)->link; 500 - bpage->link.prev = &(bpage - 1)->link; 501 - bpage->id = i; 502 - 503 - cpu_buffer->nr_pages = i + 1; 504 - } 505 - 506 - /* Close the ring */ 507 - bpage->link.next = &cpu_buffer->tail_page->link; 508 - cpu_buffer->tail_page->link.prev = &bpage->link; 509 - 510 - /* The last init'ed page points to the head page */ 511 - simple_bpage_set_head_link(bpage); 512 - 513 - return 0; 386 + return simple_ring_buffer_init_mm(cpu_buffer, bpages, desc, __load_page, __unload_page); 514 387 } 515 388 EXPORT_SYMBOL_GPL(simple_ring_buffer_init); 389 + 390 + void simple_ring_buffer_unload_mm(struct simple_rb_per_cpu *cpu_buffer, 391 + void (*unload_page)(void *)) 392 + { 393 + int p; 394 + 395 + if (!simple_rb_loaded(cpu_buffer)) 396 + return; 397 + 398 + simple_rb_enable_tracing(cpu_buffer, false); 399 + 400 + unload_page(cpu_buffer->meta); 401 + for (p = 0; p < cpu_buffer->nr_pages; p++) 402 + unload_page(cpu_buffer->bpages[p].page); 403 + 404 + cpu_buffer->bpages = NULL; 405 + } 516 406 517 407 /** 518 408 * simple_ring_buffer_unload - Prepare @cpu_buffer for deletion ··· 494 436 */ 495 437 void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer) 496 438 { 497 - if (!simple_rb_loaded(cpu_buffer)) 498 - return; 499 - 500 - simple_rb_enable_tracing(cpu_buffer, false); 501 - 502 - cpu_buffer->bpages = NULL; 439 + return simple_ring_buffer_unload_mm(cpu_buffer, __unload_page); 503 440 } 504 441 EXPORT_SYMBOL_GPL(simple_ring_buffer_unload); 505 442