+ xa_unlock(&fpriv->bo_list_handles);
- rcu_read_unlock();
- *result = NULL;
- return -ENOENT;
+ *result = list;
+
+ return list ? 0 : -ENOENT;
}
void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
@@ -219,12 +208,12 @@ int amdgpu_bo_create_list_entry_array(struct
drm_amdgpu_bo_list_in *in,
int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
- struct amdgpu_device *adev = drm_to_adev(dev);
struct amdgpu_fpriv *fpriv = filp->driver_priv;
- union drm_amdgpu_bo_list *args = data;
- uint32_t handle = args->in.list_handle;
+ struct amdgpu_device *adev = drm_to_adev(dev);
struct drm_amdgpu_bo_list_entry *info = NULL;
- struct amdgpu_bo_list *list, *old;
+ struct amdgpu_bo_list *list, *prev, *curr;
+ uint32_t handle = args->in.list_handle;
+ union drm_amdgpu_bo_list *args = data;
int r;
r = amdgpu_bo_create_list_entry_array(&args->in, &info);
@@ -238,19 +227,19 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void
*data,
if (r)
goto error_free;
- mutex_lock(&fpriv->bo_list_lock);
- r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL);
- mutex_unlock(&fpriv->bo_list_lock);
- if (r < 0) {
+ r = xa_alloc(&fpriv->bo_list_handles, &handle, list,
+ xa_limit_32b, GFP_KERNEL);
+ if (r)
goto error_put_list;
- }
- handle = r;
break;
case AMDGPU_BO_LIST_OP_DESTROY:
- amdgpu_bo_list_destroy(fpriv, handle);
+ list = xa_erase(&fpriv->bo_list_handles, handle);
+ if (list)
+ amdgpu_bo_list_put(list);
handle = 0;
+
break;
case AMDGPU_BO_LIST_OP_UPDATE:
@@ -259,16 +248,23 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void
*data,
if (r)
goto error_free;
- mutex_lock(&fpriv->bo_list_lock);
- old = idr_replace(&fpriv->bo_list_handles, list, handle);
- mutex_unlock(&fpriv->bo_list_lock);
+ curr = xa_load(&fpriv->bo_list_handles, handle);
+ if (!curr) {
+ r = -ENOENT;
+ goto error_put_list;
+ }
- if (IS_ERR(old)) {
- r = PTR_ERR(old);
+ prev = xa_cmpxchg(&fpriv->bo_list_handles, handle, curr, list,
+ GFP_KERNEL);
+ if (xa_is_err(prev)) {
+ r = xa_err(prev);
+ goto error_put_list;
+ } else if (prev != curr) {
+ r = -ENOENT;
goto error_put_list;
}
- amdgpu_bo_list_put(old);
+ amdgpu_bo_list_put(curr);
break;
default:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
index 2b5e7c46a39d..0989f1090c63 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
@@ -58,7 +58,7 @@ struct amdgpu_bo_list {
struct amdgpu_bo_list_entry entries[] __counted_by(num_entries);
};
-int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
+int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, u32 id,
struct amdgpu_bo_list **result);
void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 6ee77f431d56..88f104041157 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -1445,8 +1445,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct
drm_file *file_priv)
if (r)
goto error_vm;
- mutex_init(&fpriv->bo_list_lock);
- idr_init_base(&fpriv->bo_list_handles, 1);
+ xa_init_flags(&fpriv->bo_list_handles, XA_FLAGS_ALLOC1);
r = amdgpu_userq_mgr_init(&fpriv->userq_mgr, file_priv, adev);
if (r)
@@ -1492,8 +1491,8 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
struct amdgpu_bo_list *list;
struct amdgpu_bo *pd;
+ unsigned long handle;
u32 pasid;
- int handle;
if (!fpriv)
return;
@@ -1529,11 +1528,9 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
amdgpu_pasid_free_delayed(pd->tbo.base.resv, pasid);
amdgpu_bo_unref(&pd);
- idr_for_each_entry(&fpriv->bo_list_handles, list, handle)
+ xa_for_each(&fpriv->bo_list_handles, handle, list)
amdgpu_bo_list_put(list);
-
- idr_destroy(&fpriv->bo_list_handles);
- mutex_destroy(&fpriv->bo_list_lock);
+ xa_destroy(&fpriv->bo_list_handles);
kfree(fpriv);
file_priv->driver_priv = NULL;