drm/i915: Fix phys pwrite for struct_mutex-less operation
Since commitfe115628d5
("drm/i915: Implement pwrite without struct-mutex") the lowlevel pwrite calls are now called without the protection of struct_mutex, but pwrite_phys was still asserting that it held the struct_mutex and later tried to drop and relock it. Fixes:fe115628d5
("drm/i915: Implement pwrite without struct-mutex") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: <drm-intel-fixes@lists.freedesktop.org> Link: http://patchwork.freedesktop.org/patch/msgid/20170106152240.5793-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
This commit is contained in:
parent
984ff29f74
commit
10466d2a59
|
@ -597,47 +597,21 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
|
||||||
struct drm_i915_gem_pwrite *args,
|
struct drm_i915_gem_pwrite *args,
|
||||||
struct drm_file *file)
|
struct drm_file *file)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = obj->base.dev;
|
|
||||||
void *vaddr = obj->phys_handle->vaddr + args->offset;
|
void *vaddr = obj->phys_handle->vaddr + args->offset;
|
||||||
char __user *user_data = u64_to_user_ptr(args->data_ptr);
|
char __user *user_data = u64_to_user_ptr(args->data_ptr);
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* We manually control the domain here and pretend that it
|
/* We manually control the domain here and pretend that it
|
||||||
* remains coherent i.e. in the GTT domain, like shmem_pwrite.
|
* remains coherent i.e. in the GTT domain, like shmem_pwrite.
|
||||||
*/
|
*/
|
||||||
lockdep_assert_held(&obj->base.dev->struct_mutex);
|
|
||||||
ret = i915_gem_object_wait(obj,
|
|
||||||
I915_WAIT_INTERRUPTIBLE |
|
|
||||||
I915_WAIT_LOCKED |
|
|
||||||
I915_WAIT_ALL,
|
|
||||||
MAX_SCHEDULE_TIMEOUT,
|
|
||||||
to_rps_client(file));
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
intel_fb_obj_invalidate(obj, ORIGIN_CPU);
|
intel_fb_obj_invalidate(obj, ORIGIN_CPU);
|
||||||
if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) {
|
if (copy_from_user(vaddr, user_data, args->size))
|
||||||
unsigned long unwritten;
|
return -EFAULT;
|
||||||
|
|
||||||
/* The physical object once assigned is fixed for the lifetime
|
|
||||||
* of the obj, so we can safely drop the lock and continue
|
|
||||||
* to access vaddr.
|
|
||||||
*/
|
|
||||||
mutex_unlock(&dev->struct_mutex);
|
|
||||||
unwritten = copy_from_user(vaddr, user_data, args->size);
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
|
||||||
if (unwritten) {
|
|
||||||
ret = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drm_clflush_virt_range(vaddr, args->size);
|
drm_clflush_virt_range(vaddr, args->size);
|
||||||
i915_gem_chipset_flush(to_i915(dev));
|
i915_gem_chipset_flush(to_i915(obj->base.dev));
|
||||||
|
|
||||||
out:
|
|
||||||
intel_fb_obj_flush(obj, false, ORIGIN_CPU);
|
intel_fb_obj_flush(obj, false, ORIGIN_CPU);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *i915_gem_object_alloc(struct drm_i915_private *dev_priv)
|
void *i915_gem_object_alloc(struct drm_i915_private *dev_priv)
|
||||||
|
|
Loading…
Reference in New Issue