Acquire the GTT mutex in psb_gtt_{insert,remove}_pages(). Remove locking from callers. Also remove the GTT locking around the resume code. Resume does not run concurrently with other GTT operations. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/gpu/drm/gma500/gem.c | 11 ++--------- drivers/gpu/drm/gma500/gtt.c | 24 +++++++++++------------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index 026ce11f7460..2f44535f58e7 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c @@ -35,15 +35,13 @@ int psb_gem_pin(struct psb_gem_object *pobj) if (drm_WARN_ONCE(dev, ret, "dma_resv_lock() failed, ret=%d\n", ret)) return ret; - mutex_lock(&dev_priv->gtt_mutex); - if (pobj->in_gart || pobj->stolen) goto out; /* already mapped */ pages = drm_gem_get_pages(obj); if (IS_ERR(pages)) { ret = PTR_ERR(pages); - goto err_mutex_unlock; + goto err_dma_resv_unlock; } npages = obj->size / PAGE_SIZE; @@ -59,13 +57,11 @@ int psb_gem_pin(struct psb_gem_object *pobj) out: ++pobj->in_gart; - mutex_unlock(&dev_priv->gtt_mutex); dma_resv_unlock(obj->resv); return 0; -err_mutex_unlock: - mutex_unlock(&dev_priv->gtt_mutex); +err_dma_resv_unlock: dma_resv_unlock(obj->resv); return ret; } @@ -83,8 +79,6 @@ void psb_gem_unpin(struct psb_gem_object *pobj) if (drm_WARN_ONCE(dev, ret, "dma_resv_lock() failed, ret=%d\n", ret)) return; - mutex_lock(&dev_priv->gtt_mutex); - WARN_ON(!pobj->in_gart); --pobj->in_gart; @@ -105,7 +99,6 @@ void psb_gem_unpin(struct psb_gem_object *pobj) pobj->pages = NULL; out: - mutex_unlock(&dev_priv->gtt_mutex); dma_resv_unlock(obj->resv); } diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 309ffe921bfd..4202e88e5f84 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -74,11 +74,7 @@ static u32 __iomem *psb_gtt_entry(struct drm_psb_private *pdev, const struct res return pdev->gtt_map + (offset >> PAGE_SHIFT); } -/* - * Take our preallocated GTT range and insert the GEM object into - * the GTT. This is protected via the gtt mutex which the caller - * must hold. - */ +/* Acquires GTT mutex internally. */ void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *res, struct page **pages) { @@ -86,6 +82,8 @@ void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *r u32 __iomem *gtt_slot; u32 pte; + mutex_lock(&pdev->gtt_mutex); + /* Write our page entries into the GTT itself */ npages = resource_size(res) >> PAGE_SHIFT; @@ -98,19 +96,19 @@ void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *r /* Make sure all the entries are set before we return */ ioread32(gtt_slot - 1); + + mutex_unlock(&pdev->gtt_mutex); } -/* - * Remove a preallocated GTT range from the GTT. Overwrite all the - * page table entries with the dummy page. This is protected via the gtt - * mutex which the caller must hold. - */ +/* Acquires GTT mutex internally. */ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *res) { resource_size_t npages, i; u32 __iomem *gtt_slot; u32 pte; + mutex_lock(&pdev->gtt_mutex); + /* Install scratch page for the resource */ pte = psb_gtt_mask_pte(page_to_pfn(pdev->scratch_page), PSB_MMU_CACHED_MEMORY); @@ -123,6 +121,8 @@ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *r /* Make sure all the entries are set before we return */ ioread32(gtt_slot - 1); + + mutex_unlock(&pdev->gtt_mutex); } static void psb_gtt_alloc(struct drm_device *dev) @@ -306,8 +306,6 @@ int psb_gtt_restore(struct drm_device *dev) struct psb_gem_object *pobj; unsigned int restored = 0, total = 0, size = 0; - /* On resume, the gtt_mutex is already initialized */ - mutex_lock(&dev_priv->gtt_mutex); psb_gtt_init(dev, 1); while (r != NULL) { @@ -325,7 +323,7 @@ int psb_gtt_restore(struct drm_device *dev) r = r->sibling; total++; } - mutex_unlock(&dev_priv->gtt_mutex); + DRM_DEBUG_DRIVER("Restored %u of %u gtt ranges (%u KB)", restored, total, (size / 1024)); -- 2.35.1