From patchwork Tue Sep 12 21:42:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Llu=C3=ADs_Vilanova?= X-Patchwork-Id: 9950181 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DA77360325 for ; Tue, 12 Sep 2017 21:42:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C59122621D for ; Tue, 12 Sep 2017 21:42:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B829328FC6; Tue, 12 Sep 2017 21:42:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C0C042621D for ; Tue, 12 Sep 2017 21:42:55 +0000 (UTC) Received: from localhost ([::1]:38770 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsxK-0002MI-Qn for patchwork-qemu-devel@patchwork.kernel.org; Tue, 12 Sep 2017 17:42:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44301) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drswl-0002LM-IV for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:42:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drswi-00056N-2s for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:42:19 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:54644) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drswh-00055P-JN for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:42:16 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLgCk6022680; Tue, 12 Sep 2017 23:42:12 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id C705C25B; Tue, 12 Sep 2017 23:42:06 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:42:05 +0300 Message-Id: <150525252530.15988.15700689004917162150.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLgCk6022680 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 10/22] instrument: Add support for tracing events X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Lluís Vilanova --- .gitignore | 1 Makefile | 3 + instrument/Makefile.objs | 1 instrument/error.h | 6 ++ instrument/qemu-instr/types.h | 51 +++++++++++++++ instrument/qemu-instr/types.inc.h | 15 ++++ instrument/trace.c | 125 +++++++++++++++++++++++++++++++++++++ trace/control.h | 1 8 files changed, 203 insertions(+) create mode 100644 instrument/qemu-instr/types.h create mode 100644 instrument/qemu-instr/types.inc.h create mode 100644 instrument/trace.c diff --git a/.gitignore b/.gitignore index cf65316863..5ffcb9a091 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,4 @@ trace-dtrace-root.h trace-dtrace-root.dtrace trace-ust-all.h trace-ust-all.c +!/instrument/* diff --git a/Makefile b/Makefile index c3d9a4bcd9..646fe2f327 100644 --- a/Makefile +++ b/Makefile @@ -602,6 +602,9 @@ endif ifdef CONFIG_INSTRUMENT $(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr/" $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h "$(DESTDIR)$(includedir)/qemu-instr/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/trace.h "$(DESTDIR)$(includedir)/qemu-instr/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.h "$(DESTDIR)$(includedir)/qemu-instr/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.inc.h "$(DESTDIR)$(includedir)/qemu-instr/" endif install-datadir: diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index ec76b2080b..d7e6c760c3 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -4,3 +4,4 @@ target-obj-$(CONFIG_INSTRUMENT) += cmdline.o target-obj-$(CONFIG_INSTRUMENT) += load.o target-obj-$(CONFIG_INSTRUMENT) += qmp.o target-obj-$(CONFIG_INSTRUMENT) += control.o +target-obj-$(CONFIG_INSTRUMENT) += trace.o diff --git a/instrument/error.h b/instrument/error.h index f8d1dd4b16..7a51d62fdb 100644 --- a/instrument/error.h +++ b/instrument/error.h @@ -25,4 +25,10 @@ return; \ } +#define ERROR_IF_RET(cond, ret, msg, args...) \ + if (unlikely(cond)) { \ + _ERROR(msg, ##args); \ + return ret; \ + } \ + #endif /* INSTRUMENT_ERROR_H */ diff --git a/instrument/qemu-instr/types.h b/instrument/qemu-instr/types.h new file mode 100644 index 0000000000..ea3a032b4f --- /dev/null +++ b/instrument/qemu-instr/types.h @@ -0,0 +1,51 @@ +/* + * QEMU-specific types for instrumentation clients. + * + * Copyright (C) 2012-2017 Lluís Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef QI__TYPES_H +#define QI__TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * SECTION: types + * @section_id: qi-types + * @title: Common types + */ + +/** + * QITraceEvent: + * + * Opaque structure defining a tracing event. + */ +typedef struct QITraceEvent QITraceEvent; + +/** + * QITraceEventIter: + * + * Opaque structure defining a tracing event iterator. + */ +typedef struct QITraceEventIter QITraceEventIter; + +/** + * QICPU: + * + * Opaque guest CPU pointer. + */ +typedef struct QICPU_d *QICPU; + + +#include + +#ifdef __cplusplus +} +#endif + +#endif /* QI__TYPES_H */ diff --git a/instrument/qemu-instr/types.inc.h b/instrument/qemu-instr/types.inc.h new file mode 100644 index 0000000000..0d99ea59a2 --- /dev/null +++ b/instrument/qemu-instr/types.inc.h @@ -0,0 +1,15 @@ +/* + * QEMU-specific types for instrumentation clients. + * + * Copyright (C) 2012-2017 Lluís Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include + + +struct QITraceEventIter { + char buffer[(sizeof(size_t) * 2) + sizeof(char *)]; +}; diff --git a/instrument/trace.c b/instrument/trace.c new file mode 100644 index 0000000000..6a437039b4 --- /dev/null +++ b/instrument/trace.c @@ -0,0 +1,125 @@ +/* + * API for QEMU's tracing events. + * + * Copyright (C) 2012-2017 Lluís Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "instrument/error.h" +#include "qemu/compiler.h" +#include "qemu-instr/trace.h" +#include "trace/control.h" + + +SYM_PUBLIC +QITraceEvent *qi_trace_event_name(const char *name) +{ + ERROR_IF_RET(!name, NULL, "must provide a name"); + return (QITraceEvent *)trace_event_name(name); +} + +SYM_PUBLIC +void qi_trace_event_iter_init(QITraceEventIter *iter, const char *pattern) +{ + TraceEventIter *iter_ = (TraceEventIter *)iter; + ERROR_IF(!iter_, "must provide an iterator"); + trace_event_iter_init(iter_, pattern); +} + +SYM_PUBLIC +QITraceEvent *qi_trace_event_iter_next(QITraceEventIter *iter) +{ + TraceEventIter *iter_ = (TraceEventIter *)iter; + ERROR_IF_RET(!iter_, NULL, "must provide an iterator"); + return (QITraceEvent *)trace_event_iter_next(iter_); +} + + +SYM_PUBLIC +bool qi_trace_event_is_vcpu(QITraceEvent *ev) +{ + TraceEvent *ev_ = (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_is_vcpu(ev_); +} + +SYM_PUBLIC +const char *qi_trace_event_get_name(QITraceEvent *ev) +{ + TraceEvent *ev_ = (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_name(ev_); +} + + +SYM_PUBLIC +bool qi_trace_event_get_state(QITraceEvent *ev) +{ + TraceEvent *ev_ = (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_state_static(ev_) && + trace_event_get_state_dynamic(ev_); +} + +SYM_PUBLIC +bool qi_trace_event_get_vcpu_state(QICPU *vcpu, QITraceEvent *ev) +{ + CPUState *vcpu_ = (CPUState *)vcpu; + TraceEvent *ev_ = (TraceEvent *)ev; + ERROR_IF_RET(!vcpu_, false, "must provide a vCPU"); + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_state_static(ev_) && + trace_event_get_vcpu_state_dynamic(vcpu_, ev_); +} + +SYM_PUBLIC +bool qi_trace_event_get_state_static(QITraceEvent *ev) +{ + TraceEvent *ev_ = (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_state_static(ev_); +} + +SYM_PUBLIC +bool qi_trace_event_get_state_dynamic(QITraceEvent *ev) +{ + TraceEvent *ev_ = (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_state_dynamic(ev_); +} + +SYM_PUBLIC +bool qi_trace_event_get_vcpu_state_dynamic(QICPU *vcpu, QITraceEvent *ev) +{ + CPUState *vcpu_ = (CPUState *)vcpu; + TraceEvent *ev_ = (TraceEvent *)ev; + ERROR_IF_RET(!vcpu_, false, "must provide a vCPU"); + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_vcpu_state_dynamic(vcpu_, ev_); +} + +SYM_PUBLIC +void qi_trace_event_set_state_dynamic(QITraceEvent *ev, bool state) +{ + TraceEvent *ev_ = (TraceEvent *)ev; + ERROR_IF(!ev_, "must provide an event"); + ERROR_IF(!trace_event_get_state_static(ev_), + "event must be statically enabled"); + trace_event_set_state_dynamic(ev_, state); +} + +SYM_PUBLIC +void qi_trace_event_set_vcpu_state_dynamic(QICPU *vcpu, + QITraceEvent *ev, bool state) +{ + CPUState *vcpu_ = (CPUState *)vcpu; + TraceEvent *ev_ = (TraceEvent *)ev; + ERROR_IF(!vcpu_, "must provide a vCPU"); + ERROR_IF(!ev_, "must provide an event"); + ERROR_IF(!trace_event_get_state_static(ev_), + "event must be statically enabled"); + trace_event_set_vcpu_state_dynamic(vcpu_, ev_, state); +} diff --git a/trace/control.h b/trace/control.h index 1903e22975..3e6da24c98 100644 --- a/trace/control.h +++ b/trace/control.h @@ -13,6 +13,7 @@ #include "qemu-common.h" #include "event-internal.h" +/* NOTE: Keep in sync with size of QITraceEventIter */ typedef struct TraceEventIter { size_t event; size_t group;