[PATCH 4/4] drm/amdgpu: Optimize mutex usage
Christian König
deathsimple at vodafone.de
Mon Jun 12 22:54:32 UTC 2017
Am 12.06.2017 um 22:31 schrieb Alex Xie:
> Use rw_semaphore instead of mutex for bo_lists.
>
> In original function amdgpu_bo_list_get, the waiting
> for result->lock can be quite long while mutex
> bo_list_lock was holding. It can make other tasks
> waiting for bo_list_lock for long period too.
> Change bo_list_lock to rw_semaphore can avoid most of
> such long waiting.
>
> Secondly, this patch allows several tasks(readers of idr)
> to proceed at the same time.
>
> Signed-off-by: Alex Xie <AlexBin.Xie at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 ++-
> drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 14 +++++++-------
> drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 3 +--
> 3 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 063fc73..bfc40d7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -35,6 +35,7 @@
> #include <linux/rbtree.h>
> #include <linux/hashtable.h>
> #include <linux/dma-fence.h>
> +#include <linux/rwsem.h>
>
> #include <ttm/ttm_bo_api.h>
> #include <ttm/ttm_bo_driver.h>
> @@ -859,7 +860,7 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
> struct amdgpu_fpriv {
> struct amdgpu_vm vm;
> struct amdgpu_bo_va *prt_va;
> - struct mutex bo_list_lock;
> + struct rw_semaphore bo_list_lock;
> struct idr bo_list_handles;
> struct amdgpu_ctx_mgr ctx_mgr;
> u32 vram_lost_counter;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> index 4363f28..bfe736e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> @@ -45,10 +45,10 @@ static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv,
> if (!*result)
> return -ENOMEM;
>
> - mutex_lock(&fpriv->bo_list_lock);
> + down_read(&fpriv->bo_list_lock);
> r = idr_alloc(&fpriv->bo_list_handles, *result,
> 1, 0, GFP_KERNEL);
> - mutex_unlock(&fpriv->bo_list_lock);
> + up_read(&fpriv->bo_list_lock);
The protection here is incorrect, you need to take the write side here
as well.
>
> if (r < 0) {
> kfree(*result);
> @@ -67,17 +67,17 @@ static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
> {
> struct amdgpu_bo_list *list;
>
> - mutex_lock(&fpriv->bo_list_lock);
> + down_write(&fpriv->bo_list_lock);
> list = idr_remove(&fpriv->bo_list_handles, id);
> if (list) {
> /* Another user may have a reference to this list still */
> mutex_lock(&list->lock);
> mutex_unlock(&list->lock);
> - mutex_unlock(&fpriv->bo_list_lock);
> + up_write(&fpriv->bo_list_lock);
> amdgpu_bo_list_free(list);
> }
> else {
> - mutex_unlock(&fpriv->bo_list_lock);
> + up_write(&fpriv->bo_list_lock);
> }
> }
>
> @@ -173,11 +173,11 @@ amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id)
> {
> struct amdgpu_bo_list *result;
>
> - mutex_lock(&fpriv->bo_list_lock);
> + down_read(&fpriv->bo_list_lock);
> result = idr_find(&fpriv->bo_list_handles, id);
> if (result)
> mutex_lock(&result->lock);
> - mutex_unlock(&fpriv->bo_list_lock);
> + up_read(&fpriv->bo_list_lock);
Actually rw_semaphores are a bit less efficient than mutexes and the
contention on this is practically not existent since at least the open
source stack makes all BO list operations from a single thread.
So I'm not sure if that is actually more efficient.
Christian.
> return result;
> }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index f68ced6..c4cba81 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -841,7 +841,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
> goto out_suspend;
> }
>
> - mutex_init(&fpriv->bo_list_lock);
> + init_rwsem(&fpriv->bo_list_lock);
> idr_init(&fpriv->bo_list_handles);
>
> amdgpu_ctx_mgr_init(&fpriv->ctx_mgr);
> @@ -900,7 +900,6 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
> amdgpu_bo_list_free(list);
>
> idr_destroy(&fpriv->bo_list_handles);
> - mutex_destroy(&fpriv->bo_list_lock);
>
> kfree(fpriv);
> file_priv->driver_priv = NULL;
More information about the amd-gfx
mailing list