diff options
Diffstat (limited to 'shared-core/i915_dma.c')
-rw-r--r-- | shared-core/i915_dma.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 1e15e7ce..b1168635 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -213,6 +213,7 @@ static int i915_initialize(struct drm_device * dev, } DRM_DEBUG("Enabled hardware status page\n"); dev->dev_private = (void *)dev_priv; + mutex_init(&dev_priv->cmdbuf_mutex); return 0; } @@ -976,6 +977,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, req->bo_req.flags, req->bo_req.mask, req->bo_req.hint, + 0, &rep.bo_info, &buffers[buf_count]); @@ -1026,8 +1028,6 @@ static int i915_execbuffer(struct drm_device *dev, void *data, } - LOCK_TEST_WITH_RETURN(dev, file_priv); - if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, batch->num_cliprects * sizeof(struct drm_clip_rect))) @@ -1036,11 +1036,30 @@ static int i915_execbuffer(struct drm_device *dev, void *data, if (exec_buf->num_buffers > dev_priv->max_validate_buffers) return -EINVAL; + + ret = drm_bo_read_lock(&dev->bm.bm_lock); + if (ret) + return ret; + + /* + * The cmdbuf_mutex makes sure the validate-submit-fence + * operation is atomic. + */ + + ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex); + if (ret) { + drm_bo_read_unlock(&dev->bm.bm_lock); + return -EAGAIN; + } + num_buffers = exec_buf->num_buffers; buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER); - if (!buffers) + if (!buffers) { + drm_bo_read_unlock(&dev->bm.bm_lock); + mutex_unlock(&dev_priv->cmdbuf_mutex); return -ENOMEM; + } /* validate buffer list + fixup relocations */ ret = i915_validate_buffer_list(file_priv, 0, exec_buf->ops_list, @@ -1088,6 +1107,8 @@ out_err0: out_free: drm_free(buffers, (exec_buf->num_buffers * sizeof(struct drm_buffer_object *)), DRM_MEM_DRIVER); + mutex_unlock(&dev_priv->cmdbuf_mutex); + drm_bo_read_unlock(&dev->bm.bm_lock); return ret; } #endif |