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: Non-consuming read for trace remotes with an offline CPU

When a trace_buffer is created while a CPU is offline, this CPU is
cleared from the trace_buffer CPU mask, preventing the creation of a
non-consuming iterator (ring_buffer_iter). For trace remotes, it means
the iterator fails to be allocated (-ENOMEM) even though there are
available ring buffers in the trace_buffer.

For non-consuming reads of trace remotes, skip missing ring_buffer_iter
to allow reading the available ring buffers.

Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Link: https://patch.msgid.link/20260401045100.3394299-2-vdonnefort@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>

authored by

Vincent Donnefort and committed by
Marc Zyngier
ce47b798 58b4bd18

+19 -3
+19 -3
kernel/trace/trace_remote.c
··· 282 282 trace_remote_try_unload(remote); 283 283 } 284 284 285 + static bool trace_remote_has_cpu(struct trace_remote *remote, int cpu) 286 + { 287 + if (cpu == RING_BUFFER_ALL_CPUS) 288 + return true; 289 + 290 + return ring_buffer_poll_remote(remote->trace_buffer, cpu) == 0; 291 + } 292 + 285 293 static void __poll_remote(struct work_struct *work) 286 294 { 287 295 struct delayed_work *dwork = to_delayed_work(work); ··· 332 324 iter->rb_iters[cpu] = ring_buffer_read_start(iter->remote->trace_buffer, cpu, 333 325 GFP_KERNEL); 334 326 if (!iter->rb_iters[cpu]) { 327 + /* This CPU isn't part of trace_buffer. Skip it */ 328 + if (!trace_remote_has_cpu(iter->remote, cpu)) 329 + continue; 330 + 335 331 __free_ring_buffer_iter(iter, RING_BUFFER_ALL_CPUS); 336 332 return -ENOMEM; 337 333 } ··· 359 347 if (ret) 360 348 return ERR_PTR(ret); 361 349 362 - /* Test the CPU */ 363 - ret = ring_buffer_poll_remote(remote->trace_buffer, cpu); 364 - if (ret) 350 + if (!trace_remote_has_cpu(remote, cpu)) { 351 + ret = -ENODEV; 365 352 goto err; 353 + } 366 354 367 355 iter = kzalloc_obj(*iter); 368 356 if (iter) { ··· 373 361 374 362 switch (type) { 375 363 case TRI_CONSUMING: 364 + ring_buffer_poll_remote(remote->trace_buffer, cpu); 376 365 INIT_DELAYED_WORK(&iter->poll_work, __poll_remote); 377 366 schedule_delayed_work(&iter->poll_work, msecs_to_jiffies(remote->poll_ms)); 378 367 break; ··· 489 476 return ring_buffer_peek(iter->remote->trace_buffer, cpu, ts, lost_events); 490 477 case TRI_NONCONSUMING: 491 478 rb_iter = __get_rb_iter(iter, cpu); 479 + if (!rb_iter) 480 + return NULL; 481 + 492 482 rb_evt = ring_buffer_iter_peek(rb_iter, ts); 493 483 if (!rb_evt) 494 484 return NULL;