diff options
author | Eric Anholt <eric@anholt.net> | 2015-02-24 10:39:20 +0000 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2015-06-04 14:15:32 -0700 |
commit | 97a9c41ccdb7a7f1b6808583b9c3f6ca7c32ff3d (patch) | |
tree | 091dc788895a8fbfd81a20376eaf374d53601fe9 | |
parent | c963b9937092fb79d79992cb8c7937ee53459bd8 (diff) | |
download | linux-97a9c41ccdb7a7f1b6808583b9c3f6ca7c32ff3d.tar.gz |
drm/vc4: Revert "drm/vc4: Evict user mappings of shaders while they're being executed."
This reverts commit cd95e2a4feb4cf7a5e47da3e320f9fc3336899e4.
This appears to be broken on 3.18 on rpi2, and I haven't figured out
why yet. It causes a system lockup with sometimes an angry RCU
complaint beforehand.
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_bo.c | 107 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_gem.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_validate_shaders.c | 2 |
5 files changed, 3 insertions, 118 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 0cdfdd98b5e5..c39413f6bcbc 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -254,113 +254,6 @@ vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) return drm_gem_prime_export(dev, obj, flags); } - -/* vc4_gem_fault - fault handler for user mappings of objects. - * - * We don't just use the GEM helpers because we have to make sure that - * the user can't touch shader contents while they're being executed. - */ -static int -vc4_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_gem_object *gem_bo = vma->vm_private_data; - struct vc4_bo *bo = to_vc4_bo(gem_bo); - struct drm_device *dev = gem_bo->dev; - pgoff_t page_offset; - unsigned long pfn; - int ret = 0; - - /* We don't use vmf->pgoff since that has the fake offset */ - page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >> - PAGE_SHIFT; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - goto out; - - if (bo->validated_shader) { - ret = vc4_wait_for_seqno(dev, bo->seqno, ~0ull); - if (ret) - goto unlock; - - kfree(bo->validated_shader); - bo->validated_shader = NULL; - } - - pfn = (bo->base.paddr >> PAGE_SHIFT) + page_offset; - - ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn); -unlock: - mutex_unlock(&dev->struct_mutex); -out: - switch (ret) { - case 0: - case -ERESTARTSYS: - case -EINTR: - case -EBUSY: - ret = VM_FAULT_NOPAGE; - break; - case -ENOMEM: - ret = VM_FAULT_OOM; - break; - case -ENOSPC: - case -EFAULT: - ret = VM_FAULT_SIGBUS; - break; - default: - WARN_ONCE(ret, "unhandled error in vc4_gem_fault: %i\n", ret); - ret = VM_FAULT_SIGBUS; - break; - } - - return ret; -} - -const struct vm_operations_struct vc4_vm_ops = { - .fault = vc4_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - -int -vc4_mmap(struct file *filp, struct vm_area_struct *vma) -{ - int ret; - - ret = drm_gem_mmap(filp, vma); - if (ret) - return ret; - - /* Since our objects all come from normal system memory, clear - * PFNMAP that was defaulted by drm_gem_mmap_obj() to indicate - * that they have a "struct page" managing them. - */ - vma->vm_flags &= ~VM_PFNMAP; - - /* Not sure why we need to do this. */ - vma->vm_flags |= VM_MIXEDMAP; - - /* We only do whole-object mappings. */ - vma->vm_pgoff = 0; - - return 0; -} - -/* Removes all user mappings of the object. - * - * This is used to ensure that the user can't modify shaders while the - * GPU is executing them. If the user tries to access these unmapped - * pages, they'll hit a pagefault and end up in vc4_gem_fault(), which - * then can wait for execution to finish. - */ -void -vc4_force_user_unmap(struct drm_gem_object *gem_obj) -{ - struct drm_device *dev = gem_obj->dev; - - drm_vma_node_unmap(&gem_obj->vma_node, dev->anon_inode->i_mapping); -} - int vc4_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 9fbd3b949479..a0fdd1a0d387 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -100,7 +100,7 @@ static const struct file_operations vc4_drm_fops = { .open = drm_open, .release = drm_release, .unlocked_ioctl = drm_ioctl, - .mmap = vc4_mmap, + .mmap = drm_gem_cma_mmap, .poll = drm_poll, .read = drm_read, #ifdef CONFIG_COMPAT @@ -117,7 +117,6 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = { DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), }; - static struct drm_driver vc4_drm_driver = { .driver_features = (DRIVER_MODESET | DRIVER_GEM | @@ -142,7 +141,7 @@ static struct drm_driver vc4_drm_driver = { #endif .gem_free_object = vc4_free_object, - .gem_vm_ops = &vc4_vm_ops, + .gem_vm_ops = &drm_gem_cma_vm_ops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 3226ef432e32..28f9f58c4dd9 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -352,7 +352,6 @@ void vc4_disable_vblank(struct drm_device *dev, int crtc_id); #define wait_for(COND, MS) _wait_for(COND, MS, 1) /* vc4_bo.c */ -extern const struct vm_operations_struct vc4_vm_ops; void vc4_bo_cache_init(struct drm_device *dev); void vc4_free_object(struct drm_gem_object *gem_obj); struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size); @@ -363,8 +362,6 @@ struct drm_gem_object *vc4_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); struct dma_buf *vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags); -int vc4_mmap(struct file *filp, struct vm_area_struct *vma); -void vc4_force_user_unmap(struct drm_gem_object *gem_obj); int vc4_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, @@ -386,8 +383,6 @@ int vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, int vc4_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); void vc4_submit_next_job(struct drm_device *dev); -int vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, - uint64_t timeout_ns); /* vc4_hdmi.c */ void vc4_hdmi_register(void); diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 34036c3f0f50..8843c4cf9948 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -117,7 +117,7 @@ submit_cl(struct drm_device *dev, uint32_t thread, uint32_t start, uint32_t end) barrier(); } -int +static int vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns) { struct vc4_dev *vc4 = to_vc4_dev(dev); diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c index 2b4a4ec64f7a..839d5521cfe5 100644 --- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c +++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c @@ -382,8 +382,6 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) if (shader_bo->validated_shader) return shader_bo->validated_shader; - vc4_force_user_unmap(&shader_obj->base); - /* Our validation relies on nothing modifying the shader * contents after us, so just ban sending us busy BOs. */ |