[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 09/20] instrument: Add basic control interface
From: |
Lluís Vilanova |
Subject: |
[Qemu-devel] [PATCH v4 09/20] instrument: Add basic control interface |
Date: |
Wed, 6 Sep 2017 20:59:02 +0300 |
User-agent: |
StGit/0.17.1-dirty |
Signed-off-by: Lluís Vilanova <address@hidden>
---
Makefile | 5 +++
configure | 1 +
instrument/Makefile.objs | 2 +
instrument/control.c | 28 +++++++++++++++++
instrument/control.h | 44 +++++++++++++++++++++++++++
instrument/control.inc.h | 25 ++++++++++++++++
instrument/error.h | 28 +++++++++++++++++
instrument/events.h | 37 +++++++++++++++++++++++
instrument/events.inc.h | 11 +++++++
instrument/load.c | 13 ++++++++
instrument/qemu-instr/control.h | 43 +++++++++++++++++++++++++++
instrument/qemu-instr/visibility.h | 58 ++++++++++++++++++++++++++++++++++++
stubs/Makefile.objs | 1 +
stubs/instrument.c | 13 ++++++++
14 files changed, 309 insertions(+)
create mode 100644 instrument/control.c
create mode 100644 instrument/control.h
create mode 100644 instrument/control.inc.h
create mode 100644 instrument/error.h
create mode 100644 instrument/events.h
create mode 100644 instrument/events.inc.h
create mode 100644 instrument/qemu-instr/control.h
create mode 100644 instrument/qemu-instr/visibility.h
create mode 100644 stubs/instrument.c
diff --git a/Makefile b/Makefile
index 81447b1f08..6171661458 100644
--- a/Makefile
+++ b/Makefile
@@ -589,6 +589,11 @@ ifdef CONFIG_VIRTFS
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
$(INSTALL_DATA) fsdev/virtfs-proxy-helper.1 "$(DESTDIR)$(mandir)/man1"
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/visibility.h
"$(DESTDIR)$(includedir)/qemu-instr/"
+endif
install-datadir:
$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)"
diff --git a/configure b/configure
index 05bd7b1950..3673fc9058 100755
--- a/configure
+++ b/configure
@@ -6038,6 +6038,7 @@ if test "$instrument" = "yes"; then
LIBS="-ldl $LIBS"
echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
fi
+QEMU_INCLUDES="-I\$(SRC_PATH)/instrument $QEMU_INCLUDES"
if test "$rdma" = "yes" ; then
echo "CONFIG_RDMA=y" >> $config_host_mak
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 13a8f60431..9b7e1c03aa 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -3,3 +3,5 @@
target-obj-y += cmdline.o
target-obj-$(CONFIG_INSTRUMENT) += load.o
target-obj-y += qmp.o
+
+target-obj-$(CONFIG_INSTRUMENT) += control.o
diff --git a/instrument/control.c b/instrument/control.c
new file mode 100644
index 0000000000..2c2781beeb
--- /dev/null
+++ b/instrument/control.c
@@ -0,0 +1,28 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <address@hidden>
+ *
+ * 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 "instrument/control.h"
+#include "instrument/error.h"
+#include "instrument/events.h"
+#include "instrument/load.h"
+#include "instrument/qemu-instr/control.h"
+#include "instrument/qemu-instr/visibility.h"
+
+__thread InstrState instr_cur_state;
+
+
+qi_fini_fn instr_event__fini_fn;
+void *instr_event__fini_data;
+
+QI_VPUBLIC void qi_set_fini(qi_fini_fn fn, void *data)
+{
+ ERROR_IF(!instr_get_state(), "called outside instrumentation");
+ instr_set_event(fini_fn, fn);
+ instr_set_event(fini_data, data);
+}
diff --git a/instrument/control.h b/instrument/control.h
new file mode 100644
index 0000000000..f2b085f69b
--- /dev/null
+++ b/instrument/control.h
@@ -0,0 +1,44 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <address@hidden>
+ *
+ * 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 INSTRUMENT__CONTROL_H
+#define INSTRUMENT__CONTROL_H
+
+
+/**
+ * InstrState:
+ * @INSTR_STATE_DISABLE: Intrumentation API not available.
+ * @INSTR_STATE_ENABLE: Intrumentation API available.
+ *
+ * Instrumentation state of current host thread. Used to ensure instrumentation
+ * clients use QEMU's API only in expected points.
+ */
+typedef enum {
+ INSTR_STATE_DISABLE,
+ INSTR_STATE_ENABLE,
+} InstrState;
+
+/**
+ * instr_set_state:
+ *
+ * Set the instrumentation state of the current host thread.
+ */
+static inline void instr_set_state(InstrState state);
+
+/**
+ * instr_get_state:
+ *
+ * Get the instrumentation state of the current host thread.
+ */
+static inline InstrState instr_get_state(void);
+
+
+#include "instrument/control.inc.h"
+
+#endif /* INSTRUMENT__CONTROL_H */
diff --git a/instrument/control.inc.h b/instrument/control.inc.h
new file mode 100644
index 0000000000..0f649f4caa
--- /dev/null
+++ b/instrument/control.inc.h
@@ -0,0 +1,25 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <address@hidden>
+ *
+ * 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/atomic.h"
+#include "qemu/compiler.h"
+#include <stdbool.h>
+
+
+extern __thread InstrState instr_cur_state;
+
+static inline void instr_set_state(InstrState state)
+{
+ atomic_store_release(&instr_cur_state, state);
+}
+
+static inline InstrState instr_get_state(void)
+{
+ return atomic_load_acquire(&instr_cur_state);
+}
diff --git a/instrument/error.h b/instrument/error.h
new file mode 100644
index 0000000000..f8d1dd4b16
--- /dev/null
+++ b/instrument/error.h
@@ -0,0 +1,28 @@
+/*
+ * Helpers for controlling errors in instrumentation libraries.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <address@hidden>
+ *
+ * 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 INSTRUMENT_ERROR_H
+#define INSTRUMENT_ERROR_H
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+
+
+#define _ERROR(msg, args...) \
+ do { \
+ error_report("%s:" msg, __func__, ##args); \
+ } while (0)
+
+#define ERROR_IF(cond, msg, args...) \
+ if (unlikely(cond)) { \
+ _ERROR(msg, ##args); \
+ return; \
+ }
+
+#endif /* INSTRUMENT_ERROR_H */
diff --git a/instrument/events.h b/instrument/events.h
new file mode 100644
index 0000000000..82ad0bd827
--- /dev/null
+++ b/instrument/events.h
@@ -0,0 +1,37 @@
+/*
+ * Internal API for triggering instrumentation events.
+ *
+ * Copyright (C) 2017 Lluís Vilanova <address@hidden>
+ *
+ * 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 INSTRUMENT__EVENTS_H
+#define INSTRUMENT__EVENTS_H
+
+#include "instrument/qemu-instr/control.h"
+
+/**
+ * instr_get_event:
+ *
+ * Get value set by instrumentation library.
+ */
+#define instr_get_event(name) \
+ atomic_load_acquire(&instr_event__ ## name)
+
+/**
+ * instr_get_event:
+ *
+ * Set value from instrumentation library.
+ */
+#define instr_set_event(name, fn) \
+ atomic_store_release(&instr_event__ ## name, fn)
+
+
+extern qi_fini_fn instr_event__fini_fn;
+extern void *instr_event__fini_data;
+
+#include "instrument/events.inc.h"
+
+#endif /* INSTRUMENT__EVENTS_H */
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
new file mode 100644
index 0000000000..8b1ce7fcb2
--- /dev/null
+++ b/instrument/events.inc.h
@@ -0,0 +1,11 @@
+/*
+ * Internal API for triggering instrumentation events.
+ *
+ * Copyright (C) 2017 Lluís Vilanova <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+
+
diff --git a/instrument/load.c b/instrument/load.c
index a57401102a..e180f03429 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -11,6 +11,8 @@
#include "qemu-common.h"
#include <dlfcn.h>
+#include "instrument/control.h"
+#include "instrument/events.h"
#include "instrument/load.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
@@ -105,8 +107,11 @@ InstrLoadError instr_load(const char * path, int argc,
const char ** argv,
res = INSTR_LOAD_DLERROR;
goto err;
}
+ instr_set_event(fini_fn, NULL);
+ instr_set_state(INSTR_STATE_ENABLE);
main_res = main_cb(argc, argv);
+ instr_set_state(INSTR_STATE_DISABLE);
if (main_res != 0) {
res = INSTR_LOAD_ERROR;
@@ -136,6 +141,14 @@ InstrUnloadError instr_unload(int64_t handle_id)
goto out;
}
+ qi_fini_fn fini_fn = instr_get_event(fini_fn);
+ if (fini_fn) {
+ void *fini_data = instr_get_event(fini_data);
+ fini_fn(fini_data);
+ }
+
+ instr_set_event(fini_fn, NULL);
+
/* this should never fail */
if (dlclose(handle->dlhandle) < 0) {
res = INSTR_UNLOAD_DLERROR;
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
new file mode 100644
index 0000000000..f6e289daa0
--- /dev/null
+++ b/instrument/qemu-instr/control.h
@@ -0,0 +1,43 @@
+/*
+ * Main instrumentation interface for QEMU.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <address@hidden>
+ *
+ * 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__CONTROL_H
+#define QI__CONTROL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stddef.h>
+
+
+/**
+ * SECTION:control
+ * @section_id: qi-control
+ * @title: Event control API for QEMU event instrumentation
+ */
+
+typedef void (*qi_fini_fn)(void *arg);
+
+/**
+ * qi_set_fini:
+ * @fn: Finalization function.
+ * @data: Argument to pass to the finalization function.
+ *
+ * Set the function to call when finalizing (unloading) the instrumentation
+ * library.
+ */
+void qi_set_fini(qi_fini_fn fn, void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QI__CONTROL_H */
diff --git a/instrument/qemu-instr/visibility.h
b/instrument/qemu-instr/visibility.h
new file mode 100644
index 0000000000..305dddf7d8
--- /dev/null
+++ b/instrument/qemu-instr/visibility.h
@@ -0,0 +1,58 @@
+/*
+ * Macros for symbol visibility.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory of QEMU.
+ */
+
+#ifndef QI__VISIBILITY_H
+#define QI__VISIBILITY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * SECTION:visibility
+ * @section_id: qi-visibility
+ * @title: Symbol visibility
+ *
+ * This code is taken from http://gcc.gnu.org/wiki/Visibility.
+ */
+
+/**
+ * QI_VPUBLIC:
+ *
+ * Make an element public to user's instrumentation code.
+ */
+
+/**
+ * QI_VLOCAL:
+ *
+ * Make an element not visible to user's instrumentation code.
+ */
+
+#if defined _WIN32 || defined __CYGWIN__
+ #ifdef __GNUC__
+ #define QI_VPUBLIC __attribute__ ((dllimport))
+ #else
+ #define QI_VPUBLIC __declspec(dllimport)
+ #endif
+ #define QI_VLOCAL
+#else
+ #if __GNUC__ >= 4
+ #define QI_VPUBLIC __attribute__ ((visibility ("default")))
+ #define QI_VLOCAL __attribute__ ((visibility ("hidden")))
+ #else
+ #define QI_VPUBLIC
+ #define QI_VLOCAL
+ #endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QI__VISIBILITY_H */
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index e69c217aff..3aaec2d9dd 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -13,6 +13,7 @@ stub-obj-y += error-printf.o
stub-obj-y += fdset.o
stub-obj-y += gdbstub.o
stub-obj-y += get-vm-name.o
+stub-obj-y += instrument.o
stub-obj-y += iothread.o
stub-obj-y += iothread-lock.o
stub-obj-y += is-daemonized.o
diff --git a/stubs/instrument.c b/stubs/instrument.c
new file mode 100644
index 0000000000..6731710fd5
--- /dev/null
+++ b/stubs/instrument.c
@@ -0,0 +1,13 @@
+/*
+ * Instrumentation placeholders.
+ *
+ * Copyright (C) 2017 Lluís Vilanova <address@hidden>
+ *
+ * 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 "instrument/control.h"
+
+
+__thread InstrState instr_cur_state;
- Re: [Qemu-devel] [PATCH v4 03/20] instrument: Add generic library loader, (continued)
- [Qemu-devel] [PATCH v4 04/20] instrument: [linux-user] Add command line library loader, Lluís Vilanova, 2017/09/06
- [Qemu-devel] [PATCH v4 05/20] instrument: [bsd-user] Add command line library loader, Lluís Vilanova, 2017/09/06
- [Qemu-devel] [PATCH v4 06/20] instrument: [softmmu] Add command line library loader, Lluís Vilanova, 2017/09/06
- [Qemu-devel] [PATCH v4 07/20] instrument: [qapi] Add library loader, Lluís Vilanova, 2017/09/06
- [Qemu-devel] [PATCH v4 08/20] instrument: [hmp] Add library loader, Lluís Vilanova, 2017/09/06
- [Qemu-devel] [PATCH v4 09/20] instrument: Add basic control interface,
Lluís Vilanova <=
- [Qemu-devel] [PATCH v4 10/20] instrument: Add support for tracing events, Lluís Vilanova, 2017/09/06
- [Qemu-devel] [PATCH v4 11/20] instrument: Track vCPUs, Lluís Vilanova, 2017/09/06
- [Qemu-devel] [PATCH v4 12/20] instrument: Add event 'guest_cpu_enter', Lluís Vilanova, 2017/09/06
- [Qemu-devel] [PATCH v4 13/20] instrument: Add event 'guest_cpu_exit', Lluís Vilanova, 2017/09/06
- [Qemu-devel] [PATCH v4 14/20] instrument: Add event 'guest_cpu_reset', Lluís Vilanova, 2017/09/06