for (i = 0; i < list->num_entries; ++i)
amdgpu_bo_unref(&list->array[i].robj);
- mutex_destroy(&list->lock);
kvfree(list->array);
kfree_rcu(list, rhead);
}
return -ENOMEM;
/* initialize bo list*/
- mutex_init(&list->lock);
kref_init(&list->refcount);
r = amdgpu_bo_list_set(adev, filp, list, info, num_entries);
if (r) {
if (*result && kref_get_unless_zero(&(*result)->refcount)) {
rcu_read_unlock();
- mutex_lock(&(*result)->lock);
return 0;
}
void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
{
- mutex_unlock(&list->lock);
kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
}
for (i = 0; i < list->num_entries; ++i)
amdgpu_bo_unref(&list->array[i].robj);
- mutex_destroy(&list->lock);
kvfree(list->array);
kfree(list);
}
union drm_amdgpu_bo_list *args = data;
uint32_t handle = args->in.list_handle;
struct drm_amdgpu_bo_list_entry *info = NULL;
- struct amdgpu_bo_list *list;
+ struct amdgpu_bo_list *list, *old;
int r;
r = amdgpu_bo_create_list_entry_array(&args->in, &info);
break;
case AMDGPU_BO_LIST_OP_UPDATE:
- r = amdgpu_bo_list_get(fpriv, handle, &list);
+ r = amdgpu_bo_list_create(adev, filp, info, args->in.bo_number,
+ &list);
if (r)
goto error_free;
- r = amdgpu_bo_list_set(adev, filp, list, info,
- args->in.bo_number);
- amdgpu_bo_list_put(list);
- if (r)
+ mutex_lock(&fpriv->bo_list_lock);
+ old = idr_replace(&fpriv->bo_list_handles, list, handle);
+ mutex_unlock(&fpriv->bo_list_lock);
+
+ if (IS_ERR(old)) {
+ amdgpu_bo_list_put(list);
+ r = PTR_ERR(old);
goto error_free;
+ }
+ amdgpu_bo_list_put(old);
break;
default: