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.

Merge tag 'trace-v4.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Pull tracing fixes from Steven Rostedt:
"Various fixes to the tracing infrastructure:

- Fix double free when the reg() call fails in
event_trigger_callback()

- Fix anomoly of snapshot causing tracing_on flag to change

- Add selftest to test snapshot and tracing_on affecting each other

- Fix setting of tracepoint flag on error that prevents probes from
being deleted.

- Fix another possible double free that is similar to
event_trigger_callback()

- Quiet a gcc warning of a false positive unused variable

- Fix crash of partial exposed task->comm to trace events"

* tag 'trace-v4.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
kthread, tracing: Don't expose half-written comm when creating kthreads
tracing: Quiet gcc warning about maybe unused link variable
tracing: Fix possible double free in event_enable_trigger_func()
tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure
selftests/ftrace: Add snapshot and tracing_on test case
ring_buffer: tracing: Inherit the tracing setting to next ring buffer
tracing: Fix double free of event_trigger_data

+84 -8
+1
include/linux/ring_buffer.h
··· 165 165 void ring_buffer_record_off(struct ring_buffer *buffer); 166 166 void ring_buffer_record_on(struct ring_buffer *buffer); 167 167 int ring_buffer_record_is_on(struct ring_buffer *buffer); 168 + int ring_buffer_record_is_set_on(struct ring_buffer *buffer); 168 169 void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu); 169 170 void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu); 170 171
+7 -1
kernel/kthread.c
··· 325 325 task = create->result; 326 326 if (!IS_ERR(task)) { 327 327 static const struct sched_param param = { .sched_priority = 0 }; 328 + char name[TASK_COMM_LEN]; 328 329 329 - vsnprintf(task->comm, sizeof(task->comm), namefmt, args); 330 + /* 331 + * task is already visible to other tasks, so updating 332 + * COMM must be protected. 333 + */ 334 + vsnprintf(name, sizeof(name), namefmt, args); 335 + set_task_comm(task, name); 330 336 /* 331 337 * root may have changed our (kthreadd's) priority or CPU mask. 332 338 * The kernel thread should not inherit these properties.
+16
kernel/trace/ring_buffer.c
··· 3227 3227 } 3228 3228 3229 3229 /** 3230 + * ring_buffer_record_is_set_on - return true if the ring buffer is set writable 3231 + * @buffer: The ring buffer to see if write is set enabled 3232 + * 3233 + * Returns true if the ring buffer is set writable by ring_buffer_record_on(). 3234 + * Note that this does NOT mean it is in a writable state. 3235 + * 3236 + * It may return true when the ring buffer has been disabled by 3237 + * ring_buffer_record_disable(), as that is a temporary disabling of 3238 + * the ring buffer. 3239 + */ 3240 + int ring_buffer_record_is_set_on(struct ring_buffer *buffer) 3241 + { 3242 + return !(atomic_read(&buffer->record_disabled) & RB_BUFFER_OFF); 3243 + } 3244 + 3245 + /** 3230 3246 * ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer 3231 3247 * @buffer: The ring buffer to stop writes to. 3232 3248 * @cpu: The CPU buffer to stop
+6
kernel/trace/trace.c
··· 1373 1373 1374 1374 arch_spin_lock(&tr->max_lock); 1375 1375 1376 + /* Inherit the recordable setting from trace_buffer */ 1377 + if (ring_buffer_record_is_set_on(tr->trace_buffer.buffer)) 1378 + ring_buffer_record_on(tr->max_buffer.buffer); 1379 + else 1380 + ring_buffer_record_off(tr->max_buffer.buffer); 1381 + 1376 1382 swap(tr->trace_buffer.buffer, tr->max_buffer.buffer); 1377 1383 1378 1384 __update_max_tr(tr, tsk, cpu);
+13 -5
kernel/trace/trace_events_trigger.c
··· 679 679 goto out_free; 680 680 681 681 out_reg: 682 + /* Up the trigger_data count to make sure reg doesn't free it on failure */ 683 + event_trigger_init(trigger_ops, trigger_data); 682 684 ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file); 683 685 /* 684 686 * The above returns on success the # of functions enabled, ··· 688 686 * Consider no functions a failure too. 689 687 */ 690 688 if (!ret) { 689 + cmd_ops->unreg(glob, trigger_ops, trigger_data, file); 691 690 ret = -ENOENT; 692 - goto out_free; 693 - } else if (ret < 0) 694 - goto out_free; 695 - ret = 0; 691 + } else if (ret > 0) 692 + ret = 0; 693 + 694 + /* Down the counter of trigger_data or free it if not used anymore */ 695 + event_trigger_free(trigger_ops, trigger_data); 696 696 out: 697 697 return ret; 698 698 ··· 1420 1416 goto out; 1421 1417 } 1422 1418 1419 + /* Up the trigger_data count to make sure nothing frees it on failure */ 1420 + event_trigger_init(trigger_ops, trigger_data); 1421 + 1423 1422 if (trigger) { 1424 1423 number = strsep(&trigger, ":"); 1425 1424 ··· 1473 1466 goto out_disable; 1474 1467 /* Just return zero, not the number of enabled functions */ 1475 1468 ret = 0; 1469 + event_trigger_free(trigger_ops, trigger_data); 1476 1470 out: 1477 1471 return ret; 1478 1472 ··· 1484 1476 out_free: 1485 1477 if (cmd_ops->set_filter) 1486 1478 cmd_ops->set_filter(NULL, trigger_data, NULL); 1487 - kfree(trigger_data); 1479 + event_trigger_free(trigger_ops, trigger_data); 1488 1480 kfree(enable_data); 1489 1481 goto out; 1490 1482 }
+13 -2
kernel/trace/trace_kprobe.c
··· 400 400 static int 401 401 enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file) 402 402 { 403 + struct event_file_link *link = NULL; 403 404 int ret = 0; 404 405 405 406 if (file) { 406 - struct event_file_link *link; 407 - 408 407 link = kmalloc(sizeof(*link), GFP_KERNEL); 409 408 if (!link) { 410 409 ret = -ENOMEM; ··· 422 423 ret = enable_kretprobe(&tk->rp); 423 424 else 424 425 ret = enable_kprobe(&tk->rp.kp); 426 + } 427 + 428 + if (ret) { 429 + if (file) { 430 + /* Notice the if is true on not WARN() */ 431 + if (!WARN_ON_ONCE(!link)) 432 + list_del_rcu(&link->list); 433 + kfree(link); 434 + tk->tp.flags &= ~TP_FLAG_TRACE; 435 + } else { 436 + tk->tp.flags &= ~TP_FLAG_PROFILE; 437 + } 425 438 } 426 439 out: 427 440 return ret;
+28
tools/testing/selftests/ftrace/test.d/00basic/snapshot.tc
··· 1 + #!/bin/sh 2 + # description: Snapshot and tracing setting 3 + # flags: instance 4 + 5 + [ ! -f snapshot ] && exit_unsupported 6 + 7 + echo "Set tracing off" 8 + echo 0 > tracing_on 9 + 10 + echo "Allocate and take a snapshot" 11 + echo 1 > snapshot 12 + 13 + # Since trace buffer is empty, snapshot is also empty, but allocated 14 + grep -q "Snapshot is allocated" snapshot 15 + 16 + echo "Ensure keep tracing off" 17 + test `cat tracing_on` -eq 0 18 + 19 + echo "Set tracing on" 20 + echo 1 > tracing_on 21 + 22 + echo "Take a snapshot again" 23 + echo 1 > snapshot 24 + 25 + echo "Ensure keep tracing on" 26 + test `cat tracing_on` -eq 1 27 + 28 + exit 0