summaryrefslogtreecommitdiff
path: root/mali_kbase/mali_kbase_kinstr_jm.h
diff options
context:
space:
mode:
authorSidath Senanayake <sidaths@google.com>2020-09-11 16:44:12 +0100
committerSidath Senanayake <sidaths@google.com>2020-09-11 16:44:12 +0100
commitd4ca6eb7268ee2db9deabd1745b505c6e1c162f9 (patch)
tree64058c324e9e6adb30e8689d17f0a2e2b27636bc /mali_kbase/mali_kbase_kinstr_jm.h
parentbc3c01e61c8ce9783a8ab091053905effcae12de (diff)
downloadgpu-d4ca6eb7268ee2db9deabd1745b505c6e1c162f9.tar.gz
Mali Valhall DDK r26p0 KMD
Provenance: 009a7d86a (collaborate/EAC/v_r26p0) VX504X08X-BU-00000-r26p0-01eac0 - Android DDK VX504X08X-BU-60000-r26p0-01eac0 - Android Document Bundle Signed-off-by: Sidath Senanayake <sidaths@google.com> Change-Id: Ic3671bdc454b706b6f98a9d1a615d1886da0c3e8
Diffstat (limited to 'mali_kbase/mali_kbase_kinstr_jm.h')
-rw-r--r--mali_kbase/mali_kbase_kinstr_jm.h283
1 files changed, 283 insertions, 0 deletions
diff --git a/mali_kbase/mali_kbase_kinstr_jm.h b/mali_kbase/mali_kbase_kinstr_jm.h
new file mode 100644
index 0000000..555edfe
--- /dev/null
+++ b/mali_kbase/mali_kbase_kinstr_jm.h
@@ -0,0 +1,283 @@
+/*
+ *
+ * (C) COPYRIGHT 2019,2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/*
+ * mali_kbase_kinstr_jm.h
+ * Kernel driver public interface to job manager atom tracing. This API provides
+ * a method to get the atom state changes into user space.
+ *
+ * The flow of operation is:
+ *
+ * | kernel | user |
+ * | ----------------------------------- | ----------------------------------- |
+ * | Initialize API with | |
+ * | kbase_kinstr_jm_init() | |
+ * | | |
+ * | Kernel code injects states with | |
+ * | kbase_kinstr_jm_atom_state_*() APIs | |
+ * | | Call ioctl() to get file descriptor |
+ * | | via KBASE_IOCTL_KINSTR_JM_FD |
+ * | Allocates a reader attached to FD | |
+ * | Allocates circular buffer and | |
+ * | patches, via ASM goto, the | |
+ * | kbase_kinstr_jm_atom_state_*() | |
+ * | | loop: |
+ * | | Call poll() on FD for POLLIN |
+ * | When threshold of changes is hit, | |
+ * | the poll is interrupted with | |
+ * | POLLIN. If circular buffer is | |
+ * | full then store the missed count | |
+ * | and interrupt poll | Call read() to get data from |
+ * | | circular buffer via the fd |
+ * | Kernel advances tail of circular | |
+ * | buffer | |
+ * | | Close file descriptor |
+ * | Deallocates circular buffer | |
+ * | | |
+ * | Terminate API with | |
+ * | kbase_kinstr_jm_term() | |
+ *
+ * All tracepoints are guarded on a static key. The static key is activated when
+ * a user space reader gets created. This means that there is negligible cost
+ * inserting the tracepoints into code when there are no readers.
+ */
+
+#ifndef _KBASE_KINSTR_JM_H_
+#define _KBASE_KINSTR_JM_H_
+
+#include "mali_kbase_kinstr_jm_reader.h"
+
+#ifdef __KERNEL__
+#include <linux/version.h>
+#include <linux/static_key.h>
+#else
+/* empty wrapper macros for userspace */
+#define static_branch_unlikely(key) (1)
+#define KERNEL_VERSION(a, b, c) (0)
+#define LINUX_VERSION_CODE (1)
+#endif /* __KERNEL__ */
+
+/* Forward declarations */
+struct kbase_context;
+struct kbase_kinstr_jm;
+struct kbase_jd_atom;
+union kbase_kinstr_jm_fd;
+
+/**
+ * kbase_kinstr_jm_init() - Initialise an instrumentation job manager context.
+ * @ctx: Non-NULL pointer to where the pointer to the created context will
+ * be stored on success.
+ *
+ * Return: 0 on success, else error code.
+ */
+int kbase_kinstr_jm_init(struct kbase_kinstr_jm **ctx);
+
+/**
+ * kbase_kinstr_jm_term() - Terminate an instrumentation job manager context.
+ * @ctx: Pointer to context to be terminated.
+ */
+void kbase_kinstr_jm_term(struct kbase_kinstr_jm *ctx);
+
+/**
+ * kbase_kinstr_jm_get_fd() - Retrieves a file descriptor that can be used to
+ * read the atom state changes from userspace
+ *
+ * @ctx: Pointer to the initialized context
+ * @jm_fd_arg: Pointer to the union containing the in/out params
+ * Return: -1 on failure, valid file descriptor on success
+ */
+int kbase_kinstr_jm_get_fd(struct kbase_kinstr_jm *const ctx,
+ union kbase_kinstr_jm_fd *jm_fd_arg);
+
+/**
+ * kbasep_kinstr_jm_atom_state() - Signifies that an atom has changed state
+ * @atom: The atom that has changed state
+ * @state: The new state of the atom
+ *
+ * This performs the actual storage of the state ready for user space to
+ * read the data. It is only called when the static key is enabled from
+ * kbase_kinstr_jm_atom_state(). There is almost never a need to invoke this
+ * function directly.
+ */
+void kbasep_kinstr_jm_atom_state(
+ struct kbase_jd_atom *const atom,
+ const enum kbase_kinstr_jm_reader_atom_state state);
+
+/* Allows ASM goto patching to reduce tracing overhead. This is
+ * incremented/decremented when readers are created and terminated. This really
+ * shouldn't be changed externally, but if you do, make sure you use
+ * a static_key_inc()/static_key_dec() pair.
+ */
+#if KERNEL_VERSION(4, 3, 0) <= LINUX_VERSION_CODE
+extern struct static_key_false basep_kinstr_jm_reader_static_key;
+#else
+/* Pre-4.3 kernels have a different API for static keys, but work
+ * mostly the same with less type safety. */
+extern struct static_key basep_kinstr_jm_reader_static_key;
+#define static_branch_unlikely(key) static_key_false(key)
+#endif /* KERNEL_VERSION(4, 3, 0) <= LINUX_VERSION_CODE */
+
+/**
+ * kbase_kinstr_jm_atom_state() - Signifies that an atom has changed state
+ * @atom: The atom that has changed state
+ * @state: The new state of the atom
+ *
+ * This uses a static key to reduce overhead when tracing is disabled
+ */
+static inline void kbase_kinstr_jm_atom_state(
+ struct kbase_jd_atom *const atom,
+ const enum kbase_kinstr_jm_reader_atom_state state)
+{
+ if (static_branch_unlikely(&basep_kinstr_jm_reader_static_key))
+ kbasep_kinstr_jm_atom_state(atom, state);
+}
+
+/**
+ * kbase_kinstr_jm_atom_state_queue() - Signifies that an atom has entered a
+ * hardware or software queue.
+ * @atom: The atom that has changed state
+ */
+static inline void kbase_kinstr_jm_atom_state_queue(
+ struct kbase_jd_atom *const atom)
+{
+ kbase_kinstr_jm_atom_state(
+ atom, KBASE_KINSTR_JM_READER_ATOM_STATE_QUEUE);
+}
+
+/**
+ * kbase_kinstr_jm_atom_state_start() - Signifies that work has started on an
+ * atom
+ * @atom: The atom that has changed state
+ */
+static inline void kbase_kinstr_jm_atom_state_start(
+ struct kbase_jd_atom *const atom)
+{
+ kbase_kinstr_jm_atom_state(
+ atom, KBASE_KINSTR_JM_READER_ATOM_STATE_START);
+}
+
+/**
+ * kbase_kinstr_jm_atom_state_stop() - Signifies that work has stopped on an
+ * atom
+ * @atom: The atom that has changed state
+ */
+static inline void kbase_kinstr_jm_atom_state_stop(
+ struct kbase_jd_atom *const atom)
+{
+ kbase_kinstr_jm_atom_state(
+ atom, KBASE_KINSTR_JM_READER_ATOM_STATE_STOP);
+}
+
+/**
+ * kbase_kinstr_jm_atom_state_complete() - Signifies that all work has completed
+ * on an atom
+ * @atom: The atom that has changed state
+ */
+static inline void kbase_kinstr_jm_atom_state_complete(
+ struct kbase_jd_atom *const atom)
+{
+ kbase_kinstr_jm_atom_state(
+ atom, KBASE_KINSTR_JM_READER_ATOM_STATE_COMPLETE);
+}
+
+/**
+ * kbase_kinstr_jm_atom_queue() - A software *or* hardware atom is queued for
+ * execution
+ * @atom: The atom that has changed state
+ */
+static inline void kbase_kinstr_jm_atom_queue(struct kbase_jd_atom *const atom)
+{
+ kbase_kinstr_jm_atom_state_queue(atom);
+}
+
+/**
+ * kbase_kinstr_jm_atom_complete() - A software *or* hardware atom is fully
+ * completed
+ * @atom: The atom that has changed state
+ */
+static inline void kbase_kinstr_jm_atom_complete(
+ struct kbase_jd_atom *const atom)
+{
+ kbase_kinstr_jm_atom_state_complete(atom);
+}
+
+/**
+ * kbase_kinstr_jm_atom_sw_start() - A software atom has started work
+ * @atom: The atom that has changed state
+ */
+static inline void kbase_kinstr_jm_atom_sw_start(
+ struct kbase_jd_atom *const atom)
+{
+ kbase_kinstr_jm_atom_state_start(atom);
+}
+
+/**
+ * kbase_kinstr_jm_atom_sw_stop() - A software atom has stopped work
+ * @atom: The atom that has changed state
+ */
+static inline void kbase_kinstr_jm_atom_sw_stop(
+ struct kbase_jd_atom *const atom)
+{
+ kbase_kinstr_jm_atom_state_stop(atom);
+}
+
+/**
+ * kbasep_kinstr_jm_atom_hw_submit() - A hardware atom has been submitted
+ * @atom: The atom that has been submitted
+ *
+ * This private implementation should not be called directly, it is protected
+ * by a static key in kbase_kinstr_jm_atom_hw_submit(). Use that instead.
+ */
+void kbasep_kinstr_jm_atom_hw_submit(struct kbase_jd_atom *const atom);
+
+/**
+ * kbase_kinstr_jm_atom_hw_submit() - A hardware atom has been submitted
+ * @atom: The atom that has been submitted
+ */
+static inline void kbase_kinstr_jm_atom_hw_submit(
+ struct kbase_jd_atom *const atom)
+{
+ if (static_branch_unlikely(&basep_kinstr_jm_reader_static_key))
+ kbasep_kinstr_jm_atom_hw_submit(atom);
+}
+
+/**
+ * kbasep_kinstr_jm_atom_hw_release() - A hardware atom has been released
+ * @atom: The atom that has been released
+ *
+ * This private implementation should not be called directly, it is protected
+ * by a static key in kbase_kinstr_jm_atom_hw_release(). Use that instead.
+ */
+void kbasep_kinstr_jm_atom_hw_release(struct kbase_jd_atom *const atom);
+
+/**
+ * kbase_kinstr_jm_atom_hw_release() - A hardware atom has been released
+ * @atom: The atom that has been released
+ */
+static inline void kbase_kinstr_jm_atom_hw_release(
+ struct kbase_jd_atom *const atom)
+{
+ if (static_branch_unlikely(&basep_kinstr_jm_reader_static_key))
+ kbasep_kinstr_jm_atom_hw_release(atom);
+}
+
+#endif /* _KBASE_KINSTR_JM_H_ */