From patchwork Fri Dec 10 10:54:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12669287 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9248C4332F for ; Fri, 10 Dec 2021 10:55:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237197AbhLJK6p (ORCPT ); Fri, 10 Dec 2021 05:58:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232982AbhLJK6o (ORCPT ); Fri, 10 Dec 2021 05:58:44 -0500 Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA361C061746 for ; Fri, 10 Dec 2021 02:55:09 -0800 (PST) Received: by mail-ed1-x52a.google.com with SMTP id g14so27929221edb.8 for ; Fri, 10 Dec 2021 02:55:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JeWMLzHBXuunA+mzw+25RA7DoMF6Is/8Vg1Bz5ffmJE=; b=m5C2622Yl+Sk6qHbupeOlF+FkmmiOVVfm5ieZkGRRAq01J3DrxiDohsuR8nVxVeMhu M4uOkfTFMd26CXgl8Garb9/omZh230NL2cJRzxpAyQCjK2RDVyLRRgdcu9Olc2OhZ9We 1BDNe4X0wPEd67opQelmEj5ZjOFwnWzg8mWO/mCc3u0IuXsff38yeooNtF3UAJFrvxIg +txJPmz7/gZ9gbmrkql9CGFGBRT5lLzdpk7ghWtvj3LScaqWQTljngpFwme/xsaeMfJ1 i/vU6Eo7qQ/yG3PBajVkCoDiTmBcwO9AoqFpJG0c+kTTaCZoJQ3auOxuYMYb4PcvIXf3 6AMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JeWMLzHBXuunA+mzw+25RA7DoMF6Is/8Vg1Bz5ffmJE=; b=vqRRsUMemfBRX78quKMEN19lUVHMop9Z7jBjURkDLU2tpuHwST3IVMmf3RemRLAWnN srlk/aku8lMVR6r4RyYiMqodwaQlEgE8DTGkJ4aFQYJJMVbUXHarcKzzwQRVsgzjDMnf WIv7wiguGfQKCrVioPI95Ra/5jvABw62C28YHm5e4jXPv1ZZ19blG1F9Xc6J3IIZFveP wtNXuezwC5hXEGgoDaXJoLQB2CZyqh3K62z22X2gGyjiuaqgBIiqegfmywhEtz460brA zEy8DxwGZlX9iY4IeJulEhb7alA4BSfYXvtQ++Ux8GsAp0fUSSDGmDF+zj/hJYor1Apf E1LQ== X-Gm-Message-State: AOAM531KUg9L+ihLzk6YRKVx1e4dGhOg8jkb5qom7EWPxkosYWrqPgEh 8CEMsq3ttOkcC00x0qRJaqJYPtGA9uI= X-Google-Smtp-Source: ABdhPJwMLA32z7SEEn8BVONDPFnpNbtRvRgGHCgb4XtWRZ+FqdHsUMQT6uybFrnYgg4P9GhK8YDefg== X-Received: by 2002:a17:907:1c9d:: with SMTP id nb29mr24027451ejc.74.1639133708289; Fri, 10 Dec 2021 02:55:08 -0800 (PST) Received: from oberon.zico.biz.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id x7sm1306314edd.28.2021.12.10.02.55.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Dec 2021 02:55:07 -0800 (PST) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v7 20/25] trace-cmd library: Initialize CPU data for reading from version 7 trace files Date: Fri, 10 Dec 2021 12:54:43 +0200 Message-Id: <20211210105448.97850-21-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211210105448.97850-1-tz.stoyanov@gmail.com> References: <20211210105448.97850-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org In version 7 trace files, CPU trace data is written in slightly different way than in version 6 files. Added new CPU data initialization flow, to handle version 7 files: - the top trace instance is saved in the same way as the other trace instances. - per CPU trace metadata is stored in the buffer option. - trace data section has section header. Signed-off-by: Tzvetomir Stoyanov (VMware) --- lib/trace-cmd/trace-input.c | 178 +++++++++++++++++++++++++----------- 1 file changed, 123 insertions(+), 55 deletions(-) diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c index a25919a3..fe3d6e77 100644 --- a/lib/trace-cmd/trace-input.c +++ b/lib/trace-cmd/trace-input.c @@ -3203,34 +3203,18 @@ static int read_options_type(struct tracecmd_input *handle) return 0; } -static int read_cpu_data(struct tracecmd_input *handle) +static int init_cpu_data(struct tracecmd_input *handle) { - struct tep_handle *pevent = handle->pevent; enum kbuffer_long_size long_size; enum kbuffer_endian endian; - unsigned long long size; unsigned long long max_size = 0; unsigned long long pages; - int cpus; int cpu; - /* - * Check if this is a latency report or not. - */ - if (handle->file_state == TRACECMD_FILE_CPU_LATENCY) - return 1; - /* We expect this to be flyrecord */ if (handle->file_state != TRACECMD_FILE_CPU_FLYRECORD) return -1; - cpus = handle->cpus; - - handle->cpu_data = malloc(sizeof(*handle->cpu_data) * handle->cpus); - if (!handle->cpu_data) - return -1; - memset(handle->cpu_data, 0, sizeof(*handle->cpu_data) * handle->cpus); - if (force_read) handle->read_page = true; @@ -3245,32 +3229,14 @@ static int read_cpu_data(struct tracecmd_input *handle) endian = KBUFFER_ENDIAN_LITTLE; for (cpu = 0; cpu < handle->cpus; cpu++) { - unsigned long long offset; - - handle->cpu_data[cpu].cpu = cpu; - handle->cpu_data[cpu].kbuf = kbuffer_alloc(long_size, endian); if (!handle->cpu_data[cpu].kbuf) goto out_free; - if (tep_is_old_format(pevent)) + if (tep_is_old_format(handle->pevent)) kbuffer_set_old_format(handle->cpu_data[cpu].kbuf); - read8(handle, &offset); - read8(handle, &size); - - handle->cpu_data[cpu].file_offset = offset; - handle->cpu_data[cpu].file_size = size; - if (size > max_size) - max_size = size; - - if (size && (offset + size > handle->total_file_size)) { - /* this happens if the file got truncated */ - printf("File possibly truncated. " - "Need at least %llu, but file size is %zu.\n", - offset + size, handle->total_file_size); - errno = EINVAL; - goto out_free; - } + if (handle->cpu_data[cpu].file_size > max_size) + max_size = handle->cpu_data[cpu].file_size; } /* Calculate about a meg of pages for buffering */ @@ -3288,6 +3254,101 @@ static int read_cpu_data(struct tracecmd_input *handle) goto out_free; } + return 0; + + out_free: + for ( ; cpu >= 0; cpu--) { + free_page(handle, cpu); + kbuffer_free(handle->cpu_data[cpu].kbuf); + handle->cpu_data[cpu].kbuf = NULL; + } + return -1; +} + +static int init_buffer_cpu_data(struct tracecmd_input *handle, struct input_buffer_instance *buffer) +{ + unsigned long long offset; + unsigned long long size; + unsigned short id, flags; + int cpu; + + if (handle->cpu_data) + return -1; + + if (lseek64(handle->fd, buffer->offset, SEEK_SET) == (off_t)-1) + return -1; + if (read_section_header(handle, &id, &flags, NULL, NULL)) + return -1; + + handle->file_state = TRACECMD_FILE_CPU_FLYRECORD; + handle->cpus = buffer->cpus; + if (handle->max_cpu < handle->cpus) + handle->max_cpu = handle->cpus; + + handle->cpu_data = calloc(handle->cpus, sizeof(*handle->cpu_data)); + if (!handle->cpu_data) + return -1; + + for (cpu = 0; cpu < handle->cpus; cpu++) { + handle->cpu_data[cpu].cpu = buffer->cpu_data[cpu].cpu; + offset = buffer->cpu_data[cpu].offset; + size = buffer->cpu_data[cpu].size; + handle->cpu_data[cpu].file_offset = offset; + handle->cpu_data[cpu].file_size = size; + if (size && (offset + size > handle->total_file_size)) { + /* this happens if the file got truncated */ + printf("File possibly truncated. " + "Need at least %llu, but file size is %zu.\n", + offset + size, handle->total_file_size); + errno = EINVAL; + return -1; + } + } + + return init_cpu_data(handle); +} + +static int read_cpu_data(struct tracecmd_input *handle) +{ + unsigned long long size; + int cpus; + int cpu; + + /* + * Check if this is a latency report or not. + */ + if (handle->file_state == TRACECMD_FILE_CPU_LATENCY) + return 1; + + /* We expect this to be flyrecord */ + if (handle->file_state != TRACECMD_FILE_CPU_FLYRECORD) + return -1; + + cpus = handle->cpus; + + handle->cpu_data = malloc(sizeof(*handle->cpu_data) * handle->cpus); + if (!handle->cpu_data) + return -1; + memset(handle->cpu_data, 0, sizeof(*handle->cpu_data) * handle->cpus); + + for (cpu = 0; cpu < handle->cpus; cpu++) { + unsigned long long offset; + + handle->cpu_data[cpu].cpu = cpu; + read8(handle, &offset); + read8(handle, &size); + handle->cpu_data[cpu].file_offset = offset; + handle->cpu_data[cpu].file_size = size; + if (size && (offset + size > handle->total_file_size)) { + /* this happens if the file got truncated */ + printf("File possibly truncated. " + "Need at least %llu, but file size is %zu.\n", + offset + size, handle->total_file_size); + errno = EINVAL; + return -1; + } + } + /* * It is possible that an option changed the number of CPUs. * If that happened, then there's "empty" cpu data saved for @@ -3307,15 +3368,7 @@ static int read_cpu_data(struct tracecmd_input *handle) } } - return 0; - - out_free: - for ( ; cpu >= 0; cpu--) { - free_page(handle, cpu); - kbuffer_free(handle->cpu_data[cpu].kbuf); - handle->cpu_data[cpu].kbuf = NULL; - } - return -1; + return init_cpu_data(handle); } static int read_data_and_size(struct tracecmd_input *handle, @@ -3413,14 +3466,7 @@ static int read_and_parse_trace_clock(struct tracecmd_input *handle, return 0; } -/** - * tracecmd_init_data - prepare reading the data from trace.dat - * @handle: input handle for the trace.dat file - * - * This prepares reading the data from trace.dat. This is called - * after tracecmd_read_headers() and before tracecmd_read_data(). - */ -int tracecmd_init_data(struct tracecmd_input *handle) +static int init_data_v6(struct tracecmd_input *handle) { struct tep_handle *pevent = handle->pevent; int ret; @@ -3442,7 +3488,29 @@ int tracecmd_init_data(struct tracecmd_input *handle) tracecmd_parse_trace_clock(handle, clock, 8); } } + return ret; +} + +static int init_data_v7(struct tracecmd_input *handle) +{ + return init_buffer_cpu_data(handle, &handle->top_buffer); +} +/** + * tracecmd_init_data - prepare reading the data from trace.dat + * @handle: input handle for the trace.dat file + * + * This prepares reading the data from trace.dat. This is called + * after tracecmd_read_headers() and before tracecmd_read_data(). + */ +int tracecmd_init_data(struct tracecmd_input *handle) +{ + int ret; + + if (!HAS_SECTIONS(handle)) + ret = init_data_v6(handle); + else + ret = init_data_v7(handle); tracecmd_blk_hack(handle); return ret;