Primarily as a thought experiment, construct an ioctl that allows the user to cancel the associated fence, causing immediate completion if currently executing. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/gem/i915_gem_cancel.c | 57 ++++++++++++++++++++++ drivers/gpu/drm/i915/gem/i915_gem_ioctls.h | 2 + drivers/gpu/drm/i915/i915_drv.c | 1 + include/uapi/drm/i915_drm.h | 8 +++ 5 files changed, 69 insertions(+) create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_cancel.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index f9ef5199b124..86ff6142d2fe 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -129,6 +129,7 @@ i915-y += $(gt-y) # GEM (Graphics Execution Management) code gem-y += \ gem/i915_gem_busy.o \ + gem/i915_gem_cancel.o \ gem/i915_gem_clflush.o \ gem/i915_gem_client_blt.o \ gem/i915_gem_context.o \ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_cancel.c b/drivers/gpu/drm/i915/gem/i915_gem_cancel.c new file mode 100644 index 000000000000..c85dc22fb96d --- /dev/null +++ b/drivers/gpu/drm/i915/gem/i915_gem_cancel.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2020 Intel Corporation + */ + +#include <linux/sync_file.h> + +#include <drm/drm_print.h> +#include <drm/drm_syncobj.h> + +#include "i915_drv.h" +#include "i915_gem_ioctls.h" + +int +i915_gem_cancel_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct drm_i915_gem_cancel *args = data; + struct dma_fence *fence; + int err; + + /* Only supported if we can gracefully cancel a request */ + if (!(to_i915(dev)->caps.scheduler & I915_SCHEDULER_CAP_PREEMPTION)) + return -ENODEV; + + if (args->flags & ~(I915_GEM_CANCEL_SYNCOBJ)) + return -EINVAL; + + if (args->flags & I915_GEM_CANCEL_SYNCOBJ) { + struct drm_syncobj *syncobj; + + syncobj = drm_syncobj_find(file, args->handle); + if (!syncobj) { + DRM_DEBUG("Invalid syncobj handle:%d provided\n", + args->handle); + return -ENOENT; + } + + fence = drm_syncobj_fence_get(syncobj); + drm_syncobj_put(syncobj); + } else { + fence = sync_file_get_fence(args->handle); + if (!fence) { + DRM_DEBUG("Invalid fence fd:%d provided\n", + args->handle); + return -ENOENT; + } + } + + err = -EINVAL; + if (dma_fence_is_i915(fence)) { + i915_request_cancel(to_request(fence), -EINTR); + err = 0; + } + + dma_fence_put(fence); + return err; +} diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h index 87d8b27f426d..6487f9a652e6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h @@ -12,6 +12,8 @@ struct drm_file; int i915_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +int i915_gem_cancel_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); int i915_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file); int i915_gem_execbuffer_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5708e11d917b..de80fbf47b73 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1758,6 +1758,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_QUERY, i915_query_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_VM_CREATE, i915_gem_vm_create_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_VM_DESTROY, i915_gem_vm_destroy_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_CANCEL, i915_gem_cancel_ioctl, DRM_RENDER_ALLOW), }; static const struct drm_driver driver = { diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 6edcb2b6c708..bc1d065cd1e0 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -359,6 +359,7 @@ typedef struct _drm_i915_sarea { #define DRM_I915_QUERY 0x39 #define DRM_I915_GEM_VM_CREATE 0x3a #define DRM_I915_GEM_VM_DESTROY 0x3b +#define DRM_I915_GEM_CANCEL 0x3c /* Must be kept compact -- no holes */ #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) @@ -422,6 +423,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query) #define DRM_IOCTL_I915_GEM_VM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_CREATE, struct drm_i915_gem_vm_control) #define DRM_IOCTL_I915_GEM_VM_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_VM_DESTROY, struct drm_i915_gem_vm_control) +#define DRM_IOCTL_I915_GEM_CANCEL DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CANCEL, struct drm_i915_gem_cancel) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -1569,6 +1571,12 @@ struct drm_i915_gem_wait { __s64 timeout_ns; }; +struct drm_i915_gem_cancel { + __u32 handle; + __u32 flags; +#define I915_GEM_CANCEL_SYNCOBJ (1 << 0) +}; + struct drm_i915_gem_context_create { __u32 ctx_id; /* output: id of new context*/ __u32 pad; -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx