From patchwork Mon Oct 19 10:25:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10092 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 0AD0BBDB13 for ; Mon, 19 Oct 2020 10:25:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7F6A261373; Mon, 19 Oct 2020 12:25:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="GZPrhrWW"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 82B6A60CE6 for ; Mon, 19 Oct 2020 12:25:41 +0200 (CEST) Received: from pyrite.rasen.tech (unknown [IPv6:2400:4051:61:600:2c71:1b79:d06d:5032]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DE40548; Mon, 19 Oct 2020 12:25:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1603103141; bh=sMFOGcg9V4O0CNpf0G26yp8ixJ6okqEZUVAOwNiI4dw=; h=From:To:Cc:Subject:Date:From; b=GZPrhrWWoD0YsSqb2qSE6juHMwpMYf22gwx4HFJQ4VJc0lca0nl8q9t66lpjTkfDh cY68WfZLuPfYQngc4+lfseGHaZTdMwO8OLBsaFguQ/X5mDsSz8y5H8FDUDwasV07Jv 8uk8NvhuxHD8zF5kNA0AZ4gC3ZzN684jmeyDRwF0= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Mon, 19 Oct 2020 19:25:28 +0900 Message-Id: <20201019102529.28359-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 1/2] libcamera: tracing: Implement tracing infrastructure X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Implement tracing infrastructure in libcamera. It takes .tp files, as required by lttng, and generates a tracepoint header and C file, as lttng requires. meson is updated accordingly to get it to compile with the rest of libcamera. Update the documentation accordingly. Signed-off-by: Paul Elder --- Documentation/Doxyfile.in | 2 + README.rst | 3 ++ include/libcamera/internal/meson.build | 9 +++++ .../internal/tracepoints/meson.build | 4 ++ meson.build | 3 ++ meson_options.txt | 5 +++ src/libcamera/meson.build | 7 ++++ src/libcamera/tracepoints.cpp | 10 +++++ utils/meson.build | 1 + utils/tracepoints/generate_header.py | 40 +++++++++++++++++++ utils/tracepoints/header.tmpl | 40 +++++++++++++++++++ utils/tracepoints/meson.build | 5 +++ 12 files changed, 129 insertions(+) create mode 100644 include/libcamera/internal/tracepoints/meson.build create mode 100644 src/libcamera/tracepoints.cpp create mode 100644 utils/tracepoints/generate_header.py create mode 100644 utils/tracepoints/header.tmpl create mode 100644 utils/tracepoints/meson.build diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index 5ccd0d05..9a7a3fb4 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -842,6 +842,8 @@ EXCLUDE = @TOP_SRCDIR@/include/libcamera/span.h \ @TOP_SRCDIR@/src/libcamera/ipa_ipc_unixsocket.cpp \ @TOP_SRCDIR@/src/libcamera/pipeline/ \ @TOP_SRCDIR@/src/libcamera/proxy/ \ + @TOP_SRCDIR@/src/libcamera/tracepoints.cpp \ + @TOP_BUILDDIR@/include/libcamera/internal/tracepoints.h \ @TOP_BUILDDIR@/include/libcamera/ipa/ \ @TOP_BUILDDIR@/src/libcamera/proxy/ diff --git a/README.rst b/README.rst index fc8f4948..039015ac 100644 --- a/README.rst +++ b/README.rst @@ -81,6 +81,9 @@ for gstreamer: [optional] for qcam: [optional] qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5 qttools5-dev-tools libtiff-dev +for tracing with lttng: [optional] + lttng-ust-dev + Using GStreamer plugin ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 8dd744fd..21805edd 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -1,5 +1,14 @@ # SPDX-License-Identifier: CC0-1.0 +subdir('tracepoints') + +libcamera_tracepoint_header = custom_target( + 'tp_header', + input: [ tracepoints_header_template, tracepoint_files ], + output: 'tracepoints.h', + command: [ tracepoints_header_generator, '@OUTPUT@', '@INPUT@' ], +) + libcamera_internal_headers = files([ 'byte_stream_buffer.h', 'camera_controls.h', diff --git a/include/libcamera/internal/tracepoints/meson.build b/include/libcamera/internal/tracepoints/meson.build new file mode 100644 index 00000000..2dd6733e --- /dev/null +++ b/include/libcamera/internal/tracepoints/meson.build @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: CC0-1.0 + +tracepoint_files = files([ +]) diff --git a/meson.build b/meson.build index de15cc16..b6a8c2d2 100644 --- a/meson.build +++ b/meson.build @@ -103,6 +103,9 @@ libcamera_includes = include_directories('include') # Sub-directories fill py_modules with their dependencies. py_modules = [] +# We need to check in include/ if we need to generate the tracepoint header +liblttng = cc.find_library('lttng-ust', required : get_option('tracepoints')) + # Utilities are parsed first to provide support for other components. subdir('utils') diff --git a/meson_options.txt b/meson_options.txt index 7f7b3e59..9e768beb 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -28,6 +28,11 @@ option('test', type : 'boolean', description: 'Compile and include the tests') +option('tracepoints', + type : 'feature', + value : 'auto', + description: 'Compile libcamera with lttng tracepoints') + option('v4l2', type : 'boolean', value : false, diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 42340eae..7dc77c67 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -58,6 +58,7 @@ libcamera_sources = files([ libcamera_sources += libcamera_public_headers libcamera_sources += libcamera_generated_headers +libcamera_sources += libcamera_tracepoint_header includes = [ libcamera_includes, @@ -75,6 +76,11 @@ if libgnutls.found() config_h.set('HAVE_GNUTLS', 1) endif +if liblttng.found() + config_h.set('TRACING_ENABLED', 1) + libcamera_sources += files(['tracepoints.cpp']) +endif + if libudev.found() config_h.set('HAVE_LIBUDEV', 1) libcamera_sources += files([ @@ -117,6 +123,7 @@ libcamera_deps = [ libatomic, libdl, libgnutls, + liblttng, libudev, dependency('threads'), ] diff --git a/src/libcamera/tracepoints.cpp b/src/libcamera/tracepoints.cpp new file mode 100644 index 00000000..0173b75a --- /dev/null +++ b/src/libcamera/tracepoints.cpp @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * tracepoints.cpp - Tracepoints with lttng + */ +#define TRACEPOINT_CREATE_PROBES +#define TRACEPOINT_DEFINE + +#include "libcamera/internal/tracepoints.h" diff --git a/utils/meson.build b/utils/meson.build index 383d5285..8e28ada7 100644 --- a/utils/meson.build +++ b/utils/meson.build @@ -2,6 +2,7 @@ subdir('ipc') subdir('ipu3') +subdir('tracepoints') ## Code generation py_modules += ['yaml'] diff --git a/utils/tracepoints/generate_header.py b/utils/tracepoints/generate_header.py new file mode 100644 index 00000000..52268eba --- /dev/null +++ b/utils/tracepoints/generate_header.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020, Google Inc. +# +# Author: Paul Elder +# +# generate_header.py - Generate header file to contain lttng tracepoints + +import datetime +import jinja2 +import os +import sys + +def main(argv): + if len(argv) < 3: + print(f'Usage: {argv[0]} output template tp_files...') + return 1 + + output = argv[1] + template = argv[2] + + year = datetime.datetime.now().year + path = output.replace('include/', '', 1) + + source = '' + for fname in argv[3:]: + source += open(fname, 'r').read() + '\n\n' + + template = jinja2.Template(open(template, 'r').read()) + string = template.render(year=year, path=path, source=source) + + f = open(output, 'w') + f.write(string) + f.close() + + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/utils/tracepoints/header.tmpl b/utils/tracepoints/header.tmpl new file mode 100644 index 00000000..b1595656 --- /dev/null +++ b/utils/tracepoints/header.tmpl @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) {{year}}, Google Inc. + * + * tracepoints.h - Tracepoints with lttng + * + * This file is auto-generated. Do not edit. + */ +#ifndef __LIBCAMERA_INTERNAL_TRACEPOINTS_H__ +#define __LIBCAMERA_INTERNAL_TRACEPOINTS_H__ + +#if TRACING_ENABLED +#define LIBCAMERA_TRACEPOINT(...) tracepoint(libcamera, __VA_ARGS__) +#else +#define LIBCAMERA_TRACEPOINT(...) do {} while (0) +#endif + +#endif /* __LIBCAMERA_INTERNAL_TRACEPOINTS_H__ */ + + +#if TRACING_ENABLED + +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER libcamera + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "{{path}}" + +#if !defined(INCLUDE_LIBCAMERA_INTERNAL_TRACEPOINTS_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ) +#define INCLUDE_LIBCAMERA_INTERNAL_TRACEPOINTS_TP_H + +#include + +{{source}} + +#endif /* INCLUDE_LIBCAMERA_INTERNAL_TRACEPOINTS_TP_H */ + +#include + +#endif /* TRACING_ENABLED */ diff --git a/utils/tracepoints/meson.build b/utils/tracepoints/meson.build new file mode 100644 index 00000000..7294287b --- /dev/null +++ b/utils/tracepoints/meson.build @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: CC0-1.0 + +tracepoints_header_template = files(['header.tmpl']) + +tracepoints_header_generator = find_program('./generate_header.py') From patchwork Mon Oct 19 10:25:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10093 X-Patchwork-Delegate: paul.elder@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 15C74BDB13 for ; Mon, 19 Oct 2020 10:25:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D5B20613B9; Mon, 19 Oct 2020 12:25:44 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="iTewMI+E"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7128760CE6 for ; Mon, 19 Oct 2020 12:25:43 +0200 (CEST) Received: from pyrite.rasen.tech (unknown [IPv6:2400:4051:61:600:2c71:1b79:d06d:5032]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E441048; Mon, 19 Oct 2020 12:25:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1603103143; bh=rRoJhzJzGSfugpMegRHU33P6BAY2YBiH7+QcK13EVMg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iTewMI+E7I2XAIrxHEVBvK4dVC6G46taQKum72bck4lq2N1/Ti6EEQtQzs11D23HC 4ds9a+T1Euu3A1996jc2G97c3YHB4e2Hrz4bRqtBGMm/UzO/oVqorGlOL8Xc+KLDR1 PqJx0Xhj/JLoxzZroSgTCBw0OzuVNrA3UB4ucZTg= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Mon, 19 Oct 2020 19:25:29 +0900 Message-Id: <20201019102529.28359-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201019102529.28359-1-paul.elder@ideasonboard.com> References: <20201019102529.28359-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 2/2] [DO NOT MERGE] libcamera: uvcvideo, request: Add tracepoints X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add and use tracepoints in the uvcvideo pipeline handler and Request. This is only meant to show how one would create and use tracepoints. Signed-off-by: Paul Elder --- Setting log level is also available. I haven't tested it yet, but in theory is should Just Work (TM). It looks like you can set log levels on the event definitions, and not when you emit the events. --- .../internal/tracepoints/meson.build | 2 + .../libcamera/internal/tracepoints/request.tp | 91 +++++++++++++++++++ .../internal/tracepoints/uvcvideo.tp | 13 +++ src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 3 + src/libcamera/request.cpp | 16 ++++ 5 files changed, 125 insertions(+) create mode 100644 include/libcamera/internal/tracepoints/request.tp create mode 100644 include/libcamera/internal/tracepoints/uvcvideo.tp diff --git a/include/libcamera/internal/tracepoints/meson.build b/include/libcamera/internal/tracepoints/meson.build index 2dd6733e..3ec53fbc 100644 --- a/include/libcamera/internal/tracepoints/meson.build +++ b/include/libcamera/internal/tracepoints/meson.build @@ -1,4 +1,6 @@ # SPDX-License-Identifier: CC0-1.0 tracepoint_files = files([ + 'request.tp', + 'uvcvideo.tp', ]) diff --git a/include/libcamera/internal/tracepoints/request.tp b/include/libcamera/internal/tracepoints/request.tp new file mode 100644 index 00000000..c64bbd43 --- /dev/null +++ b/include/libcamera/internal/tracepoints/request.tp @@ -0,0 +1,91 @@ +TRACEPOINT_EVENT_CLASS( + libcamera, + request, + TP_ARGS( + uint64_t, cookie, + int, status, + int, cancelled + ), + TP_FIELDS( + ctf_integer(uint64_t, cookie, cookie) + ctf_integer(int, status, status) + ctf_integer(int, cancelled, cancelled) + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_construct, + TP_ARGS( + uint64_t, cookie, + int, status, + int, cancelled + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_deconstruct, + TP_ARGS( + uint64_t, cookie, + int, status, + int, cancelled + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_reuse, + TP_ARGS( + uint64_t, cookie, + int, status, + int, cancelled + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_add_buffer, + TP_ARGS( + uint64_t, cookie, + int, status, + int, cancelled + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_find_buffer, + TP_ARGS( + uint64_t, cookie, + int, status, + int, cancelle + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_complete, + TP_ARGS( + uint64_t, cookie, + int, status, + int, cancelled + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_complete_buffer, + TP_ARGS( + uint64_t, cookie, + int, status, + int, cancelled + ) +) diff --git a/include/libcamera/internal/tracepoints/uvcvideo.tp b/include/libcamera/internal/tracepoints/uvcvideo.tp new file mode 100644 index 00000000..61592ce5 --- /dev/null +++ b/include/libcamera/internal/tracepoints/uvcvideo.tp @@ -0,0 +1,13 @@ +TRACEPOINT_EVENT_CLASS( + libcamera, + uvcvideo, + TP_ARGS(), + TP_FIELDS() +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + uvcvideo, + uvcvideo_contruct, + TP_ARGS() +) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 8ec0dac1..bc01a78c 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -27,6 +27,8 @@ #include "libcamera/internal/v4l2_controls.h" #include "libcamera/internal/v4l2_videodevice.h" +#include "libcamera/internal/tracepoints.h" + namespace libcamera { LOG_DEFINE_CATEGORY(UVC) @@ -171,6 +173,7 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager) : PipelineHandler(manager) { + LIBCAMERA_TRACEPOINT(uvcvideo_contruct); } CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera, diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index ae8b1660..74c1a7b0 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -17,6 +17,8 @@ #include "libcamera/internal/camera_controls.h" #include "libcamera/internal/log.h" +#include "libcamera/internal/tracepoints.h" + /** * \file request.h * \brief Describes a frame capture request to be processed by a camera @@ -85,10 +87,14 @@ Request::Request(Camera *camera, uint64_t cookie) * \todo: Add a validator for metadata controls. */ metadata_ = new ControlList(controls::controls); + + LIBCAMERA_TRACEPOINT(request_construct, cookie_, status_, cancelled_); } Request::~Request() { + LIBCAMERA_TRACEPOINT(request_deconstruct, cookie_, status_, cancelled_); + delete metadata_; delete controls_; delete validator_; @@ -106,6 +112,8 @@ Request::~Request() */ void Request::reuse(ReuseFlag flags) { + LIBCAMERA_TRACEPOINT(request_reuse, cookie_, status_, cancelled_); + pending_.clear(); if (flags & ReuseBuffers) { for (auto pair : bufferMap_) { @@ -167,6 +175,8 @@ void Request::reuse(ReuseFlag flags) */ int Request::addBuffer(const Stream *stream, FrameBuffer *buffer) { + LIBCAMERA_TRACEPOINT(request_add_buffer, cookie_, status_, cancelled_); + if (!stream) { LOG(Request, Error) << "Invalid stream reference"; return -EINVAL; @@ -202,6 +212,8 @@ int Request::addBuffer(const Stream *stream, FrameBuffer *buffer) */ FrameBuffer *Request::findBuffer(const Stream *stream) const { + LIBCAMERA_TRACEPOINT(request_find_buffer, cookie_, status_, cancelled_); + const auto it = bufferMap_.find(stream); if (it == bufferMap_.end()) return nullptr; @@ -253,6 +265,8 @@ FrameBuffer *Request::findBuffer(const Stream *stream) const */ void Request::complete() { + LIBCAMERA_TRACEPOINT(request_complete, cookie_, status_, cancelled_); + ASSERT(!hasPendingBuffers()); status_ = cancelled_ ? RequestCancelled : RequestComplete; @@ -276,6 +290,8 @@ void Request::complete() */ bool Request::completeBuffer(FrameBuffer *buffer) { + LIBCAMERA_TRACEPOINT(request_complete_buffer, cookie_, status_, cancelled_); + int ret = pending_.erase(buffer); ASSERT(ret == 1);