[Intel-gfx] [PATCH 9/9] drm/i915: add bufferless execbuf ioctl

David Woodhouse dwmw2 at infradead.org
Thu Oct 8 03:34:59 PDT 2015


On Fri, 2015-09-04 at 09:59 -0700, Jesse Barnes wrote:
> We just need to pass in an address to execute and some flags, since we
> don't have to worry about buffer relocation or any of the other usual
> stuff.  Returns a fence to be used for synchronization.
> ---
>  drivers/gpu/drm/i915/i915_dma.c            | 140 ++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/i915_drv.h            |   7 ++
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c |   2 +-
>  drivers/gpu/drm/i915/i915_svm.c            |  10 ---
>  drivers/gpu/drm/i915/i915_sync.c           |   4 +-
>  include/uapi/drm/i915_drm.h                |  24 +++++
>  6 files changed, 173 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index b868084..19b463a 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -50,7 +50,8 @@
>  #include 
>  #include 
>  #include 
> -
> +#include 
> +#include "../../../staging/android/sync.h"
>  
>  static int i915_getparam(struct drm_device *dev, void *data,
>  > 	> 	> 	>  struct drm_file *file_priv)
> @@ -1247,6 +1248,132 @@ i915_gem_reject_pin_ioctl(struct drm_device *dev, void *data,
>  > 	> return -ENODEV;
>  }
>  
> +int intel_exec_mm_ioctl(struct drm_device *dev, void *data,
> +> 	> 	> 	> struct drm_file *file)
> +{
> + > 	> struct drm_i915_private *dev_priv = dev->dev_private;
> +> 	> struct drm_i915_exec_mm *exec_mm = data;
> +> 	> struct intel_ringbuffer *ringbuf;
> +> 	> struct intel_engine_cs *ring;
> +> 	> struct intel_context *ctx;
> +> 	> struct drm_i915_gem_request *request;
> +> 	> struct fence *fence;
> +> 	> struct sync_fence *sfence;
> +> 	> u32 ctx_id = exec_mm->ctx_id;
> +> 	> int fd = get_unused_fd_flags(O_CLOEXEC);
> +> 	> int ret = 0;
> +
> +> 	> if (exec_mm->batch_ptr & 3) {
> +> 	> 	> DRM_ERROR("misaligned batch ptr\n");
> +> 	> 	> ret = -ENOEXEC;
> +> 	> 	> goto out;
> +> 	> }
> +
> +> 	> if (!dev_priv->svm.svm_available) {
> +> 	> 	> ret = -ENODEV;
> +> 	> 	> goto out;
> +> 	> }
> +
> +> 	> ret = i915_mutex_lock_interruptible(dev);
> +> 	> if (ret) {
> +> 	> 	> DRM_ERROR("mutex interrupted\n");
> +> 	> 	> goto out;
> +> 	> }
> +
> +> 	> if (file == NULL) {
> +> 	> 	> ret = -EINVAL;
> +> 	> 	> goto out_unlock;
> +> 	> }
> +
> +> 	> ctx = i915_gem_validate_context(dev, file, &dev_priv->ring[RCS],
> +> 	> 	> 	> 	> 	> ctx_id);
> +> 	> if (ctx == NULL) {
> +> 	> 	> ret = -ENOENT;
> +> 	> 	> DRM_ERROR("couldn't get context\n");
> +> 	> 	> goto out_unlock;
> +> 	> }
> +
> +> 	> if (!ctx->is_svm) {
> +> 	> 	> ret = -EINVAL;
> +> 	> 	> DRM_ERROR("context is not SVM enabled\n");
> +> 	> 	> goto out_unlock;
> +> 	> }
> +
> +> 	> i915_gem_context_reference(ctx);
> +
> +> 	> ringbuf = ctx->engine[RCS].ringbuf;
> +> 	> ring = ringbuf->ring;
> +> 	> if (!ring) {
> +> 	> 	> DRM_ERROR("context has no last ring\n");
> +> 	> 	> ret = -EIO;
> +> 	> 	> goto out_unref;
> +> 	> }
> +
> +> 	> if (!ctx->rcs_initialized) {
> +> 	> 	> DRM_DEBUG("ring not ready\n");
> +> 	> 	> ret = -EIO;
> +> 	> 	> goto out_unref;
> +> 	> }
> +
> +> 	> ret = i915_gem_request_alloc(ring, ctx, &request);
> +> 	> if (ret) {
> +> 	> 	> DRM_ERROR("request alloc failed\n");
> +> 	> 	> goto out_unref;
> +> 	> }
> +
> +> 	> ret = i915_gem_request_add_to_client(request, file);
> +> 	> if (ret) {
> +> 	> 	> DRM_ERROR("failed to add request to client\n");
> +> 	> 	> goto out_free_req;
> +> 	> }
> +
> +> 	> fence = i915_fence_create_ring(ring, ctx);
> +> 	> if (!fence) {
> +> 	> 	> ret = -ENOMEM;
> +> 	> 	> DRM_ERROR("fence creation failed\n");
> +> 	> 	> goto out_free_req;
> +> 	> }
> +
> +> 	> sfence = sync_fence_create_dma("svm-execbuf", fence);
> +> 	> if (!sfence) {
> +> 	> 	> ret = -ENOMEM;
> +> 	> 	> DRM_ERROR("sfence creation failed\n");
> +> 	> 	> goto out_free_req;
> +> 	> }
> +
> +> 	> exec_mm->fence = fd;
> +> 	> sync_fence_install(sfence, fd);
> +
> +> 	> ret = ring->emit_flush(request, 0, I915_GEM_GPU_DOMAINS);
> +> 	> if (ret) {
> +> 	> 	> DRM_ERROR("ring flush failed: %d\n", ret);
> +> 	> 	> goto out_free_req;
> +> 	> }
> +
> +> 	> ret = ring->emit_bb_start(request, exec_mm->batch_ptr, 0);
> +> 	> if (ret) {
> +> 	> 	> DRM_ERROR("ring dispatch execbuf failed: %d\n", ret);
> +> 	> 	> goto out_free_req;
> +> 	> }

FWIW naïvely adding a call to 

 __i915_add_request(request, NULL, true);

here in the hope that it would actually do something *useful* rather
than just reserving space in the ring and never using it, causing the
warning in intel_ring_reserved_space_reserve() that I observed next
time we do anything... didn't work. With various and confusing failure
modes, about which I won't go into detail.

I'm going to leave it to the big boys and keep hacking on my backported
version of the IOMMU code to 4.0, where the SVM bits in the i915 driver
*did* work :)

-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5691 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20151008/bd15d442/attachment-0001.bin>


More information about the Intel-gfx mailing list