Daniel recently pointed out that vc4 has test in it's vmap code that cannot really fail. [1] I took the opportunity to cleanup vc'4 vmap and mmap implementations.
The patches got smoke-tested by running fbdev and Xorg on an RPi3.
[1] https://lore.kernel.org/dri-devel/20201211094000.GK401619@phenom.ffwll.local...
Thomas Zimmermann (3): drm/vc4: Use drm_gem_cma_vmap() directly drm/vc4: Make several BO functions static drm/vc4: Move mmap implementation into GEM object function
drivers/gpu/drm/vc4/vc4_bo.c | 97 +++++++---------------------------- drivers/gpu/drm/vc4/vc4_drv.c | 14 +---- drivers/gpu/drm/vc4/vc4_drv.h | 5 -- 3 files changed, 21 insertions(+), 95 deletions(-)
-- 2.29.2
Validated shaders cannot be exported. There's no need for testing this in the BO's vmap implementation. Call drm_gem_cma_vmap() directly instead.
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de --- drivers/gpu/drm/vc4/vc4_bo.c | 14 +------------- drivers/gpu/drm/vc4/vc4_drv.h | 1 - 2 files changed, 1 insertion(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index dc316cb79e00..eff12be616b0 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -386,7 +386,7 @@ static const struct drm_gem_object_funcs vc4_gem_object_funcs = { .free = vc4_free_object, .export = vc4_prime_export, .get_sg_table = drm_gem_cma_get_sg_table, - .vmap = vc4_prime_vmap, + .vmap = drm_gem_cma_vmap, .vm_ops = &vc4_vm_ops, };
@@ -785,18 +785,6 @@ int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) return drm_gem_prime_mmap(obj, vma); }
-int vc4_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) -{ - struct vc4_bo *bo = to_vc4_bo(obj); - - if (bo->validated_shader) { - DRM_DEBUG("mmaping of shader BOs not allowed.\n"); - return -EINVAL; - } - - return drm_gem_cma_vmap(obj, map); -} - struct drm_gem_object * vc4_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 051ad4e31e52..61848c6f85ad 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -808,7 +808,6 @@ int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); struct drm_gem_object *vc4_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt); -int vc4_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); int vc4_bo_cache_init(struct drm_device *dev); int vc4_bo_inc_usecnt(struct vc4_bo *bo); void vc4_bo_dec_usecnt(struct vc4_bo *bo);
Rearrange the code to make BO functions static. This will also help with streamlining the BO's mmap implementation.
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de --- drivers/gpu/drm/vc4/vc4_bo.c | 34 +++++++++++++++++----------------- drivers/gpu/drm/vc4/vc4_drv.h | 2 -- 2 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index eff12be616b0..f9b42ff098e3 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -21,7 +21,7 @@ #include "vc4_drv.h" #include "uapi/drm/vc4_drm.h"
-static vm_fault_t vc4_fault(struct vm_fault *vmf); +static const struct drm_gem_object_funcs vc4_gem_object_funcs;
static const char * const bo_type_names[] = { "kernel", @@ -376,20 +376,6 @@ static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev, return bo; }
-static const struct vm_operations_struct vc4_vm_ops = { - .fault = vc4_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - -static const struct drm_gem_object_funcs vc4_gem_object_funcs = { - .free = vc4_free_object, - .export = vc4_prime_export, - .get_sg_table = drm_gem_cma_get_sg_table, - .vmap = drm_gem_cma_vmap, - .vm_ops = &vc4_vm_ops, -}; - /** * vc4_create_object - Implementation of driver->gem_create_object. * @dev: DRM device @@ -538,7 +524,7 @@ static void vc4_bo_cache_free_old(struct drm_device *dev) /* Called on the last userspace/kernel unreference of the BO. Returns * it to the BO cache if possible, otherwise frees it. */ -void vc4_free_object(struct drm_gem_object *gem_bo) +static void vc4_free_object(struct drm_gem_object *gem_bo) { struct drm_device *dev = gem_bo->dev; struct vc4_dev *vc4 = to_vc4_dev(dev); @@ -673,7 +659,7 @@ static void vc4_bo_cache_time_timer(struct timer_list *t) schedule_work(&vc4->bo_cache.time_work); }
-struct dma_buf * vc4_prime_export(struct drm_gem_object *obj, int flags) +static struct dma_buf *vc4_prime_export(struct drm_gem_object *obj, int flags) { struct vc4_bo *bo = to_vc4_bo(obj); struct dma_buf *dmabuf; @@ -785,6 +771,20 @@ int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) return drm_gem_prime_mmap(obj, vma); }
+static const struct vm_operations_struct vc4_vm_ops = { + .fault = vc4_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct drm_gem_object_funcs vc4_gem_object_funcs = { + .free = vc4_free_object, + .export = vc4_prime_export, + .get_sg_table = drm_gem_cma_get_sg_table, + .vmap = drm_gem_cma_vmap, + .vm_ops = &vc4_vm_ops, +}; + struct drm_gem_object * vc4_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 61848c6f85ad..a3d8d87fe355 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -782,13 +782,11 @@ struct vc4_validated_shader_info {
/* vc4_bo.c */ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size); -void vc4_free_object(struct drm_gem_object *gem_obj); struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size, bool from_cache, enum vc4_kernel_bo_type type); int vc4_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); -struct dma_buf *vc4_prime_export(struct drm_gem_object *obj, int flags); int vc4_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
Moving vc4's mmap code from vc4_mmap() into a GEM object function allows for the use drm_gem_mmap() and drm_gem_prime_mmap(). The content of vc4_drm_fpos can then be generated by DEFINE_DRM_GEM_FOPS().
The actual mmap implementation is just a check if the BO is a validated shader plus the default CMA mmap code.
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de --- drivers/gpu/drm/vc4/vc4_bo.c | 55 +++-------------------------------- drivers/gpu/drm/vc4/vc4_drv.c | 14 ++------- drivers/gpu/drm/vc4/vc4_drv.h | 2 -- 3 files changed, 6 insertions(+), 65 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index f9b42ff098e3..28e48ef2d295 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -704,19 +704,9 @@ static vm_fault_t vc4_fault(struct vm_fault *vmf) return VM_FAULT_SIGBUS; }
-int vc4_mmap(struct file *filp, struct vm_area_struct *vma) +static int vc4_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) { - struct drm_gem_object *gem_obj; - unsigned long vm_pgoff; - struct vc4_bo *bo; - int ret; - - ret = drm_gem_mmap(filp, vma); - if (ret) - return ret; - - gem_obj = vma->vm_private_data; - bo = to_vc4_bo(gem_obj); + struct vc4_bo *bo = to_vc4_bo(obj);
if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { DRM_DEBUG("mmaping of shader BOs for writing not allowed.\n"); @@ -730,45 +720,7 @@ int vc4_mmap(struct file *filp, struct vm_area_struct *vma) return -EINVAL; }
- /* - * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the - * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map - * the whole buffer. - */ - vma->vm_flags &= ~VM_PFNMAP; - - /* This ->vm_pgoff dance is needed to make all parties happy: - * - dma_mmap_wc() uses ->vm_pgoff as an offset within the allocated - * mem-region, hence the need to set it to zero (the value set by - * the DRM core is a virtual offset encoding the GEM object-id) - * - the mmap() core logic needs ->vm_pgoff to be restored to its - * initial value before returning from this function because it - * encodes the offset of this GEM in the dev->anon_inode pseudo-file - * and this information will be used when we invalidate userspace - * mappings with drm_vma_node_unmap() (called from vc4_gem_purge()). - */ - vm_pgoff = vma->vm_pgoff; - vma->vm_pgoff = 0; - ret = dma_mmap_wc(bo->base.base.dev->dev, vma, bo->base.vaddr, - bo->base.paddr, vma->vm_end - vma->vm_start); - vma->vm_pgoff = vm_pgoff; - - if (ret) - drm_gem_vm_close(vma); - - return ret; -} - -int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) -{ - struct vc4_bo *bo = to_vc4_bo(obj); - - if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { - DRM_DEBUG("mmaping of shader BOs for writing not allowed.\n"); - return -EINVAL; - } - - return drm_gem_prime_mmap(obj, vma); + return drm_gem_cma_mmap(obj, vma); }
static const struct vm_operations_struct vc4_vm_ops = { @@ -782,6 +734,7 @@ static const struct drm_gem_object_funcs vc4_gem_object_funcs = { .export = vc4_prime_export, .get_sg_table = drm_gem_cma_get_sg_table, .vmap = drm_gem_cma_vmap, + .mmap = vc4_gem_object_mmap, .vm_ops = &vc4_vm_ops, };
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 2cd97a39c286..d9b3bba7f2b7 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -140,17 +140,7 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file) kfree(vc4file); }
-static const struct file_operations vc4_drm_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = vc4_mmap, - .poll = drm_poll, - .read = drm_read, - .compat_ioctl = drm_compat_ioctl, - .llseek = noop_llseek, -}; +DEFINE_DRM_GEM_FOPS(vc4_drm_fops);
static const struct drm_ioctl_desc vc4_drm_ioctls[] = { DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, DRM_RENDER_ALLOW), @@ -193,7 +183,7 @@ static struct drm_driver vc4_drm_driver = { .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import_sg_table = vc4_prime_import_sg_table, - .gem_prime_mmap = vc4_prime_mmap, + .gem_prime_mmap = drm_gem_prime_mmap,
.dumb_create = vc4_dumb_create,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index a3d8d87fe355..0d9c0ecc4769 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -801,8 +801,6 @@ int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int vc4_label_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -int vc4_mmap(struct file *filp, struct vm_area_struct *vma); -int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); struct drm_gem_object *vc4_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt);
Hi!
Thanks for the series
On Fri, Jan 08, 2021 at 03:08:05PM +0100, Thomas Zimmermann wrote:
Daniel recently pointed out that vc4 has test in it's vmap code that cannot really fail. [1] I took the opportunity to cleanup vc'4 vmap and mmap implementations.
The patches got smoke-tested by running fbdev and Xorg on an RPi3.
[1] https://lore.kernel.org/dri-devel/20201211094000.GK401619@phenom.ffwll.local...
Acked-by: Maxime Ripard mripard@kernel.org
Maxime
dri-devel@lists.freedesktop.org