trace-cmd can record events in multiple instances: $ trace-cmd record -e sched_wakeup -B test_instance -e sched_switch When trying to split a trace.dat file recorded with the above command, only the events located in the main buffer seems to be split. The events recorded in the test_instance buffer seem to be discarded: $ trace-cmd split -i trace.dat -o trace_2.dat 284443 284444 $ trace-cmd report trace_2.dat cpus=8 <...>-525991 [004] 284443.173879: sched_wakeup: [...] <...>-525991 [004] 284443.173879: sched_wakeup: [...] <...>-525990 [007] 284443.173885: sched_wakeup: [...] <...>-525990 [007] 284443.173885: sched_wakeup: [...] (no sign of sched_switch events) Make use of the previous patches to split all the instances of a trace. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218357 Signed-off-by: Pierre Gondois <pierre.gondois@xxxxxxx> --- tracecmd/trace-split.c | 109 ++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 50 deletions(-) diff --git a/tracecmd/trace-split.c b/tracecmd/trace-split.c index 6ab138a2..37ce4176 100644 --- a/tracecmd/trace-split.c +++ b/tracecmd/trace-split.c @@ -426,6 +426,7 @@ static unsigned long long parse_file(struct tracecmd_input *handle, bool *end_reached) { unsigned long long current; + struct handle_list *handle_entry; struct tracecmd_output *ohandle; struct cpu_data *cpu_data; struct tep_record *record; @@ -437,63 +438,71 @@ static unsigned long long parse_file(struct tracecmd_input *handle, int fd; ohandle = tracecmd_copy(handle, output_file, TRACECMD_FILE_CMD_LINES, 0, NULL); + tracecmd_set_out_clock(ohandle, tracecmd_get_trace_clock(handle)); - cpus = tracecmd_cpus(handle); - cpu_data = malloc(sizeof(*cpu_data) * cpus); - if (!cpu_data) - die("Failed to allocate cpu_data for %d cpus", cpus); - - for (cpu = 0; cpu < cpus; cpu++) { - file = get_temp_file(output_file, NULL, cpu); - touch_file(file); - - fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); - cpu_data[cpu].cpu = cpu; - cpu_data[cpu].fd = fd; - cpu_data[cpu].file = file; - cpu_data[cpu].offset = 0; - if (start) - tracecmd_set_cpu_to_timestamp(handle, cpu, start); - } + list_for_each_entry(handle_entry, &handle_list, list) { + cpus = tracecmd_cpus(handle_entry->handle); + cpu_data = malloc(sizeof(*cpu_data) * cpus); + if (!cpu_data) + die("Failed to allocate cpu_data for %d cpus", cpus); - if (only_cpu >= 0) { - parse_cpu(handle, cpu_data, start, end, count, - 1, only_cpu, type, end_reached); - } else if (percpu) { + for (cpu = 0; cpu < cpus; cpu++) { + file = get_temp_file(output_file, handle_entry->name, cpu); + touch_file(file); + + fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); + cpu_data[cpu].cpu = cpu; + cpu_data[cpu].fd = fd; + cpu_data[cpu].file = file; + cpu_data[cpu].offset = 0; + if (start) + tracecmd_set_cpu_to_timestamp(handle_entry->handle, cpu, start); + } + + if (only_cpu >= 0) { + parse_cpu(handle_entry->handle, cpu_data, start, end, count, + 1, only_cpu, type, end_reached); + } else if (percpu) { + for (cpu = 0; cpu < cpus; cpu++) + parse_cpu(handle_entry->handle, cpu_data, start, + end, count, percpu, cpu, type, end_reached); + } else { + parse_cpu(handle_entry->handle, cpu_data, start, + end, count, percpu, -1, type, end_reached); + } + + cpu_list = malloc(sizeof(*cpu_list) * cpus); + if (!cpu_list) + die("Failed to allocate cpu_list for %d cpus", cpus); for (cpu = 0; cpu < cpus; cpu++) - parse_cpu(handle, cpu_data, start, - end, count, percpu, cpu, type, end_reached); - } else - parse_cpu(handle, cpu_data, start, - end, count, percpu, -1, type, end_reached); - - cpu_list = malloc(sizeof(*cpu_list) * cpus); - if (!cpu_list) - die("Failed to allocate cpu_list for %d cpus", cpus); - for (cpu = 0; cpu < cpus; cpu ++) - cpu_list[cpu] = cpu_data[cpu].file; + cpu_list[cpu] = cpu_data[cpu].file; - tracecmd_set_out_clock(ohandle, tracecmd_get_trace_clock(handle)); - if (tracecmd_append_cpu_data(ohandle, cpus, cpu_list) < 0) - die("Failed to append tracing data\n"); - - for (cpu = 0; cpu < cpus; cpu++) { - /* Set the tracecmd cursor to the next set of records */ - if (cpu_data[cpu].offset) { - record = tracecmd_read_at(handle, cpu_data[cpu].offset, NULL); - if (record && (!current || record->ts > current)) - current = record->ts + 1; - tracecmd_free_record(record); + if (!handle_entry->name) + ret = tracecmd_append_cpu_data(ohandle, cpus, cpu_list); + else + ret = tracecmd_append_buffer_cpu_data(ohandle, handle_entry->name, cpus, + cpu_list); + if (ret < 0) + die("Failed to append tracing data\n"); + + for (cpu = 0; cpu < cpus; cpu++) { + /* Set the tracecmd cursor to the next set of records */ + if (cpu_data[cpu].offset) { + record = tracecmd_read_at(handle, cpu_data[cpu].offset, NULL); + if (record && (!current || record->ts > current)) + current = record->ts + 1; + tracecmd_free_record(record); + } } - } - for (cpu = 0; cpu < cpus; cpu++) { - close(cpu_data[cpu].fd); - delete_temp_file(cpu_data[cpu].file); - put_temp_file(cpu_data[cpu].file); + for (cpu = 0; cpu < cpus; cpu++) { + close(cpu_data[cpu].fd); + delete_temp_file(cpu_data[cpu].file); + put_temp_file(cpu_data[cpu].file); + } + free(cpu_data); + free(cpu_list); } - free(cpu_data); - free(cpu_list); tracecmd_output_close(ohandle); -- 2.25.1