提交 258a5ede 编写于 作者: C Chris Wilson

drm/i915: Do a nonblocking wait first in pread/pwrite

If we try and read or write to an active request, we first must wait
upon the GPU completing that request. Let's do that without holding the
mutex (and so allow someone else to access the GPU whilst we wait). Upon
completion, we will acquire the mutex and only then start the operation
(i.e. we do not rely on state from before the initial wait).

v2: Repaint the goto labels
v3: Move the tracepoints back to the start of the ioctls
Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: NJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470388464-28458-11-git-send-email-chris@chris-wilson.co.uk
上级 3b4e896f
...@@ -956,25 +956,27 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, ...@@ -956,25 +956,27 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
args->size)) args->size))
return -EFAULT; return -EFAULT;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
return ret;
obj = i915_gem_object_lookup(file, args->handle); obj = i915_gem_object_lookup(file, args->handle);
if (!obj) { if (!obj)
ret = -ENOENT; return -ENOENT;
goto unlock;
}
/* Bounds check source. */ /* Bounds check source. */
if (args->offset > obj->base.size || if (args->offset > obj->base.size ||
args->size > obj->base.size - args->offset) { args->size > obj->base.size - args->offset) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto err;
} }
trace_i915_gem_object_pread(obj, args->offset, args->size); trace_i915_gem_object_pread(obj, args->offset, args->size);
ret = __unsafe_wait_rendering(obj, to_rps_client(file), true);
if (ret)
goto err;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
goto err;
ret = i915_gem_shmem_pread(dev, obj, args, file); ret = i915_gem_shmem_pread(dev, obj, args, file);
/* pread for non shmem backed objects */ /* pread for non shmem backed objects */
...@@ -985,10 +987,13 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, ...@@ -985,10 +987,13 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
intel_runtime_pm_put(to_i915(dev)); intel_runtime_pm_put(to_i915(dev));
} }
out:
i915_gem_object_put(obj); i915_gem_object_put(obj);
unlock:
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return ret;
err:
i915_gem_object_put_unlocked(obj);
return ret; return ret;
} }
...@@ -1374,27 +1379,29 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, ...@@ -1374,27 +1379,29 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
return -EFAULT; return -EFAULT;
} }
intel_runtime_pm_get(dev_priv);
ret = i915_mutex_lock_interruptible(dev);
if (ret)
goto put_rpm;
obj = i915_gem_object_lookup(file, args->handle); obj = i915_gem_object_lookup(file, args->handle);
if (!obj) { if (!obj)
ret = -ENOENT; return -ENOENT;
goto unlock;
}
/* Bounds check destination. */ /* Bounds check destination. */
if (args->offset > obj->base.size || if (args->offset > obj->base.size ||
args->size > obj->base.size - args->offset) { args->size > obj->base.size - args->offset) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto err;
} }
trace_i915_gem_object_pwrite(obj, args->offset, args->size); trace_i915_gem_object_pwrite(obj, args->offset, args->size);
ret = __unsafe_wait_rendering(obj, to_rps_client(file), false);
if (ret)
goto err;
intel_runtime_pm_get(dev_priv);
ret = i915_mutex_lock_interruptible(dev);
if (ret)
goto err_rpm;
ret = -EFAULT; ret = -EFAULT;
/* We can only do the GTT pwrite on untiled buffers, as otherwise /* We can only do the GTT pwrite on untiled buffers, as otherwise
* it would end up going through the fenced access, and we'll get * it would end up going through the fenced access, and we'll get
...@@ -1419,14 +1426,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, ...@@ -1419,14 +1426,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
ret = -ENODEV; ret = -ENODEV;
} }
out:
i915_gem_object_put(obj); i915_gem_object_put(obj);
unlock:
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
put_rpm:
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
return ret; return ret;
err_rpm:
intel_runtime_pm_put(dev_priv);
err:
i915_gem_object_put_unlocked(obj);
return ret;
} }
static enum fb_op_origin static enum fb_op_origin
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册