[PATCH 02/11] drm/xe/oa: Add OA types

Ashutosh Dixit ashutosh.dixit at intel.com
Fri Jul 21 00:06:24 UTC 2023


Add types and data structs used by OA. The data structs maintain device and
gt level information, information about the open OA stream and OA buffer
used internally to capture OA counters written by HW as well as capture
configurations which can be selected for an OA stream.

Signed-off-by: Ashutosh Dixit <ashutosh.dixit at intel.com>
---
 drivers/gpu/drm/xe/xe_oa_types.h | 292 +++++++++++++++++++++++++++++++
 1 file changed, 292 insertions(+)
 create mode 100644 drivers/gpu/drm/xe/xe_oa_types.h

diff --git a/drivers/gpu/drm/xe/xe_oa_types.h b/drivers/gpu/drm/xe/xe_oa_types.h
new file mode 100644
index 0000000000000..07a4f8dab9801
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_oa_types.h
@@ -0,0 +1,292 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _XE_OA_TYPES_H_
+#define _XE_OA_TYPES_H__
+
+#include <linux/poll.h>
+#include <drm/xe_drm.h>
+#include "regs/xe_reg_defs.h"
+
+struct drm_device;
+struct drm_file;
+
+enum {
+	OA_GROUP_OAG = 0,
+	OA_GROUP_OAM_SAMEDIA_0 = 0,
+
+	OA_GROUP_MAX,
+	OA_GROUP_INVALID = U32_MAX,
+};
+
+enum oa_type {
+	TYPE_OAG,
+	TYPE_OAM,
+};
+
+enum report_header {
+	HDR_32_BIT = 0,
+	HDR_64_BIT,
+};
+
+struct xe_oa_format {
+	u32 format;
+	int size;
+	int type;
+	enum report_header header;
+};
+
+struct xe_oa_reg {
+	struct xe_reg addr;
+	u32 value;
+};
+
+struct xe_oa_config {
+	struct xe_oa *oa;
+
+	char uuid[UUID_STRING_LEN + 1];
+	int id;
+
+	const struct xe_oa_reg *mux_regs;
+	u32 mux_regs_len;
+	const struct xe_oa_reg *b_counter_regs;
+	u32 b_counter_regs_len;
+	const struct xe_oa_reg *flex_regs;
+	u32 flex_regs_len;
+
+	struct attribute_group sysfs_metric;
+	struct attribute *attrs[2];
+	struct kobj_attribute sysfs_metric_id;
+
+	struct kref ref;
+	struct rcu_head rcu;
+};
+
+struct xe_oa_regs {
+	u32 base;
+	struct xe_reg oa_head_ptr;
+	struct xe_reg oa_tail_ptr;
+	struct xe_reg oa_buffer;
+	struct xe_reg oa_ctx_ctrl;
+	struct xe_reg oa_ctrl;
+	struct xe_reg oa_debug;
+	struct xe_reg oa_status;
+	u32 oa_ctrl_counter_format_shift;
+};
+
+/**
+ * struct xe_oa_group - OA group representing one hardware OA unit
+ */
+struct xe_oa_group {
+	/** @oa_unit_id: identifier for the OA unit */
+	u32 oa_unit_id;
+
+	/**
+	 * @exclusive_stream: The stream currently using the OA unit. This is
+	 * sometimes accessed outside a syscall associated to its file
+	 * descriptor.
+	 */
+	struct xe_oa_stream *exclusive_stream;
+
+	/** @num_engines: number of engines using this OA unit */
+	u32 num_engines;
+
+	/** @regs: OA buffer register group for programming the OA unit */
+	struct xe_oa_regs regs;
+
+	/** @type: Type of OA unit - OAM, OAG etc. */
+	enum oa_type type;
+};
+
+/**
+ * struct xe_oa_gt - OA per-gt information
+ */
+struct xe_oa_gt {
+	/** @lock: lock associated with anything below within this structure */
+	struct mutex lock;
+
+	/** @num_oa_groups: number of oa groups per gt */
+	u32 num_oa_groups;
+
+	/** @group: list of OA groups - one for each OA buffer */
+	struct xe_oa_group *group;
+};
+
+/**
+ * struct xe_oa - OA device level information
+ */
+struct xe_oa {
+	/** @xe: back pointer to xe device */
+	struct xe_device *xe;
+
+	/** @metrics_kobj: kobj for metrics sysfs */
+	struct kobject *metrics_kobj;
+
+	/**
+	 * @metrics_lock: lock associated with adding/modifying/removing OA
+	 * configs in oa->metrics_idr.
+	 */
+	struct mutex metrics_lock;
+
+	/**
+	 * @metrics_idr: List of dynamic configurations (struct xe_oa_config)
+	 */
+	struct idr metrics_idr;
+
+	/** @ctx_oactxctrl_offset: offset of OACTXCONTROL register in context image */
+	u32 ctx_oactxctrl_offset;
+
+	/** @oa_formats: tracks all OA formats across platforms */
+	const struct xe_oa_format *oa_formats;
+
+#define FORMAT_MASK_SIZE DIV_ROUND_UP(XE_OA_FORMAT_MAX - 1, BITS_PER_LONG)
+
+	/** @format_mask: tracks valid OA formats for a platform */
+	unsigned long format_mask[FORMAT_MASK_SIZE];
+
+	/** @oa_unit_ids: tracks oa unit ids assigned across gt's */
+	u32 oa_unit_ids;
+};
+
+/**
+ * struct xe_oa_stream - state for a single open stream FD
+ */
+struct xe_oa_stream {
+	/** @oa: xe_oa backpointer */
+	struct xe_oa *oa;
+
+	/** @gt: gt associated with the oa stream */
+	struct xe_gt *gt;
+
+	/**
+	 * @hwe: hardware engine associated with this performance stream.
+	 */
+	struct xe_hw_engine *hwe;
+
+	/** @lock: Lock associated with operations on stream */
+	struct mutex lock;
+
+	/**
+	 * @sample: true when DRM_XE_OA_PROP_SAMPLE_OA is given when
+	 * opening a stream, representing the contents of a single sample
+	 * as read() by userspace.
+	 */
+	bool sample;
+
+	/**
+	 * @sample_size: Considering the configured contents of a sample
+	 * combined with the required header size, this is the total size
+	 * of a single sample record.
+	 */
+	int sample_size;
+
+	/**
+	 * @engine: %NULL if measuring system-wide across all engines or a
+	 * specific engine that is being monitored.
+	 */
+	struct xe_engine *engine;
+
+	/**
+	 * @enabled: Whether the stream is currently enabled, considering
+	 * whether the stream was opened in a disabled state and based
+	 * on `XE_OA_IOCTL_ENABLE` and `XE_OA_IOCTL_DISABLE` calls.
+	 */
+	bool enabled;
+
+	/** @oa_config: The OA configuration used by the stream */
+	struct xe_oa_config *oa_config;
+
+	/**
+	 * @oa_config_bos: A list of struct i915_oa_config_bo allocated lazily
+	 * each time @oa_config changes.
+	 */
+	struct llist_head oa_config_bos;
+
+	/** @specific_ctx_id: id of the context used for filtering reports */
+	u32 specific_ctx_id;
+
+	/** @specific_ctx_id_mask: The mask used to masking specific_ctx_id bits */
+	u32 specific_ctx_id_mask;
+
+	/**
+	 * @poll_check_timer: High resolution timer that will periodically
+	 * check for data in the circular OA buffer for notifying userspace
+	 * (e.g. during a read() or poll()).
+	 */
+	struct hrtimer poll_check_timer;
+
+	/**
+	 * @poll_wq: The wait queue that hrtimer callback wakes when it
+	 * sees data ready to read in the circular OA buffer.
+	 */
+	wait_queue_head_t poll_wq;
+
+	/** @pollin: Whether there is data available to read */
+	bool pollin;
+
+	/** @periodic: Whether periodic sampling is currently enabled */
+	bool periodic;
+
+	/** @period_exponent: The OA unit sampling frequency is derived from this */
+	int period_exponent;
+
+	/** @oa_buffer: State of the OA buffer */
+	struct {
+		/** @format: data format */
+		const struct xe_oa_format *format;
+
+		/** @format: xe_bo backing the OA buffer */
+		struct xe_bo *bo;
+
+		/** @vaddr: mapped vaddr of the OA buffer */
+		u8 *vaddr;
+
+		/** @last_ctx_id: last context id for OA data added */
+		u32 last_ctx_id;
+
+		/**
+		 * @ptr_lock: Locks reads and writes to all head/tail state
+		 *
+		 * Consider: the head and tail pointer state needs to be read
+		 * consistently from a hrtimer callback (atomic context) and
+		 * read() fop (user context) with tail pointer updates happening
+		 * in atomic context and head updates in user context and the
+		 * (unlikely) possibility of read() errors needing to reset all
+		 * head/tail state.
+		 *
+		 * Note: Contention/performance aren't currently a significant
+		 * concern here considering the relatively low frequency of
+		 * hrtimer callbacks (5ms period) and that reads typically only
+		 * happen in response to a hrtimer event and likely complete
+		 * before the next callback.
+		 *
+		 * Note: This lock is not held *while* reading and copying data
+		 * to userspace so the value of head observed in htrimer
+		 * callbacks won't represent any partial consumption of data.
+		 */
+		spinlock_t ptr_lock;
+
+		/**
+		 * @head: Although we can always read back the head pointer register,
+		 * we prefer to avoid trusting the HW state, just to avoid any
+		 * risk that some hardware condition could somehow bump the
+		 * head pointer unpredictably and cause us to forward the wrong
+		 * OA buffer data to userspace.
+		 */
+		u32 head;
+
+		/**
+		 * @tail: The last verified tail that can be read by userspace.
+		 */
+		u32 tail;
+	} oa_buffer;
+
+	/**
+	 * @poll_oa_period: The period in nanoseconds at which the OA
+	 * buffer should be checked for available data.
+	 */
+	u64 poll_oa_period;
+};
+#endif
-- 
2.41.0



More information about the Intel-gfx-trybot mailing list