diff --git a/alloc.c b/alloc.c index c87e520..b5a58c2 100644 --- a/alloc.c +++ b/alloc.c @@ -7,6 +7,7 @@ #include #include "log.h" #include "private.h" +#include "trace.h" /* Plane allocation algorithm * @@ -674,6 +675,10 @@ liftoff_output_apply(struct liftoff_output *output, drmModeAtomicReq *req, update_layers_priority(device); + liftoff_tracer_mark(&device->tracer, + "output_apply (begin_ctx=%d)", + device->page_flip_counter); + ret = reuse_previous_alloc(output, req, flags); if (ret == 0) { log_reuse(output); @@ -776,5 +781,9 @@ liftoff_output_apply(struct liftoff_output *output, drmModeAtomicReq *req, mark_layers_clean(output); + liftoff_tracer_mark(&device->tracer, + "output_apply (end_ctx=%d)", + device->page_flip_counter); + return 0; } diff --git a/device.c b/device.c index 6d6e21a..3aa43cd 100644 --- a/device.c +++ b/device.c @@ -20,6 +20,8 @@ liftoff_device_create(int drm_fd) liftoff_list_init(&device->planes); liftoff_list_init(&device->outputs); + liftoff_tracer_init(&device->tracer); + device->drm_fd = dup(drm_fd); if (device->drm_fd < 0) { liftoff_log_errno(LIFTOFF_ERROR, "dup"); @@ -59,6 +61,7 @@ liftoff_device_destroy(struct liftoff_device *device) return; } + liftoff_tracer_finish(&device->tracer); close(device->drm_fd); liftoff_list_for_each_safe(plane, tmp, &device->planes, link) { liftoff_plane_destroy(plane); @@ -97,6 +100,10 @@ device_test_commit(struct liftoff_device *device, drmModeAtomicReq *req, device->test_commit_counter++; + liftoff_tracer_mark(&device->tracer, + "device_test_commit (begin_ctx=%d)", + device->test_commit_counter); + flags &= ~DRM_MODE_PAGE_FLIP_EVENT; do { ret = drmModeAtomicCommit(device->drm_fd, req, @@ -104,6 +111,10 @@ device_test_commit(struct liftoff_device *device, drmModeAtomicReq *req, NULL); } while (ret == -EINTR || ret == -EAGAIN); + liftoff_tracer_mark(&device->tracer, + "device_test_commit (end_ctx=%d)", + device->test_commit_counter); + /* The kernel will return -EINVAL for invalid configuration, -ERANGE for * CRTC coords overflow, and -ENOSPC for invalid SRC coords. */ if (ret != 0 && ret != -EINVAL && ret != -ERANGE && ret != -ENOSPC) { diff --git a/include/private.h b/include/private.h index 4b237d0..3889e57 100644 --- a/include/private.h +++ b/include/private.h @@ -4,6 +4,7 @@ #include #include "list.h" #include "log.h" +#include "trace.h" /* Layer priority is assigned depending on the number of updates during a * given number of page-flips */ @@ -18,6 +19,7 @@ struct liftoff_device { uint32_t *crtcs; size_t crtcs_len; + struct liftoff_tracer tracer; int page_flip_counter; int test_commit_counter; }; diff --git a/include/trace.h b/include/trace.h new file mode 100644 index 0000000..9821986 --- /dev/null +++ b/include/trace.h @@ -0,0 +1,21 @@ +#ifndef TRACE_H +#define TRACE_H + +#include +#include "log.h" + +struct liftoff_tracer { + FILE *f; +}; + +int +liftoff_tracer_init(struct liftoff_tracer *tracer); + +void +liftoff_tracer_finish(struct liftoff_tracer *tracer); + +void +liftoff_tracer_mark(struct liftoff_tracer *tracer, const char *format, ...) +_LIFTOFF_ATTRIB_PRINTF(2, 3); + +#endif diff --git a/meson.build b/meson.build index db08ab6..014f926 100644 --- a/meson.build +++ b/meson.build @@ -38,6 +38,7 @@ liftoff_lib = library( 'log.c', 'output.c', 'plane.c', + 'trace.c', ), include_directories: liftoff_inc, version: meson.project_version(), diff --git a/trace.c b/trace.c new file mode 100644 index 0000000..4e690b0 --- /dev/null +++ b/trace.c @@ -0,0 +1,39 @@ +#include +#include "trace.h" + +int +liftoff_tracer_init(struct liftoff_tracer *tracer) +{ + tracer->f = fopen("/sys/kernel/tracing/trace_marker", "w"); + if (tracer->f == NULL) { + return -errno; + } + liftoff_log(LIFTOFF_DEBUG, "Kernel tracing is enabled"); + return 0; +} + +void +liftoff_tracer_finish(struct liftoff_tracer *tracer) +{ + if (tracer->f != NULL) { + fclose(tracer->f); + } +} + +void +liftoff_tracer_mark(struct liftoff_tracer *tracer, const char *format, ...) +{ + if (tracer->f == NULL) { + return; + } + + fprintf(tracer->f, "libliftoff: "); + + va_list args; + va_start(args, format); + vfprintf(tracer->f, format, args); + va_end(args); + + fprintf(tracer->f, "\n"); + fflush(tracer->f); +}