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>
This commit is contained in:
José Roberto de Souza
2023-09-19 08:52:18 -07:00
committed by Marge Bot
parent 9dcc74e557
commit 531605accf
6 changed files with 224 additions and 242 deletions

View File

@@ -3,8 +3,8 @@
* Copyright © 2023 Intel Corporation * Copyright © 2023 Intel Corporation
*/ */
#ifndef _UAPI_XE_DRM_H_ #ifndef _XE_DRM_H_
#define _UAPI_XE_DRM_H_ #define _XE_DRM_H_
#include "drm.h" #include "drm.h"
@@ -39,7 +39,7 @@ extern "C" {
* redefine the interface more easily than an ever growing struct of * redefine the interface more easily than an ever growing struct of
* increasing complexity, and for large parts of that interface to be * increasing complexity, and for large parts of that interface to be
* entirely optional. The downside is more pointer chasing; chasing across * 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: * Example chaining:
* *
@@ -106,11 +106,10 @@ struct xe_user_extension {
#define DRM_XE_EXEC_QUEUE_CREATE 0x06 #define DRM_XE_EXEC_QUEUE_CREATE 0x06
#define DRM_XE_EXEC_QUEUE_DESTROY 0x07 #define DRM_XE_EXEC_QUEUE_DESTROY 0x07
#define DRM_XE_EXEC 0x08 #define DRM_XE_EXEC 0x08
#define DRM_XE_MMIO 0x09 #define DRM_XE_EXEC_QUEUE_SET_PROPERTY 0x09
#define DRM_XE_EXEC_QUEUE_SET_PROPERTY 0x0a #define DRM_XE_WAIT_USER_FENCE 0x0a
#define DRM_XE_WAIT_USER_FENCE 0x0b #define DRM_XE_VM_MADVISE 0x0b
#define DRM_XE_VM_MADVISE 0x0c #define DRM_XE_EXEC_QUEUE_GET_PROPERTY 0x0c
#define DRM_XE_EXEC_QUEUE_GET_PROPERTY 0x0d
/* Must be kept compact -- no holes */ /* 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) #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_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_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_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_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_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) #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. * enum drm_xe_memory_class - Supported memory classes.
*/ */
@@ -219,6 +237,60 @@ struct drm_xe_query_mem_region {
__u64 reserved[6]; __u64 reserved[6];
}; };
/**
* 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 * struct drm_xe_query_mem_usage - describe memory regions and usage
* *
@@ -256,46 +328,65 @@ struct drm_xe_query_config {
#define XE_QUERY_CONFIG_VA_BITS 3 #define XE_QUERY_CONFIG_VA_BITS 3
#define XE_QUERY_CONFIG_GT_COUNT 4 #define XE_QUERY_CONFIG_GT_COUNT 4
#define XE_QUERY_CONFIG_MEM_REGION_COUNT 5 #define XE_QUERY_CONFIG_MEM_REGION_COUNT 5
#define XE_QUERY_CONFIG_MAX_ENGINE_PRIORITY 6 #define XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY 6
#define XE_QUERY_CONFIG_NUM_PARAM (XE_QUERY_CONFIG_MAX_ENGINE_PRIORITY + 1) #define XE_QUERY_CONFIG_NUM_PARAM (XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY + 1)
/** @info: array of elements containing the config info */ /** @info: array of elements containing the config info */
__u64 info[]; __u64 info[];
}; };
/** /**
* struct drm_xe_query_gts - describe GTs * struct drm_xe_query_gt - describe an individual GT.
* *
* If a query is made with a struct drm_xe_device_query where .query * To be used with drm_xe_query_gt_list, which will return a list with all the
* is equal to DRM_XE_DEVICE_QUERY_GTS, then the reply uses struct * existing GT individual descriptions.
* drm_xe_query_gts in .data. * Graphics Technology (GT) is a subset of a GPU/tile that is responsible for
* implementing graphics and/or media operations.
*/ */
struct drm_xe_query_gts { struct drm_xe_query_gt {
/** @num_gt: number of GTs returned in gts */
__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_MAIN 0
#define XE_QUERY_GT_TYPE_REMOTE 1 #define XE_QUERY_GT_TYPE_REMOTE 1
#define XE_QUERY_GT_TYPE_MEDIA 2 #define XE_QUERY_GT_TYPE_MEDIA 2
__u16 type; /** @type: GT type: Main, Remote, or Media */
__u16 instance; __u16 type;
__u32 clock_freq; /** @gt_id: Unique ID of this GT within the PCI Device */
__u64 features; __u16 gt_id;
__u64 native_mem_regions; /* bit mask of instances from drm_xe_query_mem_usage */ /** @clock_freq: A clock frequency for timestamp */
__u64 slow_mem_regions; /* bit mask of instances from drm_xe_query_mem_usage */ __u32 clock_freq;
__u64 inaccessible_mem_regions; /* bit mask of instances from drm_xe_query_mem_usage */ /**
__u64 reserved[8]; * @native_mem_regions: Bit mask of instances from
} gts[]; * 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_GT_LIST, then the reply uses struct
* drm_xe_query_gt_list in .data.
*/
struct drm_xe_query_gt_list {
/** @num_gt: number of GT items returned in gt_list */
__u32 num_gt;
/** @pad: MBZ */
__u32 pad;
/** @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 */ /** @extensions: Pointer to the first extension struct, if any */
__u64 extensions; __u64 extensions;
#define DRM_XE_DEVICE_QUERY_ENGINES 0 #define DRM_XE_DEVICE_QUERY_ENGINES 0
#define DRM_XE_DEVICE_QUERY_MEM_USAGE 1 #define DRM_XE_DEVICE_QUERY_MEM_USAGE 1
#define DRM_XE_DEVICE_QUERY_CONFIG 2 #define DRM_XE_DEVICE_QUERY_CONFIG 2
#define DRM_XE_DEVICE_QUERY_GTS 3 #define DRM_XE_DEVICE_QUERY_GT_LIST 3
#define DRM_XE_DEVICE_QUERY_HWCONFIG 4 #define DRM_XE_DEVICE_QUERY_HWCONFIG 4
#define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5 #define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5
#define DRM_XE_DEVICE_QUERY_ENGINE_CYCLES 6
/** @query: The type of data to query */ /** @query: The type of data to query */
__u32 query; __u32 query;
@@ -480,29 +572,11 @@ struct drm_xe_gem_mmap_offset {
__u64 reserved[2]; __u64 reserved[2];
}; };
/** /** struct drm_xe_ext_set_property - XE set property extension */
* struct drm_xe_vm_bind_op_error_capture - format of VM bind op error capture struct drm_xe_ext_set_property {
*/
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 {
/** @base: base user extension */ /** @base: base user extension */
struct xe_user_extension base; struct xe_user_extension base;
#define XE_VM_PROPERTY_BIND_OP_ERROR_CAPTURE_ADDRESS 0
/** @property: property to set */ /** @property: property to set */
__u32 property; __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_SCRATCH_PAGE (0x1 << 0)
#define DRM_XE_VM_CREATE_COMPUTE_MODE (0x1 << 1) #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) #define DRM_XE_VM_CREATE_FAULT_MODE (0x1 << 3)
/** @flags: Flags */ /** @flags: Flags */
__u32 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_MAP 0x0
#define XE_VM_BIND_OP_UNMAP 0x1 #define XE_VM_BIND_OP_UNMAP 0x1
#define XE_VM_BIND_OP_MAP_USERPTR 0x2 #define XE_VM_BIND_OP_MAP_USERPTR 0x2
#define XE_VM_BIND_OP_RESTART 0x3 #define XE_VM_BIND_OP_UNMAP_ALL 0x3
#define XE_VM_BIND_OP_UNMAP_ALL 0x4 #define XE_VM_BIND_OP_PREFETCH 0x4
#define XE_VM_BIND_OP_PREFETCH 0x5 /** @op: Bind operation to perform */
__u32 op;
#define XE_VM_BIND_FLAG_READONLY (0x1 << 16) #define XE_VM_BIND_FLAG_READONLY (0x1 << 0)
/* #define XE_VM_BIND_FLAG_ASYNC (0x1 << 1)
* 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)
/* /*
* Valid on a faulting VM only, do the MAP operation immediately rather * Valid on a faulting VM only, do the MAP operation immediately rather
* than deferring the MAP to the page fault handler. * 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 * 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 * 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 * operations, the BO handle MBZ, and the BO offset MBZ. This flag is
* intended to implement VK sparse bindings. * intended to implement VK sparse bindings.
*/ */
#define XE_VM_BIND_FLAG_NULL (0x1 << 19) #define XE_VM_BIND_FLAG_NULL (0x1 << 3)
/** @op: Operation to perform (lower 16 bits) and flags (upper 16 bits) */ /** @flags: Bind flags */
__u32 op; __u32 flags;
/** @mem_region: Memory region to prefetch VMA to, instance not a mask */ /** @mem_region: Memory region to prefetch VMA to, instance not a mask */
__u32 region; __u32 region;
@@ -680,21 +731,6 @@ struct drm_xe_vm_bind {
__u64 reserved[2]; __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 * 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 */ /** @exec_queue_id: Exec queue ID */
__u32 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_TIMESLICE 1
#define XE_EXEC_QUEUE_SET_PROPERTY_PREEMPTION_TIMEOUT 2 #define XE_EXEC_QUEUE_SET_PROPERTY_PREEMPTION_TIMEOUT 2
/* #define XE_EXEC_QUEUE_SET_PROPERTY_PERSISTENCE 3
* Long running or ULLS engine mode. DMA fences not allowed in this #define XE_EXEC_QUEUE_SET_PROPERTY_JOB_TIMEOUT 4
* mode. Must match the value of DRM_XE_VM_CREATE_COMPUTE_MODE, serves #define XE_EXEC_QUEUE_SET_PROPERTY_ACC_TRIGGER 5
* as a sanity check the UMD knows what it is doing. Can only be set at #define XE_EXEC_QUEUE_SET_PROPERTY_ACC_NOTIFY 6
* engine create time. #define XE_EXEC_QUEUE_SET_PROPERTY_ACC_GRANULARITY 7
*/
#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
/** @property: property to set */ /** @property: property to set */
__u32 property; __u32 property;
@@ -732,24 +761,6 @@ struct drm_xe_exec_queue_set_property {
__u64 reserved[2]; __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 { struct drm_xe_exec_queue_create {
#define XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY 0 #define XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY 0
/** @extensions: Pointer to the first extension struct, if any */ /** @extensions: Pointer to the first extension struct, if any */
@@ -878,27 +889,6 @@ struct drm_xe_exec {
__u64 reserved[2]; __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 * 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 */ /** @extensions: Pointer to the first extension struct, if any */
__u64 extensions; __u64 extensions;
union { /**
/** * @addr: user pointer address to wait on, must qword aligned
* @addr: user pointer address to wait on, must qword aligned */
*/ __u64 addr;
__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;
};
#define DRM_XE_UFENCE_WAIT_EQ 0 #define DRM_XE_UFENCE_WAIT_EQ 0
#define DRM_XE_UFENCE_WAIT_NEQ 1 #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_SOFT_OP (1 << 0) /* e.g. Wait on VM bind */
#define DRM_XE_UFENCE_WAIT_ABSTIME (1 << 1) #define DRM_XE_UFENCE_WAIT_ABSTIME (1 << 1)
#define DRM_XE_UFENCE_WAIT_VM_ERROR (1 << 2)
/** @flags: wait flags */ /** @flags: wait flags */
__u16 flags; __u16 flags;
@@ -1053,8 +1034,48 @@ struct drm_xe_vm_madvise {
__u64 reserved[2]; __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) #if defined(__cplusplus)
} }
#endif #endif
#endif /* _UAPI_XE_DRM_H_ */ #endif /* _XE_DRM_H_ */

View File

@@ -89,25 +89,9 @@ xe_gem_mmap(struct iris_bufmgr *bufmgr, struct iris_bo *bo)
static inline int static inline int
xe_gem_vm_bind_op(struct iris_bo *bo, uint32_t op) 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; uint32_t handle = op == XE_VM_BIND_OP_UNMAP ? 0 : bo->gem_handle;
uint64_t range, obj_offset = 0; uint64_t range, obj_offset = 0;
int ret;
if (iris_bo_is_imported(bo)) if (iris_bo_is_imported(bo))
range = bo->size; range = bo->size;
@@ -130,30 +114,12 @@ xe_gem_vm_bind_op(struct iris_bo *bo, uint32_t op)
.bind.range = range, .bind.range = range,
.bind.addr = intel_48b_address(bo->address), .bind.addr = intel_48b_address(bo->address),
.bind.op = op, .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); ret = intel_ioctl(iris_bufmgr_get_fd(bo->bufmgr), DRM_IOCTL_XE_VM_BIND, &args);
if (ret) { if (ret) {
DBG("vm_bind_op: DRM_IOCTL_XE_VM_BIND failed(%i)", 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; return ret;
} }

View File

@@ -29,15 +29,8 @@
bool bool
xe_gem_read_render_timestamp(int fd, uint64_t *value) xe_gem_read_render_timestamp(int fd, uint64_t *value)
{ {
struct drm_xe_mmio mmio = { /* TODO: re-implement with DRM_XE_QUERY_CS_CYCLES */
.addr = RCS_TIMESTAMP, return false;
.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;
} }
bool bool

View File

@@ -132,17 +132,17 @@ intel_device_info_xe_query_regions(int fd, struct intel_device_info *devinfo,
static bool static bool
xe_query_gts(int fd, struct intel_device_info *devinfo) xe_query_gts(int fd, struct intel_device_info *devinfo)
{ {
struct drm_xe_query_gts *gts; struct drm_xe_query_gt_list *gt_list;
gts = xe_query_alloc_fetch(fd, DRM_XE_DEVICE_QUERY_GTS, NULL); gt_list = xe_query_alloc_fetch(fd, DRM_XE_DEVICE_QUERY_GT_LIST, NULL);
if (!gts) if (!gt_list)
return false; return false;
for (uint32_t i = 0; i < gts->num_gt; i++) { for (uint32_t i = 0; i < gt_list->num_gt; i++) {
if (gts->gts[i].type == XE_QUERY_GT_TYPE_MAIN) if (gt_list->gt_list[i].type == XE_QUERY_GT_TYPE_MAIN)
devinfo->timestamp_frequency = gts->gts[i].clock_freq; devinfo->timestamp_frequency = gt_list->gt_list[i].clock_freq;
} }
free(gts); free(gt_list);
return true; return true;
} }

View File

@@ -37,8 +37,8 @@ bool anv_xe_device_destroy_vm(struct anv_device *device)
VkResult anv_xe_device_setup_vm(struct anv_device *device) VkResult anv_xe_device_setup_vm(struct anv_device *device)
{ {
struct drm_xe_vm_create create = { struct drm_xe_vm_create create = {
.flags = DRM_XE_VM_CREATE_SCRATCH_PAGE | .flags = DRM_XE_VM_CREATE_ASYNC_DEFAULT |
DRM_XE_VM_CREATE_ASYNC_BIND_OPS, DRM_XE_VM_CREATE_SCRATCH_PAGE,
}; };
if (intel_ioctl(device->fd, DRM_IOCTL_XE_VM_CREATE, &create) != 0) if (intel_ioctl(device->fd, DRM_IOCTL_XE_VM_CREATE, &create) != 0)
return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 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->has_exec_timeline = true;
device->max_context_priority = 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); free(config);
return VK_SUCCESS; return VK_SUCCESS;

View File

@@ -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); STACK_ARRAY(struct drm_xe_vm_bind_op, xe_binds_stackarray, num_binds);
struct drm_xe_vm_bind_op *xe_binds; struct drm_xe_vm_bind_op *xe_binds;
if (num_binds > 1) { if (num_binds > 1) {
if (!xe_binds_stackarray) if (!xe_binds_stackarray) {
ret = -ENOMEM;
goto out_syncobj; goto out_syncobj;
}
xe_binds = xe_binds_stackarray; xe_binds = xe_binds_stackarray;
args.vector_of_binds = (uintptr_t)xe_binds; 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), .addr = intel_48b_address(bind->address),
.tile_mask = 0, .tile_mask = 0,
.op = XE_VM_BIND_OP_UNMAP, .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, .region = 0,
}; };
if (bind->op == ANV_VM_BIND) { if (bind->op == ANV_VM_BIND) {
if (!bo) { 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); assert(xe_bind->obj_offset == 0);
} else if (bo->from_host_ptr) { } else if (bo->from_host_ptr) {
xe_bind->op = XE_VM_BIND_OP_MAP_USERPTR; 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! */ /* userptr and bo_offset are an union! */
if (bo && bo->from_host_ptr) if (bo && bo->from_host_ptr)
xe_bind->userptr = (uintptr_t)bo->map; xe_bind->userptr = (uintptr_t)bo->map;