summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Roberto de Souza <jose.souza@intel.com>2023-09-19 08:52:18 -0700
committerMarge Bot <emma+marge@anholt.net>2023-10-23 23:24:26 +0000
commit531605accfbe2530c4710087b78b79f1dc92569c (patch)
tree437074626008bc4ff5c179d77e83c66ba54892ea
parent9dcc74e5579a5182959ab36454c6ae97ff814784 (diff)
downloadmesa-531605accfbe2530c4710087b78b79f1dc92569c.tar.gz
mesa-531605accfbe2530c4710087b78b79f1dc92569c.tar.bz2
mesa-531605accfbe2530c4710087b78b79f1dc92569c.zip
intel: Sync xe_drm.h
Sync xe_drm.h with commit xxxxx ("drm/xe/uapi: Fix naming of XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY"). One not so straght forward change is that sync VM binds now don't require a syncobj anymore, the uAPI will return as soon the VM bind operations are done. Signed-off-by: José Roberto de Souza <jose.souza@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25300>
-rw-r--r--include/drm-uapi/xe_drm.h379
-rw-r--r--src/gallium/drivers/iris/xe/iris_kmd_backend.c36
-rw-r--r--src/intel/common/xe/intel_gem.c11
-rw-r--r--src/intel/dev/xe/intel_device_info.c14
-rw-r--r--src/intel/vulkan/xe/anv_device.c6
-rw-r--r--src/intel/vulkan/xe/anv_kmd_backend.c18
6 files changed, 223 insertions, 241 deletions
diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
index 00d5cb4ef85..6ff1106e4ec 100644
--- a/include/drm-uapi/xe_drm.h
+++ b/include/drm-uapi/xe_drm.h
@@ -3,8 +3,8 @@
* Copyright © 2023 Intel Corporation
*/
-#ifndef _UAPI_XE_DRM_H_
-#define _UAPI_XE_DRM_H_
+#ifndef _XE_DRM_H_
+#define _XE_DRM_H_
#include "drm.h"
@@ -39,7 +39,7 @@ extern "C" {
* redefine the interface more easily than an ever growing struct of
* increasing complexity, and for large parts of that interface to be
* entirely optional. The downside is more pointer chasing; chasing across
- * the __user boundary with pointers encapsulated inside u64.
+ * the boundary with pointers encapsulated inside u64.
*
* Example chaining:
*
@@ -106,11 +106,10 @@ struct xe_user_extension {
#define DRM_XE_EXEC_QUEUE_CREATE 0x06
#define DRM_XE_EXEC_QUEUE_DESTROY 0x07
#define DRM_XE_EXEC 0x08
-#define DRM_XE_MMIO 0x09
-#define DRM_XE_EXEC_QUEUE_SET_PROPERTY 0x0a
-#define DRM_XE_WAIT_USER_FENCE 0x0b
-#define DRM_XE_VM_MADVISE 0x0c
-#define DRM_XE_EXEC_QUEUE_GET_PROPERTY 0x0d
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY 0x09
+#define DRM_XE_WAIT_USER_FENCE 0x0a
+#define DRM_XE_VM_MADVISE 0x0b
+#define DRM_XE_EXEC_QUEUE_GET_PROPERTY 0x0c
/* Must be kept compact -- no holes */
#define DRM_IOCTL_XE_DEVICE_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_DEVICE_QUERY, struct drm_xe_device_query)
@@ -123,11 +122,30 @@ struct xe_user_extension {
#define DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_GET_PROPERTY, struct drm_xe_exec_queue_get_property)
#define DRM_IOCTL_XE_EXEC_QUEUE_DESTROY DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_DESTROY, struct drm_xe_exec_queue_destroy)
#define DRM_IOCTL_XE_EXEC DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC, struct drm_xe_exec)
-#define DRM_IOCTL_XE_MMIO DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_MMIO, struct drm_xe_mmio)
#define DRM_IOCTL_XE_EXEC_QUEUE_SET_PROPERTY DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_SET_PROPERTY, struct drm_xe_exec_queue_set_property)
#define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
#define DRM_IOCTL_XE_VM_MADVISE DRM_IOW(DRM_COMMAND_BASE + DRM_XE_VM_MADVISE, struct drm_xe_vm_madvise)
+/** struct drm_xe_engine_class_instance - instance of an engine class */
+struct drm_xe_engine_class_instance {
+#define DRM_XE_ENGINE_CLASS_RENDER 0
+#define DRM_XE_ENGINE_CLASS_COPY 1
+#define DRM_XE_ENGINE_CLASS_VIDEO_DECODE 2
+#define DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE 3
+#define DRM_XE_ENGINE_CLASS_COMPUTE 4
+ /*
+ * Kernel only classes (not actual hardware engine class). Used for
+ * creating ordered queues of VM bind operations.
+ */
+#define DRM_XE_ENGINE_CLASS_VM_BIND_ASYNC 5
+#define DRM_XE_ENGINE_CLASS_VM_BIND_SYNC 6
+ __u16 engine_class;
+
+ __u16 engine_instance;
+ __u16 gt_id;
+ __u16 rsvd;
+};
+
/**
* enum drm_xe_memory_class - Supported memory classes.
*/
@@ -220,6 +238,60 @@ struct drm_xe_query_mem_region {
};
/**
+ * struct drm_xe_query_engine_cycles - correlate CPU and GPU timestamps
+ *
+ * If a query is made with a struct drm_xe_device_query where .query is equal to
+ * DRM_XE_DEVICE_QUERY_ENGINE_CYCLES, then the reply uses struct drm_xe_query_engine_cycles
+ * in .data. struct drm_xe_query_engine_cycles is allocated by the user and
+ * .data points to this allocated structure.
+ *
+ * The query returns the engine cycles and the frequency that can
+ * be used to calculate the engine timestamp. In addition the
+ * query returns a set of cpu timestamps that indicate when the command
+ * streamer cycle count was captured.
+ */
+struct drm_xe_query_engine_cycles {
+ /**
+ * @eci: This is input by the user and is the engine for which command
+ * streamer cycles is queried.
+ */
+ struct drm_xe_engine_class_instance eci;
+
+ /**
+ * @clockid: This is input by the user and is the reference clock id for
+ * CPU timestamp. For definition, see clock_gettime(2) and
+ * perf_event_open(2). Supported clock ids are CLOCK_MONOTONIC,
+ * CLOCK_MONOTONIC_RAW, CLOCK_REALTIME, CLOCK_BOOTTIME, CLOCK_TAI.
+ */
+ __s32 clockid;
+
+ /** @width: Width of the engine cycle counter in bits. */
+ __u32 width;
+
+ /**
+ * @engine_cycles: Engine cycles as read from its register
+ * at 0x358 offset.
+ */
+ __u64 engine_cycles;
+
+ /** @engine_frequency: Frequency of the engine cycles in Hz. */
+ __u64 engine_frequency;
+
+ /**
+ * @cpu_timestamp: CPU timestamp in ns. The timestamp is captured before
+ * reading the engine_cycles register using the reference clockid set by the
+ * user.
+ */
+ __u64 cpu_timestamp;
+
+ /**
+ * @cpu_delta: Time delta in ns captured around reading the lower dword
+ * of the engine_cycles register.
+ */
+ __u64 cpu_delta;
+};
+
+/**
* struct drm_xe_query_mem_usage - describe memory regions and usage
*
* If a query is made with a struct drm_xe_device_query where .query
@@ -256,46 +328,65 @@ struct drm_xe_query_config {
#define XE_QUERY_CONFIG_VA_BITS 3
#define XE_QUERY_CONFIG_GT_COUNT 4
#define XE_QUERY_CONFIG_MEM_REGION_COUNT 5
-#define XE_QUERY_CONFIG_MAX_ENGINE_PRIORITY 6
-#define XE_QUERY_CONFIG_NUM_PARAM (XE_QUERY_CONFIG_MAX_ENGINE_PRIORITY + 1)
+#define XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY 6
+#define XE_QUERY_CONFIG_NUM_PARAM (XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY + 1)
/** @info: array of elements containing the config info */
__u64 info[];
};
/**
- * struct drm_xe_query_gts - describe GTs
+ * struct drm_xe_query_gt - describe an individual GT.
+ *
+ * To be used with drm_xe_query_gt_list, which will return a list with all the
+ * existing GT individual descriptions.
+ * Graphics Technology (GT) is a subset of a GPU/tile that is responsible for
+ * implementing graphics and/or media operations.
+ */
+struct drm_xe_query_gt {
+#define XE_QUERY_GT_TYPE_MAIN 0
+#define XE_QUERY_GT_TYPE_REMOTE 1
+#define XE_QUERY_GT_TYPE_MEDIA 2
+ /** @type: GT type: Main, Remote, or Media */
+ __u16 type;
+ /** @gt_id: Unique ID of this GT within the PCI Device */
+ __u16 gt_id;
+ /** @clock_freq: A clock frequency for timestamp */
+ __u32 clock_freq;
+ /**
+ * @native_mem_regions: Bit mask of instances from
+ * drm_xe_query_mem_usage that lives on the same GPU/Tile and have
+ * direct access.
+ */
+ __u64 native_mem_regions;
+ /**
+ * @slow_mem_regions: Bit mask of instances from
+ * drm_xe_query_mem_usage that this GT can indirectly access, although
+ * they live on a different GPU/Tile.
+ */
+ __u64 slow_mem_regions;
+ /**
+ * @inaccessible_mem_regions: Bit mask of instances from
+ * drm_xe_query_mem_usage that is not accessible by this GT at all.
+ */
+ __u64 inaccessible_mem_regions;
+ /** @reserved: Reserved */
+ __u64 reserved[8];
+};
+
+/**
+ * struct drm_xe_query_gt_list - A list with GT description items.
*
* If a query is made with a struct drm_xe_device_query where .query
- * is equal to DRM_XE_DEVICE_QUERY_GTS, then the reply uses struct
- * drm_xe_query_gts in .data.
+ * is equal to DRM_XE_DEVICE_QUERY_GT_LIST, then the reply uses struct
+ * drm_xe_query_gt_list in .data.
*/
-struct drm_xe_query_gts {
- /** @num_gt: number of GTs returned in gts */
+struct drm_xe_query_gt_list {
+ /** @num_gt: number of GT items returned in gt_list */
__u32 num_gt;
-
/** @pad: MBZ */
__u32 pad;
-
- /**
- * @gts: The GTs returned for this device
- *
- * TODO: convert drm_xe_query_gt to proper kernel-doc.
- * TODO: Perhaps info about every mem region relative to this GT? e.g.
- * bandwidth between this GT and remote region?
- */
- struct drm_xe_query_gt {
-#define XE_QUERY_GT_TYPE_MAIN 0
-#define XE_QUERY_GT_TYPE_REMOTE 1
-#define XE_QUERY_GT_TYPE_MEDIA 2
- __u16 type;
- __u16 instance;
- __u32 clock_freq;
- __u64 features;
- __u64 native_mem_regions; /* bit mask of instances from drm_xe_query_mem_usage */
- __u64 slow_mem_regions; /* bit mask of instances from drm_xe_query_mem_usage */
- __u64 inaccessible_mem_regions; /* bit mask of instances from drm_xe_query_mem_usage */
- __u64 reserved[8];
- } gts[];
+ /** @gt_list: The GT list returned for this device */
+ struct drm_xe_query_gt gt_list[];
};
/**
@@ -385,12 +476,13 @@ struct drm_xe_device_query {
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;
-#define DRM_XE_DEVICE_QUERY_ENGINES 0
-#define DRM_XE_DEVICE_QUERY_MEM_USAGE 1
-#define DRM_XE_DEVICE_QUERY_CONFIG 2
-#define DRM_XE_DEVICE_QUERY_GTS 3
-#define DRM_XE_DEVICE_QUERY_HWCONFIG 4
-#define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5
+#define DRM_XE_DEVICE_QUERY_ENGINES 0
+#define DRM_XE_DEVICE_QUERY_MEM_USAGE 1
+#define DRM_XE_DEVICE_QUERY_CONFIG 2
+#define DRM_XE_DEVICE_QUERY_GT_LIST 3
+#define DRM_XE_DEVICE_QUERY_HWCONFIG 4
+#define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5
+#define DRM_XE_DEVICE_QUERY_ENGINE_CYCLES 6
/** @query: The type of data to query */
__u32 query;
@@ -480,29 +572,11 @@ struct drm_xe_gem_mmap_offset {
__u64 reserved[2];
};
-/**
- * struct drm_xe_vm_bind_op_error_capture - format of VM bind op error capture
- */
-struct drm_xe_vm_bind_op_error_capture {
- /** @error: errno that occurred */
- __s32 error;
-
- /** @op: operation that encounter an error */
- __u32 op;
-
- /** @addr: address of bind op */
- __u64 addr;
-
- /** @size: size of bind */
- __u64 size;
-};
-
-/** struct drm_xe_ext_vm_set_property - VM set property extension */
-struct drm_xe_ext_vm_set_property {
+/** struct drm_xe_ext_set_property - XE set property extension */
+struct drm_xe_ext_set_property {
/** @base: base user extension */
struct xe_user_extension base;
-#define XE_VM_PROPERTY_BIND_OP_ERROR_CAPTURE_ADDRESS 0
/** @property: property to set */
__u32 property;
@@ -523,7 +597,7 @@ struct drm_xe_vm_create {
#define DRM_XE_VM_CREATE_SCRATCH_PAGE (0x1 << 0)
#define DRM_XE_VM_CREATE_COMPUTE_MODE (0x1 << 1)
-#define DRM_XE_VM_CREATE_ASYNC_BIND_OPS (0x1 << 2)
+#define DRM_XE_VM_CREATE_ASYNC_DEFAULT (0x1 << 2)
#define DRM_XE_VM_CREATE_FAULT_MODE (0x1 << 3)
/** @flags: Flags */
__u32 flags;
@@ -583,41 +657,18 @@ struct drm_xe_vm_bind_op {
#define XE_VM_BIND_OP_MAP 0x0
#define XE_VM_BIND_OP_UNMAP 0x1
#define XE_VM_BIND_OP_MAP_USERPTR 0x2
-#define XE_VM_BIND_OP_RESTART 0x3
-#define XE_VM_BIND_OP_UNMAP_ALL 0x4
-#define XE_VM_BIND_OP_PREFETCH 0x5
+#define XE_VM_BIND_OP_UNMAP_ALL 0x3
+#define XE_VM_BIND_OP_PREFETCH 0x4
+ /** @op: Bind operation to perform */
+ __u32 op;
-#define XE_VM_BIND_FLAG_READONLY (0x1 << 16)
- /*
- * A bind ops completions are always async, hence the support for out
- * sync. This flag indicates the allocation of the memory for new page
- * tables and the job to program the pages tables is asynchronous
- * relative to the IOCTL. That part of a bind operation can fail under
- * memory pressure, the job in practice can't fail unless the system is
- * totally shot.
- *
- * If this flag is clear and the IOCTL doesn't return an error, in
- * practice the bind op is good and will complete.
- *
- * If this flag is set and doesn't return an error, the bind op can
- * still fail and recovery is needed. If configured, the bind op that
- * caused the error will be captured in drm_xe_vm_bind_op_error_capture.
- * Once the user sees the error (via a ufence +
- * XE_VM_PROPERTY_BIND_OP_ERROR_CAPTURE_ADDRESS), it should free memory
- * via non-async unbinds, and then restart all queued async binds op via
- * XE_VM_BIND_OP_RESTART. Or alternatively the user should destroy the
- * VM.
- *
- * This flag is only allowed when DRM_XE_VM_CREATE_ASYNC_BIND_OPS is
- * configured in the VM and must be set if the VM is configured with
- * DRM_XE_VM_CREATE_ASYNC_BIND_OPS and not in an error state.
- */
-#define XE_VM_BIND_FLAG_ASYNC (0x1 << 17)
+#define XE_VM_BIND_FLAG_READONLY (0x1 << 0)
+#define XE_VM_BIND_FLAG_ASYNC (0x1 << 1)
/*
* Valid on a faulting VM only, do the MAP operation immediately rather
* than deferring the MAP to the page fault handler.
*/
-#define XE_VM_BIND_FLAG_IMMEDIATE (0x1 << 18)
+#define XE_VM_BIND_FLAG_IMMEDIATE (0x1 << 2)
/*
* When the NULL flag is set, the page tables are setup with a special
* bit which indicates writes are dropped and all reads return zero. In
@@ -625,9 +676,9 @@ struct drm_xe_vm_bind_op {
* operations, the BO handle MBZ, and the BO offset MBZ. This flag is
* intended to implement VK sparse bindings.
*/
-#define XE_VM_BIND_FLAG_NULL (0x1 << 19)
- /** @op: Operation to perform (lower 16 bits) and flags (upper 16 bits) */
- __u32 op;
+#define XE_VM_BIND_FLAG_NULL (0x1 << 3)
+ /** @flags: Bind flags */
+ __u32 flags;
/** @mem_region: Memory region to prefetch VMA to, instance not a mask */
__u32 region;
@@ -680,21 +731,6 @@ struct drm_xe_vm_bind {
__u64 reserved[2];
};
-/** struct drm_xe_ext_exec_queue_set_property - exec queue set property extension */
-struct drm_xe_ext_exec_queue_set_property {
- /** @base: base user extension */
- struct xe_user_extension base;
-
- /** @property: property to set */
- __u32 property;
-
- /** @pad: MBZ */
- __u32 pad;
-
- /** @value: property value */
- __u64 value;
-};
-
/**
* struct drm_xe_exec_queue_set_property - exec queue set property
*
@@ -707,21 +743,14 @@ struct drm_xe_exec_queue_set_property {
/** @exec_queue_id: Exec queue ID */
__u32 exec_queue_id;
-#define XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY 0
+#define XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY 0
#define XE_EXEC_QUEUE_SET_PROPERTY_TIMESLICE 1
#define XE_EXEC_QUEUE_SET_PROPERTY_PREEMPTION_TIMEOUT 2
- /*
- * Long running or ULLS engine mode. DMA fences not allowed in this
- * mode. Must match the value of DRM_XE_VM_CREATE_COMPUTE_MODE, serves
- * as a sanity check the UMD knows what it is doing. Can only be set at
- * engine create time.
- */
-#define XE_EXEC_QUEUE_SET_PROPERTY_COMPUTE_MODE 3
-#define XE_EXEC_QUEUE_SET_PROPERTY_PERSISTENCE 4
-#define XE_EXEC_QUEUE_SET_PROPERTY_JOB_TIMEOUT 5
-#define XE_EXEC_QUEUE_SET_PROPERTY_ACC_TRIGGER 6
-#define XE_EXEC_QUEUE_SET_PROPERTY_ACC_NOTIFY 7
-#define XE_EXEC_QUEUE_SET_PROPERTY_ACC_GRANULARITY 8
+#define XE_EXEC_QUEUE_SET_PROPERTY_PERSISTENCE 3
+#define XE_EXEC_QUEUE_SET_PROPERTY_JOB_TIMEOUT 4
+#define XE_EXEC_QUEUE_SET_PROPERTY_ACC_TRIGGER 5
+#define XE_EXEC_QUEUE_SET_PROPERTY_ACC_NOTIFY 6
+#define XE_EXEC_QUEUE_SET_PROPERTY_ACC_GRANULARITY 7
/** @property: property to set */
__u32 property;
@@ -732,24 +761,6 @@ struct drm_xe_exec_queue_set_property {
__u64 reserved[2];
};
-/** struct drm_xe_engine_class_instance - instance of an engine class */
-struct drm_xe_engine_class_instance {
-#define DRM_XE_ENGINE_CLASS_RENDER 0
-#define DRM_XE_ENGINE_CLASS_COPY 1
-#define DRM_XE_ENGINE_CLASS_VIDEO_DECODE 2
-#define DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE 3
-#define DRM_XE_ENGINE_CLASS_COMPUTE 4
- /*
- * Kernel only class (not actual hardware engine class). Used for
- * creating ordered queues of VM bind operations.
- */
-#define DRM_XE_ENGINE_CLASS_VM_BIND 5
- __u16 engine_class;
-
- __u16 engine_instance;
- __u16 gt_id;
-};
-
struct drm_xe_exec_queue_create {
#define XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY 0
/** @extensions: Pointer to the first extension struct, if any */
@@ -878,27 +889,6 @@ struct drm_xe_exec {
__u64 reserved[2];
};
-struct drm_xe_mmio {
- /** @extensions: Pointer to the first extension struct, if any */
- __u64 extensions;
-
- __u32 addr;
-
-#define DRM_XE_MMIO_8BIT 0x0
-#define DRM_XE_MMIO_16BIT 0x1
-#define DRM_XE_MMIO_32BIT 0x2
-#define DRM_XE_MMIO_64BIT 0x3
-#define DRM_XE_MMIO_BITS_MASK 0x3
-#define DRM_XE_MMIO_READ 0x4
-#define DRM_XE_MMIO_WRITE 0x8
- __u32 flags;
-
- __u64 value;
-
- /** @reserved: Reserved */
- __u64 reserved[2];
-};
-
/**
* struct drm_xe_wait_user_fence - wait user fence
*
@@ -913,18 +903,10 @@ struct drm_xe_wait_user_fence {
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;
- union {
- /**
- * @addr: user pointer address to wait on, must qword aligned
- */
- __u64 addr;
-
- /**
- * @vm_id: The ID of the VM which encounter an error used with
- * DRM_XE_UFENCE_WAIT_VM_ERROR. Upper 32 bits must be clear.
- */
- __u64 vm_id;
- };
+ /**
+ * @addr: user pointer address to wait on, must qword aligned
+ */
+ __u64 addr;
#define DRM_XE_UFENCE_WAIT_EQ 0
#define DRM_XE_UFENCE_WAIT_NEQ 1
@@ -937,7 +919,6 @@ struct drm_xe_wait_user_fence {
#define DRM_XE_UFENCE_WAIT_SOFT_OP (1 << 0) /* e.g. Wait on VM bind */
#define DRM_XE_UFENCE_WAIT_ABSTIME (1 << 1)
-#define DRM_XE_UFENCE_WAIT_VM_ERROR (1 << 2)
/** @flags: wait flags */
__u16 flags;
@@ -1053,8 +1034,48 @@ struct drm_xe_vm_madvise {
__u64 reserved[2];
};
+/**
+ * DOC: XE PMU event config IDs
+ *
+ * Check 'man perf_event_open' to use the ID's XE_PMU_XXXX listed in xe_drm.h
+ * in 'struct perf_event_attr' as part of perf_event_open syscall to read a
+ * particular event.
+ *
+ * For example to open the XE_PMU_INTERRUPTS(0):
+ *
+ * .. code-block:: C
+ *
+ * struct perf_event_attr attr;
+ * long long count;
+ * int cpu = 0;
+ * int fd;
+ *
+ * memset(&attr, 0, sizeof(struct perf_event_attr));
+ * attr.type = type; // eg: /sys/bus/event_source/devices/xe_0000_56_00.0/type
+ * attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED;
+ * attr.use_clockid = 1;
+ * attr.clockid = CLOCK_MONOTONIC;
+ * attr.config = XE_PMU_INTERRUPTS(0);
+ *
+ * fd = syscall(__NR_perf_event_open, &attr, -1, cpu, -1, 0);
+ */
+
+/*
+ * Top bits of every counter are GT id.
+ */
+#define __XE_PMU_GT_SHIFT (56)
+
+#define ___XE_PMU_OTHER(gt, x) \
+ (((__u64)(x)) | ((__u64)(gt) << __XE_PMU_GT_SHIFT))
+
+#define XE_PMU_INTERRUPTS(gt) ___XE_PMU_OTHER(gt, 0)
+#define XE_PMU_RENDER_GROUP_BUSY(gt) ___XE_PMU_OTHER(gt, 1)
+#define XE_PMU_COPY_GROUP_BUSY(gt) ___XE_PMU_OTHER(gt, 2)
+#define XE_PMU_MEDIA_GROUP_BUSY(gt) ___XE_PMU_OTHER(gt, 3)
+#define XE_PMU_ANY_ENGINE_GROUP_BUSY(gt) ___XE_PMU_OTHER(gt, 4)
+
#if defined(__cplusplus)
}
#endif
-#endif /* _UAPI_XE_DRM_H_ */
+#endif /* _XE_DRM_H_ */
diff --git a/src/gallium/drivers/iris/xe/iris_kmd_backend.c b/src/gallium/drivers/iris/xe/iris_kmd_backend.c
index b1cfc9fbf34..609d70e9154 100644
--- a/src/gallium/drivers/iris/xe/iris_kmd_backend.c
+++ b/src/gallium/drivers/iris/xe/iris_kmd_backend.c
@@ -89,25 +89,9 @@ xe_gem_mmap(struct iris_bufmgr *bufmgr, struct iris_bo *bo)
static inline int
xe_gem_vm_bind_op(struct iris_bo *bo, uint32_t op)
{
- struct drm_syncobj_create create = {};
- int ret = intel_ioctl(iris_bufmgr_get_fd(bo->bufmgr),
- DRM_IOCTL_SYNCOBJ_CREATE, &create);
- if (ret) {
- DBG("vm_bind_op: Unable to create SYNCOBJ(%i)", ret);
- return ret;
- }
-
- struct drm_xe_sync sync = {
- .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL,
- .handle = create.handle,
- };
- /* Old compilers do not allow declarations after 'goto label' */
- struct drm_syncobj_destroy destroy = {
- .handle = create.handle,
- };
-
uint32_t handle = op == XE_VM_BIND_OP_UNMAP ? 0 : bo->gem_handle;
uint64_t range, obj_offset = 0;
+ int ret;
if (iris_bo_is_imported(bo))
range = bo->size;
@@ -130,30 +114,12 @@ xe_gem_vm_bind_op(struct iris_bo *bo, uint32_t op)
.bind.range = range,
.bind.addr = intel_48b_address(bo->address),
.bind.op = op,
- .num_syncs = 1,
- .syncs = (uintptr_t)&sync,
};
ret = intel_ioctl(iris_bufmgr_get_fd(bo->bufmgr), DRM_IOCTL_XE_VM_BIND, &args);
if (ret) {
DBG("vm_bind_op: DRM_IOCTL_XE_VM_BIND failed(%i)", ret);
- goto bind_error;
}
- struct drm_syncobj_wait wait = {
- .handles = (uintptr_t)&create.handle,
- .timeout_nsec = INT64_MAX,
- .count_handles = 1,
- .flags = 0,
- .first_signaled = 0,
- .pad = 0,
- };
- ret = intel_ioctl(iris_bufmgr_get_fd(bo->bufmgr), DRM_IOCTL_SYNCOBJ_WAIT, &wait);
- if (ret)
- DBG("vm_bind_op: DRM_IOCTL_SYNCOBJ_WAIT failed(%i)", ret);
-
-bind_error:
- if (intel_ioctl(iris_bufmgr_get_fd(bo->bufmgr), DRM_IOCTL_SYNCOBJ_DESTROY, &destroy))
- DBG("vm_bind_op: Unable to destroy SYNCOBJ(%i)", ret);
return ret;
}
diff --git a/src/intel/common/xe/intel_gem.c b/src/intel/common/xe/intel_gem.c
index b9e9fa70a3b..cca0db5e956 100644
--- a/src/intel/common/xe/intel_gem.c
+++ b/src/intel/common/xe/intel_gem.c
@@ -29,15 +29,8 @@
bool
xe_gem_read_render_timestamp(int fd, uint64_t *value)
{
- struct drm_xe_mmio mmio = {
- .addr = RCS_TIMESTAMP,
- .flags = DRM_XE_MMIO_READ | DRM_XE_MMIO_64BIT,
- };
- if (intel_ioctl(fd, DRM_IOCTL_XE_MMIO, &mmio))
- return false;
-
- *value = mmio.value;
- return true;
+ /* TODO: re-implement with DRM_XE_QUERY_CS_CYCLES */
+ return false;
}
bool
diff --git a/src/intel/dev/xe/intel_device_info.c b/src/intel/dev/xe/intel_device_info.c
index 92e281810f0..cf944e9dc3a 100644
--- a/src/intel/dev/xe/intel_device_info.c
+++ b/src/intel/dev/xe/intel_device_info.c
@@ -132,17 +132,17 @@ intel_device_info_xe_query_regions(int fd, struct intel_device_info *devinfo,
static bool
xe_query_gts(int fd, struct intel_device_info *devinfo)
{
- struct drm_xe_query_gts *gts;
- gts = xe_query_alloc_fetch(fd, DRM_XE_DEVICE_QUERY_GTS, NULL);
- if (!gts)
+ struct drm_xe_query_gt_list *gt_list;
+ gt_list = xe_query_alloc_fetch(fd, DRM_XE_DEVICE_QUERY_GT_LIST, NULL);
+ if (!gt_list)
return false;
- for (uint32_t i = 0; i < gts->num_gt; i++) {
- if (gts->gts[i].type == XE_QUERY_GT_TYPE_MAIN)
- devinfo->timestamp_frequency = gts->gts[i].clock_freq;
+ for (uint32_t i = 0; i < gt_list->num_gt; i++) {
+ if (gt_list->gt_list[i].type == XE_QUERY_GT_TYPE_MAIN)
+ devinfo->timestamp_frequency = gt_list->gt_list[i].clock_freq;
}
- free(gts);
+ free(gt_list);
return true;
}
diff --git a/src/intel/vulkan/xe/anv_device.c b/src/intel/vulkan/xe/anv_device.c
index dbb1e2e0ca0..de5b98afd16 100644
--- a/src/intel/vulkan/xe/anv_device.c
+++ b/src/intel/vulkan/xe/anv_device.c
@@ -37,8 +37,8 @@ bool anv_xe_device_destroy_vm(struct anv_device *device)
VkResult anv_xe_device_setup_vm(struct anv_device *device)
{
struct drm_xe_vm_create create = {
- .flags = DRM_XE_VM_CREATE_SCRATCH_PAGE |
- DRM_XE_VM_CREATE_ASYNC_BIND_OPS,
+ .flags = DRM_XE_VM_CREATE_ASYNC_DEFAULT |
+ DRM_XE_VM_CREATE_SCRATCH_PAGE,
};
if (intel_ioctl(device->fd, DRM_IOCTL_XE_VM_CREATE, &create) != 0)
return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED,
@@ -98,7 +98,7 @@ anv_xe_physical_device_get_parameters(struct anv_physical_device *device)
device->has_exec_timeline = true;
device->max_context_priority =
- drm_sched_priority_to_vk_priority(config->info[XE_QUERY_CONFIG_MAX_ENGINE_PRIORITY]);
+ drm_sched_priority_to_vk_priority(config->info[XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY]);
free(config);
return VK_SUCCESS;
diff --git a/src/intel/vulkan/xe/anv_kmd_backend.c b/src/intel/vulkan/xe/anv_kmd_backend.c
index 3b3e6a53048..7a61499d004 100644
--- a/src/intel/vulkan/xe/anv_kmd_backend.c
+++ b/src/intel/vulkan/xe/anv_kmd_backend.c
@@ -117,8 +117,10 @@ xe_vm_bind_op(struct anv_device *device, int num_binds,
STACK_ARRAY(struct drm_xe_vm_bind_op, xe_binds_stackarray, num_binds);
struct drm_xe_vm_bind_op *xe_binds;
if (num_binds > 1) {
- if (!xe_binds_stackarray)
+ if (!xe_binds_stackarray) {
+ ret = -ENOMEM;
goto out_syncobj;
+ }
xe_binds = xe_binds_stackarray;
args.vector_of_binds = (uintptr_t)xe_binds;
@@ -138,12 +140,18 @@ xe_vm_bind_op(struct anv_device *device, int num_binds,
.addr = intel_48b_address(bind->address),
.tile_mask = 0,
.op = XE_VM_BIND_OP_UNMAP,
+ /* TODO: do proper error handling here, once the way to do it is
+ * settled. As of right now the final interface is still under
+ * discussion.
+ */
+ .flags = XE_VM_BIND_FLAG_ASYNC,
.region = 0,
};
if (bind->op == ANV_VM_BIND) {
if (!bo) {
- xe_bind->op = XE_VM_BIND_OP_MAP | XE_VM_BIND_FLAG_NULL;
+ xe_bind->op = XE_VM_BIND_OP_MAP;
+ xe_bind->flags |= XE_VM_BIND_FLAG_NULL;
assert(xe_bind->obj_offset == 0);
} else if (bo->from_host_ptr) {
xe_bind->op = XE_VM_BIND_OP_MAP_USERPTR;
@@ -153,12 +161,6 @@ xe_vm_bind_op(struct anv_device *device, int num_binds,
}
}
- /* TODO: do proper error handling here, once the way to do it is
- * settled. As of right now the final interface is still under
- * discussion.
- */
- xe_bind->op |= XE_VM_BIND_FLAG_ASYNC;
-
/* userptr and bo_offset are an union! */
if (bo && bo->from_host_ptr)
xe_bind->userptr = (uintptr_t)bo->map;