tu: Allow being preempted on a7xx

This is only tested on a7xx so far, although it should work on a6xx too.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30544>
This commit is contained in:
Connor Abbott 2024-10-08 14:47:31 -04:00 committed by Marge Bot
parent 3631f9ad62
commit 1d2b479a3b
4 changed files with 54 additions and 3 deletions

View file

@ -124,6 +124,8 @@ struct tu_physical_device
bool has_cached_non_coherent_memory;
uintptr_t level1_dcache_size;
bool has_preemption;
struct {
uint32_t type_count;
VkMemoryPropertyFlags types[VK_MAX_MEMORY_TYPES];

View file

@ -121,6 +121,24 @@ tu_drm_get_va_prop(const struct tu_physical_device *dev,
return 0;
}
static bool
tu_drm_has_preemption(const struct tu_physical_device *dev)
{
struct drm_msm_submitqueue req = {
.flags = MSM_SUBMITQUEUE_ALLOW_PREEMPT,
.prio = dev->submitqueue_priority_count / 2,
};
int ret = drmCommandWriteRead(dev->local_fd,
DRM_MSM_SUBMITQUEUE_NEW, &req, sizeof(req));
if (ret)
return false;
drmCommandWrite(dev->local_fd, DRM_MSM_SUBMITQUEUE_CLOSE, &req.id,
sizeof(req.id));
return true;
}
static uint32_t
tu_drm_get_priorities(const struct tu_physical_device *dev)
{
@ -214,7 +232,9 @@ msm_submitqueue_new(struct tu_device *dev,
assert(priority >= 0 &&
priority < dev->physical_device->submitqueue_priority_count);
struct drm_msm_submitqueue req = {
.flags = 0,
.flags = dev->physical_device->info->chip >= 7 &&
dev->physical_device->has_preemption ?
MSM_SUBMITQUEUE_ALLOW_PREEMPT : 0,
.prio = priority,
};
@ -1245,6 +1265,8 @@ tu_knl_drm_msm_load(struct tu_instance *instance,
device->has_set_iova = !tu_drm_get_va_prop(device, &device->va_start,
&device->va_size);
device->has_preemption = tu_drm_has_preemption(device);
/* Even if kernel is new enough, the GPU itself may not support it. */
device->has_cached_coherent_memory =
(device->msm_minor_version >= 8) &&

View file

@ -310,11 +310,13 @@ virtio_submitqueue_new(struct tu_device *dev,
priority < dev->physical_device->submitqueue_priority_count);
struct drm_msm_submitqueue req = {
.flags = 0,
.flags = dev->physical_device->info->chip >= 7 &&
dev->physical_device->has_preemption ?
MSM_SUBMITQUEUE_ALLOW_PREEMPT : 0,
.prio = priority,
};
int ret = virtio_simple_ioctl(dev, DRM_IOCTL_MSM_SUBMITQUEUE_NEW, &req);
int ret = virtio_simple_ioctl(dev->vdev->vdrm, DRM_IOCTL_MSM_SUBMITQUEUE_NEW, &req);
if (ret)
return ret;
@ -328,6 +330,22 @@ virtio_submitqueue_close(struct tu_device *dev, uint32_t queue_id)
virtio_simple_ioctl(dev->vdev->vdrm, DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE, &queue_id);
}
static bool
virtio_has_preemption(struct vdrm_device *vdrm)
{
struct drm_msm_submitqueue req = {
.flags = MSM_SUBMITQUEUE_ALLOW_PREEMPT,
.prio = vdrm->caps.u.msm.priorities / 2,
};
int ret = virtio_simple_ioctl(vdrm, DRM_IOCTL_MSM_SUBMITQUEUE_NEW, &req);
if (ret)
return false;
virtio_simple_ioctl(vdrm, DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE, &req.id);
return true;
}
static VkResult
tu_wait_fence(struct tu_device *dev,
uint32_t queue_id,
@ -1312,6 +1330,11 @@ tu_knl_drm_virtio_load(struct tu_instance *instance,
caps = vdrm->caps;
/* TODO add something to virgl_renderer_capset_drm to avoid round-trip to
* host if virglrenderer is new enough.
*/
bool has_preemption = virtio_has_preemption(vdrm);
vdrm_device_close(vdrm);
mesa_logd("wire_format_version: %u", caps.wire_format_version);
@ -1367,6 +1390,7 @@ tu_knl_drm_virtio_load(struct tu_instance *instance,
device->va_start = caps.u.msm.va_start;
device->va_size = caps.u.msm.va_size;
device->has_set_iova = true;
device->has_preemption = has_preemption;
device->gmem_size = debug_get_num_option("TU_GMEM", device->gmem_size);

View file

@ -1596,6 +1596,9 @@ tu_knl_kgsl_load(struct tu_instance *instance, int fd)
fd, KGSL_MEMFLAGS_IOCOHERENT |
(KGSL_CACHEMODE_WRITEBACK << KGSL_CACHEMODE_SHIFT));
/* preemption is always supported on kgsl */
device->has_preemption = true;
instance->knl = &kgsl_knl_funcs;
result = tu_physical_device_init(device, instance);