@@ -217,6 +217,8 @@ tracecmd_peek_data_ref(struct tracecmd_input *handle, int cpu)
return rec;
}
+int tracecmd_latency_data_read(struct tracecmd_input *handle, char **buf, size_t *size);
+
struct tep_record *
tracecmd_read_prev(struct tracecmd_input *handle, struct tep_record *record);
@@ -175,6 +175,9 @@ struct tracecmd_input {
bool read_zpage; /* uncompress pages in memory, do not use tmp files */
bool cpu_compressed;
int file_version;
+ /* temporary file for uncompressed latency data */
+ struct cpu_zdata latz;
+
struct cpu_data *cpu_data;
long long ts_offset;
struct tsc2nsec tsc_calc;
@@ -3431,6 +3434,56 @@ static int read_options_type(struct tracecmd_input *handle)
return 0;
}
+int tracecmd_latency_data_read(struct tracecmd_input *handle, char **buf, size_t *size)
+{
+ struct cpu_zdata *zdata = &handle->latz;
+ void *data;
+ int rsize;
+ int fd = -1;
+ int id;
+
+ if (!handle || !buf || !size)
+ return -1;
+ if (handle->file_state != TRACECMD_FILE_CPU_LATENCY)
+ return -1;
+
+ if (!handle->cpu_compressed) {
+ fd = handle->fd;
+ } else if (!handle->read_zpage) {
+ if (zdata->fd < 0)
+ return -1;
+ fd = zdata->fd;
+ }
+
+ /* Read data from a file */
+ if (fd >= 0) {
+ if (!(*buf)) {
+ *size = BUFSIZ;
+ *buf = malloc(*size);
+ if (!(*buf))
+ return -1;
+ }
+ return do_read_fd(fd, *buf, *size);
+ }
+
+ /* Uncompress data in memory */
+ if (zdata->last_chunk >= zdata->count)
+ return 0;
+ id = zdata->last_chunk;
+ if (!*buf || *size < zdata->chunks[id].size) {
+ data = realloc(*buf, zdata->chunks[id].size);
+ if (!data)
+ return -1;
+ *buf = data;
+ *size = zdata->chunks[id].size;
+ }
+ if (tracecmd_uncompress_chunk(handle->compress, &zdata->chunks[id], *buf))
+ return -1;
+ rsize = zdata->chunks[id].size;
+ zdata->last_chunk++;
+ return rsize;
+}
+
static int init_cpu_data(struct tracecmd_input *handle)
{
enum kbuffer_long_size long_size;
@@ -3494,6 +3547,32 @@ static int init_cpu_data(struct tracecmd_input *handle)
return -1;
}
+int init_latency_data(struct tracecmd_input *handle)
+{
+ unsigned long long wsize;
+ int ret;
+
+ if (!handle->cpu_compressed)
+ return 0;
+
+ if (handle->read_zpage) {
+ handle->latz.count = tracecmd_load_chunks_info(handle->compress, &handle->latz.chunks);
+ if (handle->latz.count < 0)
+ return -1;
+ } else {
+ strcpy(handle->latz.file, COMPR_TEMP_FILE);
+ handle->latz.fd = mkstemp(handle->latz.file);
+ if (handle->latz.fd < 0)
+ return -1;
+ ret = tracecmd_uncompress_copy_to(handle->compress, handle->latz.fd, NULL, &wsize);
+ if (ret)
+ return -1;
+ lseek64(handle->latz.fd, 0, SEEK_SET);
+ }
+
+ return 0;
+}
+
static int init_buffer_cpu_data(struct tracecmd_input *handle, struct input_buffer_instance *buffer)
{
unsigned long long offset;
@@ -3510,6 +3589,10 @@ static int init_buffer_cpu_data(struct tracecmd_input *handle, struct input_buff
return -1;
if (flags & TRACECMD_SEC_FL_COMPRESS)
handle->cpu_compressed = true;
+ if (buffer->latency) {
+ handle->file_state = TRACECMD_FILE_CPU_LATENCY;
+ return init_latency_data(handle) == 0 ? 1 : -1;
+ }
handle->file_state = TRACECMD_FILE_CPU_FLYRECORD;
handle->cpus = buffer->cpus;
if (handle->max_cpu < handle->cpus)
@@ -3959,7 +4042,7 @@ struct tracecmd_input *tracecmd_alloc_fd(int fd, int flags)
handle->fd = fd;
handle->ref = 1;
-
+ handle->latz.fd = -1;
/* By default, use usecs, unless told otherwise */
handle->flags |= TRACECMD_FL_IN_USECS;
@@ -4233,7 +4316,11 @@ void tracecmd_close(struct tracecmd_input *handle)
free(handle->trace_clock);
free(handle->version);
close(handle->fd);
-
+ free(handle->latz.chunks);
+ if (handle->latz.fd >= 0) {
+ close(handle->latz.fd);
+ unlink(handle->latz.file);
+ }
while (handle->sections) {
del_sec = handle->sections;
handle->sections = handle->sections->next;
Latency trace data is saved the same was as flyrecord buffer data in trace files version 7. There is a BUFFER_LAT option which hols the latency specific trace metadata and points to the secrtion in the file with the trace data. Extended the input hanlder with latency trace context and added new logic to decompress and read the latency data. A new API is added to read latency data: tracecmd_latency_data_read() Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com> --- .../include/private/trace-cmd-private.h | 2 + lib/trace-cmd/trace-input.c | 91 ++++++++++++++++++- 2 files changed, 91 insertions(+), 2 deletions(-)