@@ -135,6 +135,7 @@ enum {
TRACECMD_OPTION_TIME_SHIFT,
TRACECMD_OPTION_GUEST,
TRACECMD_OPTION_TSC2NSEC,
+ TRACECMD_OPTION_BUFFER_LAT,
TRACECMD_OPTION_HEADER_INFO,
TRACECMD_OPTION_FTRACE_EVENTS,
TRACECMD_OPTION_EVENT_FORMATS,
@@ -294,7 +295,7 @@ int tracecmd_output_write_headers(struct tracecmd_output *handler,
struct tracecmd_event_list *list);
struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, int cpus,
- int file_version);
+ int file_version, const char *compression);
struct tracecmd_output *tracecmd_create_init_fd(int fd);
struct tracecmd_output *tracecmd_create_init_file(const char *output_file);
@@ -2030,9 +2030,11 @@ out_add_buffer_option_v7(struct tracecmd_output *handle, const char *name,
}
struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, int cpus,
- int file_version)
+ int file_version, const char *compression)
{
+ enum tracecmd_section_flags flags = 0;
struct tracecmd_output *handle;
+ tsize_t offset;
char *path;
int fd;
@@ -2045,6 +2047,12 @@ struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, in
goto out_free;
if (file_version && tracecmd_output_set_version(handle, file_version))
goto out_free;
+ if (compression) {
+ if (tracecmd_output_set_compression(handle, compression))
+ goto out_free;
+ } else if (file_version >= 7) {
+ tracecmd_output_set_compression(handle, "any");
+ }
if (tracecmd_output_write_init(handle))
goto out_free;
if (tracecmd_output_write_headers(handle, NULL))
@@ -2057,7 +2065,8 @@ struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, in
if (tracecmd_write_cpus(handle, cpus) < 0)
goto out_free;
-
+ if (tracecmd_write_buffer_info(handle) < 0)
+ goto out_free;
if (tracecmd_write_options(handle) < 0)
goto out_free;
@@ -2067,23 +2076,42 @@ struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, in
goto out_free;
}
- if (do_write_check(handle, "latency ", 10))
+ if (handle->file_version < 7 && do_write_check(handle, "latency ", 10))
goto out_free;
path = get_tracing_file(handle, "trace");
if (!path)
goto out_free;
+ offset = do_lseek(handle, 0, SEEK_CUR);
+ if (handle->file_version >= 7 &&
+ !out_add_buffer_option_v7(handle, "", TRACECMD_OPTION_BUFFER_LAT, offset, 0, NULL))
+ goto out_free;
+ if (handle->compress)
+ flags |= TRACECMD_SEC_FL_COMPRESS;
+
+ offset = out_write_section_header(handle, TRACECMD_OPTION_BUFFER_LAT,
+ "buffer latency", flags, false);
+
copy_file_compress(handle, path, NULL);
+ if (out_update_section_header(handle, offset))
+ goto out_free;
put_tracing_file(path);
handle->file_state = TRACECMD_FILE_CPU_LATENCY;
+ if (tracecmd_get_out_file_version(handle) >= 7)
+ tracecmd_write_options(handle);
+
return handle;
out_free:
- tracecmd_output_close(handle);
+ if (handle)
+ tracecmd_output_close(handle);
+ else
+ close(fd);
+ unlink(output_file);
return NULL;
}
@@ -4531,7 +4531,7 @@ static void record_data(struct common_record_context *ctx)
if (latency) {
handle = tracecmd_create_file_latency(ctx->output, local_cpu_count,
- ctx->file_version);
+ ctx->file_version, ctx->compression);
tracecmd_set_quiet(handle, quiet);
} else {
if (!local_cpu_count)
Trace file version 7 format is based on sections. To fit the latency trace data in this structure, a new section and option for it is defined: BUFFER_LAT It is similar to the BUFFER section which holds the flyrecord data, but has a latency specific design. The BUFFER_LAT section has: - section header, as all other sections - compression of the trace data, optional - corresponding trace option, pointing to the section Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com> --- .../include/private/trace-cmd-private.h | 3 +- lib/trace-cmd/trace-output.c | 36 ++++++++++++++++--- tracecmd/trace-record.c | 2 +- 3 files changed, 35 insertions(+), 6 deletions(-)