From aa8c85affe3facd3842c8912186623415931cc72 Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Sun, 5 Feb 2023 21:51:24 +0900 Subject: drm/shmem-helper: Fix locking for drm_gem_shmem_get_pages_sgt() Other functions touching shmem->sgt take the pages lock, so do that here too. drm_gem_shmem_get_pages() & co take the same lock, so move to the _locked() variants to avoid recursive locking. Discovered while auditing locking to write the Rust abstractions. Fixes: 2194a63a818d ("drm: Add library for shmem backed GEM objects") Fixes: 4fa3d66f132b ("drm/shmem: Do dma_unmap_sg before purging pages") Signed-off-by: Asahi Lina Reviewed-by: Javier Martinez Canillas Signed-off-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230205125124.2260-1-lina@asahilina.net --- drivers/gpu/drm/drm_gem_shmem_helper.c | 54 +++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'drivers/gpu/drm/drm_gem_shmem_helper.c') diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index 4b828ea7119c..259176d78f3b 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -678,23 +678,7 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) } EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table); -/** - * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a - * scatter/gather table for a shmem GEM object. - * @shmem: shmem GEM object - * - * This function returns a scatter/gather table suitable for driver usage. If - * the sg table doesn't exist, the pages are pinned, dma-mapped, and a sg - * table created. - * - * This is the main function for drivers to get at backing storage, and it hides - * and difference between dma-buf imported and natively allocated objects. - * drm_gem_shmem_get_sg_table() should not be directly called by drivers. - * - * Returns: - * A pointer to the scatter/gather table of pinned pages or errno on failure. - */ -struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem) +static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem) { struct drm_gem_object *obj = &shmem->base; int ret; @@ -705,7 +689,7 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem) WARN_ON(obj->import_attach); - ret = drm_gem_shmem_get_pages(shmem); + ret = drm_gem_shmem_get_pages_locked(shmem); if (ret) return ERR_PTR(ret); @@ -727,10 +711,40 @@ err_free_sgt: sg_free_table(sgt); kfree(sgt); err_put_pages: - drm_gem_shmem_put_pages(shmem); + drm_gem_shmem_put_pages_locked(shmem); return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages_sgt); + +/** + * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a + * scatter/gather table for a shmem GEM object. + * @shmem: shmem GEM object + * + * This function returns a scatter/gather table suitable for driver usage. If + * the sg table doesn't exist, the pages are pinned, dma-mapped, and a sg + * table created. + * + * This is the main function for drivers to get at backing storage, and it hides + * and difference between dma-buf imported and natively allocated objects. + * drm_gem_shmem_get_sg_table() should not be directly called by drivers. + * + * Returns: + * A pointer to the scatter/gather table of pinned pages or errno on failure. + */ +struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem) +{ + int ret; + struct sg_table *sgt; + + ret = mutex_lock_interruptible(&shmem->pages_lock); + if (ret) + return ERR_PTR(ret); + sgt = drm_gem_shmem_get_pages_sgt_locked(shmem); + mutex_unlock(&shmem->pages_lock); + + return sgt; +} +EXPORT_SYMBOL(drm_gem_shmem_get_pages_sgt); /** * drm_gem_shmem_prime_import_sg_table - Produce a shmem GEM object from -- cgit v1.2.3