* [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location
@ 2017-12-19 1:06 Lionel Landwerlin
2017-12-19 1:09 ` ✗ Fi.CI.BAT: failure for overlay: parse tracepoints from sysfs to figure out fields' location (rev2) Patchwork
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Lionel Landwerlin @ 2017-12-19 1:06 UTC (permalink / raw)
To: intel-gfx
With changes going to drm-tip, the tracepoints field locations are
going to change. This change introduces a tracepoint parser (using a
peg parser) which lets us figure out field positions on the fly.
v2: Fix automake build (Lionel)
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
configure.ac | 5 ++
overlay/Makefile.am | 5 ++
overlay/gpu-perf.c | 164 ++++++++++++++++++++++++++++++++++--------
overlay/meson.build | 11 ++-
overlay/tracepoint_format.leg | 34 +++++++++
5 files changed, 189 insertions(+), 30 deletions(-)
create mode 100644 overlay/tracepoint_format.leg
diff --git a/configure.ac b/configure.ac
index 8740f7a4..f87f227a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -146,6 +146,11 @@ if test x"$build_x86" = xyes; then
AS_IF([test x"$LEX" != "x:" -a x"$YACC" != xyacc],
[enable_assembler=yes],
[enable_assembler=no])
+
+ AC_CHECK_TOOL([LEG], [leg])
+ if test "x$LEG" != "xleg"; then
+ AC_MSG_ERROR([leg command missing, try : apt-get install peg])
+ fi
else
enable_overlay_xvlib="no"
enable_overlay_xlib="no"
diff --git a/overlay/Makefile.am b/overlay/Makefile.am
index fca04cae..0f553b7c 100644
--- a/overlay/Makefile.am
+++ b/overlay/Makefile.am
@@ -1,7 +1,12 @@
if BUILD_OVERLAY
bin_PROGRAMS = intel-gpu-overlay
+
+BUILT_SOURCES = tracepoint_format.h
endif
+tracepoint_format.h: tracepoint_format.leg
+ $(LEG) -o $@ $<
+
AM_CPPFLAGS = -I. -I$(top_srcdir)/include/drm-uapi
AM_CFLAGS = $(DRM_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS) \
$(CAIRO_CFLAGS) $(OVERLAY_CFLAGS) $(WERROR_CFLAGS) -I$(srcdir)/../lib
diff --git a/overlay/gpu-perf.c b/overlay/gpu-perf.c
index 3d4a9be9..7fa561e3 100644
--- a/overlay/gpu-perf.c
+++ b/overlay/gpu-perf.c
@@ -57,25 +57,120 @@ struct sample_event {
uint64_t time;
uint64_t id;
uint32_t raw_size;
- uint32_t raw_hdr0;
- uint32_t raw_hdr1;
- uint32_t raw[0];
+ uint8_t tracepoint_data[0];
};
enum {
- DEVICE = 0,
- CTX,
- ENGINE,
- CTX_SEQNO,
- GLOBAL_SEQNO
+ TP_GEM_REQUEST_ADD,
+ TP_GEM_REQUEST_WAIT_BEGIN,
+ TP_GEM_REQUEST_WAIT_END,
+ TP_FLIP_COMPLETE,
+ TP_GEM_RING_SYNC_TO,
+ TP_GEM_RING_SWITCH_CONTEXT,
+
+ TP_NB
};
-static uint64_t tracepoint_id(const char *sys, const char *name)
+struct tracepoint {
+ struct {
+ char name[128];
+ int offset;
+ int size;
+ int is_signed;
+ } fields[20];
+ const char *name;
+ int n_fields;
+
+ int device_field;
+ int ctx_field;
+ int ring_field;
+ int seqno_field;
+ int global_seqno_field;
+ int plane_field;
+} tracepoints[TP_NB] = {
+ [TP_GEM_REQUEST_ADD] = { .name = "i915/i915_gem_request_add", },
+ [TP_GEM_REQUEST_WAIT_BEGIN] = { .name = "i915/i915_gem_request_wait_begin", },
+ [TP_GEM_REQUEST_WAIT_END] = { .name = "i915/i915_gem_request_wait_end", },
+ [TP_FLIP_COMPLETE] = { .name = "i915/flip_complete", },
+ [TP_GEM_RING_SYNC_TO] = { .name = "i915/gem_ring_sync_to", },
+ [TP_GEM_RING_SWITCH_CONTEXT] = { .name = "i915/gem_ring_switch_context", },
+};
+
+union parser_value {
+ char *string;
+ int integer;
+};
+
+struct parser_ctx {
+ struct tracepoint *tp;
+ FILE *fp;
+};
+
+#define YY_CTX_LOCAL
+#define YY_CTX_MEMBERS struct parser_ctx ctx;
+#define YYSTYPE union parser_value
+#define YY_PARSE(T) static T
+#define YY_INPUT(yy, buf, result, max) \
+ { \
+ int yyc = getc(yy->ctx.fp); \
+ result = (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \
+ }
+
+#include "tracepoint_format.h"
+
+static int
+parse_tracepoint(int tp_id)
+{
+ struct tracepoint *tp = &tracepoints[tp_id];
+ yycontext ctx;
+ char buf[1024];
+
+ /* Already parsed? */
+ if (tp->n_fields != 0)
+ return 0;
+
+ snprintf(buf, sizeof(buf), "%s/tracing/events/%s/format",
+ debugfs_path, tp->name);
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.ctx.tp = tp;
+ ctx.ctx.fp = fopen(buf, "r");
+
+ if (ctx.ctx.fp == NULL)
+ return 0;
+
+ if (yyparse(&ctx)) {
+ for (int f = 0; f < tp->n_fields; f++) {
+ if (!strcmp(tp->fields[f].name, "device")) {
+ tp->device_field = f;
+ } else if (!strcmp(tp->fields[f].name, "ctx")) {
+ tp->ctx_field = f;
+ } else if (!strcmp(tp->fields[f].name, "ring")) {
+ tp->ring_field = f;
+ } else if (!strcmp(tp->fields[f].name, "seqno")) {
+ tp->seqno_field = f;
+ } else if (!strcmp(tp->fields[f].name, "global_seqno")) {
+ tp->global_seqno_field = f;
+ } else if (!strcmp(tp->fields[f].name, "plane")) {
+ tp->plane_field = f;
+ }
+ }
+ } else
+ tp->n_fields = 0;
+
+ yyrelease(&ctx);
+ fclose(ctx.ctx.fp);
+
+ return tp->n_fields;
+}
+
+static uint64_t tracepoint_id(int tp_id)
{
char buf[1024];
int fd, n;
- snprintf(buf, sizeof(buf), "%s/tracing/events/%s/%s/id", debugfs_path, sys, name);
+ snprintf(buf, sizeof(buf), "%s/tracing/events/%s/id", debugfs_path,
+ tracepoints[tp_id].name);
fd = open(buf, 0);
if (fd < 0)
return 0;
@@ -88,8 +183,12 @@ static uint64_t tracepoint_id(const char *sys, const char *name)
return strtoull(buf, 0, 0);
}
-static int perf_tracepoint_open(struct gpu_perf *gp,
- const char *sys, const char *name,
+#define READ_TP_FIELD_U32(sample, tp_id, field_name) \
+ (*(const uint32_t *)((sample)->tracepoint_data + \
+ tracepoints[tp_id].fields[ \
+ tracepoints[tp_id].field_name##_field].offset))
+
+static int perf_tracepoint_open(struct gpu_perf *gp, int tp_id,
int (*func)(struct gpu_perf *, const void *))
{
struct perf_event_attr attr;
@@ -99,10 +198,13 @@ static int perf_tracepoint_open(struct gpu_perf *gp,
memset(&attr, 0, sizeof (attr));
attr.type = PERF_TYPE_TRACEPOINT;
- attr.config = tracepoint_id(sys, name);
+ attr.config = tracepoint_id(tp_id);
if (attr.config == 0)
return ENOENT;
+ if (parse_tracepoint(tp_id) == 0)
+ return ENOENT;
+
attr.sample_period = 1;
attr.sample_type = (PERF_SAMPLE_TIME | PERF_SAMPLE_STREAM_ID | PERF_SAMPLE_TID | PERF_SAMPLE_RAW);
attr.read_format = PERF_FORMAT_ID;
@@ -227,7 +329,7 @@ static int request_add(struct gpu_perf *gp, const void *event)
if (comm == NULL)
return 0;
- comm->nr_requests[sample->raw[ENGINE]]++;
+ comm->nr_requests[READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_ADD, ring)]++;
return 1;
}
@@ -235,7 +337,7 @@ static int flip_complete(struct gpu_perf *gp, const void *event)
{
const struct sample_event *sample = event;
- gp->flip_complete[sample->raw[0]]++;
+ gp->flip_complete[READ_TP_FIELD_U32(sample, TP_FLIP_COMPLETE, plane)]++;
return 1;
}
@@ -243,7 +345,7 @@ static int ctx_switch(struct gpu_perf *gp, const void *event)
{
const struct sample_event *sample = event;
- gp->ctx_switch[sample->raw[ENGINE]]++;
+ gp->ctx_switch[READ_TP_FIELD_U32(sample, TP_GEM_RING_SWITCH_CONTEXT, ring)]++;
return 1;
}
@@ -278,11 +380,11 @@ static int wait_begin(struct gpu_perf *gp, const void *event)
wait->comm = comm;
wait->comm->active = true;
- wait->context = sample->raw[ENGINE];
- wait->seqno = sample->raw[CTX_SEQNO];
+ wait->context = READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_BEGIN, ctx);
+ wait->seqno = READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_BEGIN, seqno);
wait->time = sample->time;
- wait->next = gp->wait[sample->raw[CTX]];
- gp->wait[sample->raw[CTX]] = wait;
+ wait->next = gp->wait[READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_BEGIN, ring)];
+ gp->wait[READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_BEGIN, ring)] = wait;
return 0;
}
@@ -292,9 +394,13 @@ static int wait_end(struct gpu_perf *gp, const void *event)
const struct sample_event *sample = event;
struct gpu_perf_time *wait, **prev;
- for (prev = &gp->wait[sample->raw[ENGINE]]; (wait = *prev) != NULL; prev = &wait->next) {
- if (wait->context != sample->raw[CTX] ||
- wait->seqno != sample->raw[CTX_SEQNO])
+ for (prev = &gp->wait[READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_END, ring)];
+ (wait = *prev) != NULL;
+ prev = &wait->next) {
+ if (wait->context != READ_TP_FIELD_U32(sample,
+ TP_GEM_REQUEST_WAIT_END, ctx) ||
+ wait->seqno != READ_TP_FIELD_U32(sample,
+ TP_GEM_REQUEST_WAIT_END, seqno))
continue;
wait->comm->wait_time += sample->time - wait->time;
@@ -314,12 +420,12 @@ void gpu_perf_init(struct gpu_perf *gp, unsigned flags)
gp->nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
gp->page_size = getpagesize();
- perf_tracepoint_open(gp, "i915", "i915_gem_request_add", request_add);
- if (perf_tracepoint_open(gp, "i915", "i915_gem_request_wait_begin", wait_begin) == 0)
- perf_tracepoint_open(gp, "i915", "i915_gem_request_wait_end", wait_end);
- perf_tracepoint_open(gp, "i915", "i915_flip_complete", flip_complete);
- perf_tracepoint_open(gp, "i915", "i915_gem_ring_sync_to", ring_sync);
- perf_tracepoint_open(gp, "i915", "i915_gem_ring_switch_context", ctx_switch);
+ perf_tracepoint_open(gp, TP_GEM_REQUEST_ADD, request_add);
+ if (perf_tracepoint_open(gp, TP_GEM_REQUEST_WAIT_BEGIN, wait_begin) == 0)
+ perf_tracepoint_open(gp, TP_GEM_REQUEST_WAIT_END, wait_end);
+ perf_tracepoint_open(gp, TP_FLIP_COMPLETE, flip_complete);
+ perf_tracepoint_open(gp, TP_GEM_RING_SYNC_TO, ring_sync);
+ perf_tracepoint_open(gp, TP_GEM_RING_SWITCH_CONTEXT, ctx_switch);
if (gp->nr_events == 0) {
gp->error = "i915.ko tracepoints not available";
diff --git a/overlay/meson.build b/overlay/meson.build
index afacff5e..6a5691dc 100644
--- a/overlay/meson.build
+++ b/overlay/meson.build
@@ -14,6 +14,14 @@ gpu_overlay_src = [
'rc6.c',
]
+leg = find_program('leg', required : true)
+leg_gen = generator(leg,
+ output : '@BASENAME@.h',
+ arguments : ['-o', '@OUTPUT@', '@INPUT@'])
+leg_file = leg_gen.process('tracepoint_format.leg')
+leg_lib = static_library('leg', leg_file)
+leg_inc = leg_lib.private_dir_include()
+
xv = dependency('xv', required : false)
x11 = dependency('x11', required : false)
xext = dependency('xext', required : false)
@@ -53,8 +61,9 @@ gpu_overlay_src += 'kms/kms-overlay.c'
if xrandr.found() and cairo.found()
executable('intel-gpu-overlay', gpu_overlay_src,
- include_directories : inc,
+ include_directories : [inc, leg_inc],
c_args : gpu_overlay_cflags,
dependencies : gpu_overlay_deps,
+ link_with : leg_lib,
install : true)
endif
diff --git a/overlay/tracepoint_format.leg b/overlay/tracepoint_format.leg
new file mode 100644
index 00000000..ea83db91
--- /dev/null
+++ b/overlay/tracepoint_format.leg
@@ -0,0 +1,34 @@
+TracepointFormat =
+ 'name' ':' Space PropertyName EndLine
+ 'ID' ':' Space Number EndLine
+ 'format' ':' EndLine
+ Field+
+ 'print fmt' ':' .*
+ !.
+
+Field = Space (Property ';' Space)+ EndLine
+ { yy->ctx.tp->n_fields++; }
+ | EndLine
+
+Property = 'offset' ':' v:Number
+ { yy->ctx.tp->fields[yy->ctx.tp->n_fields].offset = v.integer; }
+ | 'size' ':' v:Number
+ { yy->ctx.tp->fields[yy->ctx.tp->n_fields].size = v.integer; }
+ | 'signed' ':' v:Number
+ { yy->ctx.tp->fields[yy->ctx.tp->n_fields].is_signed = v.integer != 0; }
+ | 'field' ':' v:PropertyValue
+ { snprintf(yy->ctx.tp->fields[yy->ctx.tp->n_fields].name,
+ sizeof(yy->ctx.tp->fields[yy->ctx.tp->n_fields].name),
+ "%s", strrchr(v.string, ' ') + 1); free(v.string); }
+ | n:PropertyName ':' v:PropertyValue
+ { free(n.string); free(v.string); }
+
+PropertyName = < [A-Za-z0-9_]+ >
+ { $$.string = strdup(yytext); }
+PropertyValue = < [^;]+ >
+ { $$.string = strdup(yytext); }
+Number = < [0-9]+ >
+ { $$.integer = atoi(yytext); }
+
+EndLine = [\n]
+Space = [ \t]*
--
2.15.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 6+ messages in thread* ✗ Fi.CI.BAT: failure for overlay: parse tracepoints from sysfs to figure out fields' location (rev2) 2017-12-19 1:06 [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location Lionel Landwerlin @ 2017-12-19 1:09 ` Patchwork 2017-12-19 8:22 ` Patchwork ` (3 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: Patchwork @ 2017-12-19 1:09 UTC (permalink / raw) To: Lionel Landwerlin; +Cc: intel-gfx == Series Details == Series: overlay: parse tracepoints from sysfs to figure out fields' location (rev2) URL : https://patchwork.freedesktop.org/series/35545/ State : failure == Summary == IGT patchset build failed on latest successful build cfb711c046c22c3881d2334f0b43ec4eb0b9a5fc scripts/trace.pl: Auto-detect tracepoint field order make: *** No targets specified and no makefile found. Stop. _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 6+ messages in thread
* ✗ Fi.CI.BAT: failure for overlay: parse tracepoints from sysfs to figure out fields' location (rev2) 2017-12-19 1:06 [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location Lionel Landwerlin 2017-12-19 1:09 ` ✗ Fi.CI.BAT: failure for overlay: parse tracepoints from sysfs to figure out fields' location (rev2) Patchwork @ 2017-12-19 8:22 ` Patchwork 2017-12-19 8:35 ` Patchwork ` (2 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: Patchwork @ 2017-12-19 8:22 UTC (permalink / raw) To: Lionel Landwerlin; +Cc: intel-gfx == Series Details == Series: overlay: parse tracepoints from sysfs to figure out fields' location (rev2) URL : https://patchwork.freedesktop.org/series/35545/ State : failure == Summary == IGT patchset build failed on latest successful build cfb711c046c22c3881d2334f0b43ec4eb0b9a5fc scripts/trace.pl: Auto-detect tracepoint field order make: *** No targets specified and no makefile found. Stop. _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 6+ messages in thread
* ✗ Fi.CI.BAT: failure for overlay: parse tracepoints from sysfs to figure out fields' location (rev2) 2017-12-19 1:06 [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location Lionel Landwerlin 2017-12-19 1:09 ` ✗ Fi.CI.BAT: failure for overlay: parse tracepoints from sysfs to figure out fields' location (rev2) Patchwork 2017-12-19 8:22 ` Patchwork @ 2017-12-19 8:35 ` Patchwork 2017-12-19 9:34 ` [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location Chris Wilson 2017-12-19 10:08 ` Petri Latvala 4 siblings, 0 replies; 6+ messages in thread From: Patchwork @ 2017-12-19 8:35 UTC (permalink / raw) To: Lionel Landwerlin; +Cc: intel-gfx == Series Details == Series: overlay: parse tracepoints from sysfs to figure out fields' location (rev2) URL : https://patchwork.freedesktop.org/series/35545/ State : failure == Summary == IGT patchset build failed on latest successful build cfb711c046c22c3881d2334f0b43ec4eb0b9a5fc scripts/trace.pl: Auto-detect tracepoint field order checking if gcc supports -Werror=trigraphs... yes checking if gcc supports -Werror=array-bounds... yes checking if gcc supports -Werror=write-strings... yes checking if gcc supports -Werror=address... yes checking if gcc supports -Werror=int-to-pointer-cast... yes checking if gcc supports -Werror=pointer-to-int-cast... yes checking if gcc supports -pedantic... yes checking if gcc supports -Werror... yes checking if gcc supports -Werror=attributes... yes checking whether make supports nested variables... (cached) yes checking for DRM... yes checking for PCIACCESS... yes checking for KMOD... yes checking for PROCPS... yes checking for LIBUNWIND... yes checking for VALGRIND... no checking for OVERLAY_XVLIB... yes checking for OVERLAY_XLIB... yes checking for leg... no configure: error: leg command missing, try : apt-get install peg _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location 2017-12-19 1:06 [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location Lionel Landwerlin ` (2 preceding siblings ...) 2017-12-19 8:35 ` Patchwork @ 2017-12-19 9:34 ` Chris Wilson 2017-12-19 10:08 ` Petri Latvala 4 siblings, 0 replies; 6+ messages in thread From: Chris Wilson @ 2017-12-19 9:34 UTC (permalink / raw) To: Lionel Landwerlin, intel-gfx Quoting Lionel Landwerlin (2017-12-19 01:06:18) > With changes going to drm-tip, the tracepoints field locations are > going to change. This change introduces a tracepoint parser (using a > peg parser) which lets us figure out field positions on the fly. > > v2: Fix automake build (Lionel) > > Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> > --- > @@ -292,9 +394,13 @@ static int wait_end(struct gpu_perf *gp, const void *event) > const struct sample_event *sample = event; > struct gpu_perf_time *wait, **prev; u32 engine = READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_END, ring); u32 context = READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_END, ctx); u32 seqno = READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_END, seqno); > - for (prev = &gp->wait[sample->raw[ENGINE]]; (wait = *prev) != NULL; prev = &wait->next) { > - if (wait->context != sample->raw[CTX] || > - wait->seqno != sample->raw[CTX_SEQNO]) > + for (prev = &gp->wait[READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_END, ring)]; > + (wait = *prev) != NULL; > + prev = &wait->next) { > + if (wait->context != READ_TP_FIELD_U32(sample, > + TP_GEM_REQUEST_WAIT_END, ctx) || > + wait->seqno != READ_TP_FIELD_U32(sample, > + TP_GEM_REQUEST_WAIT_END, seqno)) > continue; Looks very useful, thanks! -Chris _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location 2017-12-19 1:06 [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location Lionel Landwerlin ` (3 preceding siblings ...) 2017-12-19 9:34 ` [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location Chris Wilson @ 2017-12-19 10:08 ` Petri Latvala 4 siblings, 0 replies; 6+ messages in thread From: Petri Latvala @ 2017-12-19 10:08 UTC (permalink / raw) To: Lionel Landwerlin; +Cc: intel-gfx On Tue, Dec 19, 2017 at 01:06:18AM +0000, Lionel Landwerlin wrote: > With changes going to drm-tip, the tracepoints field locations are > going to change. This change introduces a tracepoint parser (using a > peg parser) which lets us figure out field positions on the fly. > > v2: Fix automake build (Lionel) > > Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Adding a new dependency that doesn't involve the tests; that would be preferrable to be optional. I gave some snippets already on IRC, here they are in email form. > --- > configure.ac | 5 ++ > overlay/Makefile.am | 5 ++ > overlay/gpu-perf.c | 164 ++++++++++++++++++++++++++++++++++-------- > overlay/meson.build | 11 ++- > overlay/tracepoint_format.leg | 34 +++++++++ > 5 files changed, 189 insertions(+), 30 deletions(-) > create mode 100644 overlay/tracepoint_format.leg > > diff --git a/configure.ac b/configure.ac > index 8740f7a4..f87f227a 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -146,6 +146,11 @@ if test x"$build_x86" = xyes; then > AS_IF([test x"$LEX" != "x:" -a x"$YACC" != xyacc], > [enable_assembler=yes], > [enable_assembler=no]) > + > + AC_CHECK_TOOL([LEG], [leg]) > + if test "x$LEG" != "xleg"; then > + AC_MSG_ERROR([leg command missing, try : apt-get install peg]) > + fi > else Squash for making peg optional: AC_CHECK_TOOL([LEG], [leg]) if test "x$LEG" != "xleg"; then - AC_MSG_ERROR([leg command missing, try : apt-get install peg]) + AC_MSG_NOTICE([leg command missing, disabling overlay; try : apt-get install peg]) + enable_overlay_xvlib="no" + enable_overlay_xlib="no" fi > enable_overlay_xvlib="no" > enable_overlay_xlib="no" > diff --git a/overlay/Makefile.am b/overlay/Makefile.am > index fca04cae..0f553b7c 100644 > --- a/overlay/Makefile.am > +++ b/overlay/Makefile.am > @@ -1,7 +1,12 @@ > if BUILD_OVERLAY > bin_PROGRAMS = intel-gpu-overlay > + > +BUILT_SOURCES = tracepoint_format.h > endif > > +tracepoint_format.h: tracepoint_format.leg > + $(LEG) -o $@ $< > + > AM_CPPFLAGS = -I. -I$(top_srcdir)/include/drm-uapi > AM_CFLAGS = $(DRM_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS) \ > $(CAIRO_CFLAGS) $(OVERLAY_CFLAGS) $(WERROR_CFLAGS) -I$(srcdir)/../lib > diff --git a/overlay/gpu-perf.c b/overlay/gpu-perf.c > index 3d4a9be9..7fa561e3 100644 > --- a/overlay/gpu-perf.c > +++ b/overlay/gpu-perf.c > @@ -57,25 +57,120 @@ struct sample_event { > uint64_t time; > uint64_t id; > uint32_t raw_size; > - uint32_t raw_hdr0; > - uint32_t raw_hdr1; > - uint32_t raw[0]; > + uint8_t tracepoint_data[0]; > }; > > enum { > - DEVICE = 0, > - CTX, > - ENGINE, > - CTX_SEQNO, > - GLOBAL_SEQNO > + TP_GEM_REQUEST_ADD, > + TP_GEM_REQUEST_WAIT_BEGIN, > + TP_GEM_REQUEST_WAIT_END, > + TP_FLIP_COMPLETE, > + TP_GEM_RING_SYNC_TO, > + TP_GEM_RING_SWITCH_CONTEXT, > + > + TP_NB > }; > > -static uint64_t tracepoint_id(const char *sys, const char *name) > +struct tracepoint { > + struct { > + char name[128]; > + int offset; > + int size; > + int is_signed; > + } fields[20]; > + const char *name; > + int n_fields; > + > + int device_field; > + int ctx_field; > + int ring_field; > + int seqno_field; > + int global_seqno_field; > + int plane_field; > +} tracepoints[TP_NB] = { > + [TP_GEM_REQUEST_ADD] = { .name = "i915/i915_gem_request_add", }, > + [TP_GEM_REQUEST_WAIT_BEGIN] = { .name = "i915/i915_gem_request_wait_begin", }, > + [TP_GEM_REQUEST_WAIT_END] = { .name = "i915/i915_gem_request_wait_end", }, > + [TP_FLIP_COMPLETE] = { .name = "i915/flip_complete", }, > + [TP_GEM_RING_SYNC_TO] = { .name = "i915/gem_ring_sync_to", }, > + [TP_GEM_RING_SWITCH_CONTEXT] = { .name = "i915/gem_ring_switch_context", }, > +}; > + > +union parser_value { > + char *string; > + int integer; > +}; > + > +struct parser_ctx { > + struct tracepoint *tp; > + FILE *fp; > +}; > + > +#define YY_CTX_LOCAL > +#define YY_CTX_MEMBERS struct parser_ctx ctx; > +#define YYSTYPE union parser_value > +#define YY_PARSE(T) static T > +#define YY_INPUT(yy, buf, result, max) \ > + { \ > + int yyc = getc(yy->ctx.fp); \ > + result = (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ > + } > + > +#include "tracepoint_format.h" > + > +static int > +parse_tracepoint(int tp_id) > +{ > + struct tracepoint *tp = &tracepoints[tp_id]; > + yycontext ctx; > + char buf[1024]; > + > + /* Already parsed? */ > + if (tp->n_fields != 0) > + return 0; > + > + snprintf(buf, sizeof(buf), "%s/tracing/events/%s/format", > + debugfs_path, tp->name); > + > + memset(&ctx, 0, sizeof(ctx)); > + ctx.ctx.tp = tp; > + ctx.ctx.fp = fopen(buf, "r"); > + > + if (ctx.ctx.fp == NULL) > + return 0; > + > + if (yyparse(&ctx)) { > + for (int f = 0; f < tp->n_fields; f++) { > + if (!strcmp(tp->fields[f].name, "device")) { > + tp->device_field = f; > + } else if (!strcmp(tp->fields[f].name, "ctx")) { > + tp->ctx_field = f; > + } else if (!strcmp(tp->fields[f].name, "ring")) { > + tp->ring_field = f; > + } else if (!strcmp(tp->fields[f].name, "seqno")) { > + tp->seqno_field = f; > + } else if (!strcmp(tp->fields[f].name, "global_seqno")) { > + tp->global_seqno_field = f; > + } else if (!strcmp(tp->fields[f].name, "plane")) { > + tp->plane_field = f; > + } > + } > + } else > + tp->n_fields = 0; > + > + yyrelease(&ctx); > + fclose(ctx.ctx.fp); > + > + return tp->n_fields; > +} > + > +static uint64_t tracepoint_id(int tp_id) > { > char buf[1024]; > int fd, n; > > - snprintf(buf, sizeof(buf), "%s/tracing/events/%s/%s/id", debugfs_path, sys, name); > + snprintf(buf, sizeof(buf), "%s/tracing/events/%s/id", debugfs_path, > + tracepoints[tp_id].name); > fd = open(buf, 0); > if (fd < 0) > return 0; > @@ -88,8 +183,12 @@ static uint64_t tracepoint_id(const char *sys, const char *name) > return strtoull(buf, 0, 0); > } > > -static int perf_tracepoint_open(struct gpu_perf *gp, > - const char *sys, const char *name, > +#define READ_TP_FIELD_U32(sample, tp_id, field_name) \ > + (*(const uint32_t *)((sample)->tracepoint_data + \ > + tracepoints[tp_id].fields[ \ > + tracepoints[tp_id].field_name##_field].offset)) > + > +static int perf_tracepoint_open(struct gpu_perf *gp, int tp_id, > int (*func)(struct gpu_perf *, const void *)) > { > struct perf_event_attr attr; > @@ -99,10 +198,13 @@ static int perf_tracepoint_open(struct gpu_perf *gp, > memset(&attr, 0, sizeof (attr)); > > attr.type = PERF_TYPE_TRACEPOINT; > - attr.config = tracepoint_id(sys, name); > + attr.config = tracepoint_id(tp_id); > if (attr.config == 0) > return ENOENT; > > + if (parse_tracepoint(tp_id) == 0) > + return ENOENT; > + > attr.sample_period = 1; > attr.sample_type = (PERF_SAMPLE_TIME | PERF_SAMPLE_STREAM_ID | PERF_SAMPLE_TID | PERF_SAMPLE_RAW); > attr.read_format = PERF_FORMAT_ID; > @@ -227,7 +329,7 @@ static int request_add(struct gpu_perf *gp, const void *event) > if (comm == NULL) > return 0; > > - comm->nr_requests[sample->raw[ENGINE]]++; > + comm->nr_requests[READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_ADD, ring)]++; > return 1; > } > > @@ -235,7 +337,7 @@ static int flip_complete(struct gpu_perf *gp, const void *event) > { > const struct sample_event *sample = event; > > - gp->flip_complete[sample->raw[0]]++; > + gp->flip_complete[READ_TP_FIELD_U32(sample, TP_FLIP_COMPLETE, plane)]++; > return 1; > } > > @@ -243,7 +345,7 @@ static int ctx_switch(struct gpu_perf *gp, const void *event) > { > const struct sample_event *sample = event; > > - gp->ctx_switch[sample->raw[ENGINE]]++; > + gp->ctx_switch[READ_TP_FIELD_U32(sample, TP_GEM_RING_SWITCH_CONTEXT, ring)]++; > return 1; > } > > @@ -278,11 +380,11 @@ static int wait_begin(struct gpu_perf *gp, const void *event) > > wait->comm = comm; > wait->comm->active = true; > - wait->context = sample->raw[ENGINE]; > - wait->seqno = sample->raw[CTX_SEQNO]; > + wait->context = READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_BEGIN, ctx); > + wait->seqno = READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_BEGIN, seqno); > wait->time = sample->time; > - wait->next = gp->wait[sample->raw[CTX]]; > - gp->wait[sample->raw[CTX]] = wait; > + wait->next = gp->wait[READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_BEGIN, ring)]; > + gp->wait[READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_BEGIN, ring)] = wait; > > return 0; > } > @@ -292,9 +394,13 @@ static int wait_end(struct gpu_perf *gp, const void *event) > const struct sample_event *sample = event; > struct gpu_perf_time *wait, **prev; > > - for (prev = &gp->wait[sample->raw[ENGINE]]; (wait = *prev) != NULL; prev = &wait->next) { > - if (wait->context != sample->raw[CTX] || > - wait->seqno != sample->raw[CTX_SEQNO]) > + for (prev = &gp->wait[READ_TP_FIELD_U32(sample, TP_GEM_REQUEST_WAIT_END, ring)]; > + (wait = *prev) != NULL; > + prev = &wait->next) { > + if (wait->context != READ_TP_FIELD_U32(sample, > + TP_GEM_REQUEST_WAIT_END, ctx) || > + wait->seqno != READ_TP_FIELD_U32(sample, > + TP_GEM_REQUEST_WAIT_END, seqno)) > continue; > > wait->comm->wait_time += sample->time - wait->time; > @@ -314,12 +420,12 @@ void gpu_perf_init(struct gpu_perf *gp, unsigned flags) > gp->nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); > gp->page_size = getpagesize(); > > - perf_tracepoint_open(gp, "i915", "i915_gem_request_add", request_add); > - if (perf_tracepoint_open(gp, "i915", "i915_gem_request_wait_begin", wait_begin) == 0) > - perf_tracepoint_open(gp, "i915", "i915_gem_request_wait_end", wait_end); > - perf_tracepoint_open(gp, "i915", "i915_flip_complete", flip_complete); > - perf_tracepoint_open(gp, "i915", "i915_gem_ring_sync_to", ring_sync); > - perf_tracepoint_open(gp, "i915", "i915_gem_ring_switch_context", ctx_switch); > + perf_tracepoint_open(gp, TP_GEM_REQUEST_ADD, request_add); > + if (perf_tracepoint_open(gp, TP_GEM_REQUEST_WAIT_BEGIN, wait_begin) == 0) > + perf_tracepoint_open(gp, TP_GEM_REQUEST_WAIT_END, wait_end); > + perf_tracepoint_open(gp, TP_FLIP_COMPLETE, flip_complete); > + perf_tracepoint_open(gp, TP_GEM_RING_SYNC_TO, ring_sync); > + perf_tracepoint_open(gp, TP_GEM_RING_SWITCH_CONTEXT, ctx_switch); > > if (gp->nr_events == 0) { > gp->error = "i915.ko tracepoints not available"; > diff --git a/overlay/meson.build b/overlay/meson.build > index afacff5e..6a5691dc 100644 > --- a/overlay/meson.build > +++ b/overlay/meson.build > @@ -14,6 +14,14 @@ gpu_overlay_src = [ > 'rc6.c', > ] > > +leg = find_program('leg', required : true) > +leg_gen = generator(leg, > + output : '@BASENAME@.h', > + arguments : ['-o', '@OUTPUT@', '@INPUT@']) > +leg_file = leg_gen.process('tracepoint_format.leg') > +leg_lib = static_library('leg', leg_file) > +leg_inc = leg_lib.private_dir_include() > + > xv = dependency('xv', required : false) > x11 = dependency('x11', required : false) > xext = dependency('xext', required : false) > @@ -53,8 +61,9 @@ gpu_overlay_src += 'kms/kms-overlay.c' > > if xrandr.found() and cairo.found() > executable('intel-gpu-overlay', gpu_overlay_src, > - include_directories : inc, > + include_directories : [inc, leg_inc], > c_args : gpu_overlay_cflags, > dependencies : gpu_overlay_deps, > + link_with : leg_lib, > install : true) > endif Making that look a bit less nonsensical and also making peg optional: @@ -14,14 +14,6 @@ gpu_overlay_src = [ 'rc6.c', ] -leg = find_program('leg', required : true) -leg_gen = generator(leg, - output : '@BASENAME@.h', - arguments : ['-o', '@OUTPUT@', '@INPUT@']) -leg_file = leg_gen.process('tracepoint_format.leg') -leg_lib = static_library('leg', leg_file) -leg_inc = leg_lib.private_dir_include() - xv = dependency('xv', required : false) x11 = dependency('x11', required : false) xext = dependency('xext', required : false) @@ -59,11 +51,19 @@ gpu_overlay_src += both_x11_src gpu_overlay_src += 'kms/kms-overlay.c' -if xrandr.found() and cairo.found() - executable('intel-gpu-overlay', gpu_overlay_src, - include_directories : [inc, leg_inc], +leg = find_program('leg', required : false) +if leg.found() + leg_file = custom_target('tracepoint_format', + output: 'tracepoint_format.h', + input: 'tracepoint_format.leg', + command: [leg, '-o', '@OUTPUT@', '@INPUT@']) + gpu_overlay_src += leg_file + + if xrandr.found() and cairo.found() + executable('intel-gpu-overlay', gpu_overlay_src, + include_directories : inc, c_args : gpu_overlay_cflags, dependencies : gpu_overlay_deps, - link_with : leg_lib, install : true) + endif endif -- Petri Latvala > diff --git a/overlay/tracepoint_format.leg b/overlay/tracepoint_format.leg > new file mode 100644 > index 00000000..ea83db91 > --- /dev/null > +++ b/overlay/tracepoint_format.leg > @@ -0,0 +1,34 @@ > +TracepointFormat = > + 'name' ':' Space PropertyName EndLine > + 'ID' ':' Space Number EndLine > + 'format' ':' EndLine > + Field+ > + 'print fmt' ':' .* > + !. > + > +Field = Space (Property ';' Space)+ EndLine > + { yy->ctx.tp->n_fields++; } > + | EndLine > + > +Property = 'offset' ':' v:Number > + { yy->ctx.tp->fields[yy->ctx.tp->n_fields].offset = v.integer; } > + | 'size' ':' v:Number > + { yy->ctx.tp->fields[yy->ctx.tp->n_fields].size = v.integer; } > + | 'signed' ':' v:Number > + { yy->ctx.tp->fields[yy->ctx.tp->n_fields].is_signed = v.integer != 0; } > + | 'field' ':' v:PropertyValue > + { snprintf(yy->ctx.tp->fields[yy->ctx.tp->n_fields].name, > + sizeof(yy->ctx.tp->fields[yy->ctx.tp->n_fields].name), > + "%s", strrchr(v.string, ' ') + 1); free(v.string); } > + | n:PropertyName ':' v:PropertyValue > + { free(n.string); free(v.string); } > + > +PropertyName = < [A-Za-z0-9_]+ > > + { $$.string = strdup(yytext); } > +PropertyValue = < [^;]+ > > + { $$.string = strdup(yytext); } > +Number = < [0-9]+ > > + { $$.integer = atoi(yytext); } > + > +EndLine = [\n] > +Space = [ \t]* > -- > 2.15.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-12-19 10:08 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-12-19 1:06 [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location Lionel Landwerlin 2017-12-19 1:09 ` ✗ Fi.CI.BAT: failure for overlay: parse tracepoints from sysfs to figure out fields' location (rev2) Patchwork 2017-12-19 8:22 ` Patchwork 2017-12-19 8:35 ` Patchwork 2017-12-19 9:34 ` [PATCH i-g-t v2] overlay: parse tracepoints from sysfs to figure out fields' location Chris Wilson 2017-12-19 10:08 ` Petri Latvala
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox