summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2015-02-24 10:39:20 +0000
committerEric Anholt <eric@anholt.net>2015-06-04 14:15:32 -0700
commit97a9c41ccdb7a7f1b6808583b9c3f6ca7c32ff3d (patch)
tree091dc788895a8fbfd81a20376eaf374d53601fe9
parentc963b9937092fb79d79992cb8c7937ee53459bd8 (diff)
downloadlinux-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.c107
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c5
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h5
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate_shaders.c2
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.
*/