@@ -238,9 +238,8 @@ struct qxl_device {
uint64_t va_slot_mask;
spinlock_t release_lock;
- struct idr release_idr;
+ struct xarray releases;
uint32_t release_seqno;
- spinlock_t release_idr_lock;
struct mutex async_io_mutex;
unsigned int last_sent_io_cmd;
@@ -247,8 +247,7 @@ int qxl_device_init(struct qxl_device *qdev,
goto release_ring_free;
}
- idr_init(&qdev->release_idr);
- spin_lock_init(&qdev->release_idr_lock);
+ xa_init_flags(&qdev->releases, XA_FLAGS_ALLOC1);
spin_lock_init(&qdev->release_lock);
idr_init(&qdev->surf_id_idr);
@@ -121,7 +121,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type,
struct qxl_release **ret)
{
struct qxl_release *release;
- int handle;
+ int err;
size_t size = sizeof(*release);
release = kmalloc(size, GFP_KERNEL);
@@ -135,21 +135,19 @@ qxl_release_alloc(struct qxl_device *qdev, int type,
release->surface_release_id = 0;
INIT_LIST_HEAD(&release->bos);
- idr_preload(GFP_KERNEL);
- spin_lock(&qdev->release_idr_lock);
- handle = idr_alloc(&qdev->release_idr, release, 1, 0, GFP_NOWAIT);
+ xa_lock(&qdev->releases);
+ err = __xa_alloc(&qdev->releases, &release->id, release, xa_limit_31b,
+ GFP_KERNEL);
release->base.seqno = ++qdev->release_seqno;
- spin_unlock(&qdev->release_idr_lock);
- idr_preload_end();
- if (handle < 0) {
+ xa_unlock(&qdev->releases);
+ if (err < 0) {
kfree(release);
*ret = NULL;
- return handle;
+ return err;
}
*ret = release;
- DRM_DEBUG_DRIVER("allocated release %d\n", handle);
- release->id = handle;
- return handle;
+ DRM_DEBUG_DRIVER("allocated release %d\n", release->id);
+ return release->id;
}
static void
@@ -178,9 +176,7 @@ qxl_release_free(struct qxl_device *qdev,
if (release->surface_release_id)
qxl_surface_id_dealloc(qdev, release->surface_release_id);
- spin_lock(&qdev->release_idr_lock);
- idr_remove(&qdev->release_idr, release->id);
- spin_unlock(&qdev->release_idr_lock);
+ xa_erase(&qdev->releases, release->id);
if (release->base.ops) {
WARN_ON(list_empty(&release->bos));
@@ -288,14 +284,14 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
struct qxl_release **release)
{
if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) {
- int idr_ret;
+ int id;
struct qxl_bo *bo;
union qxl_release_info *info;
/* stash the release after the create command */
- idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
- if (idr_ret < 0)
- return idr_ret;
+ id = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
+ if (id < 0)
+ return id;
bo = create_rel->release_bo;
(*release)->release_bo = bo;
@@ -304,7 +300,7 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
qxl_release_list_add(*release, bo);
info = qxl_release_map(qdev, *release);
- info->id = idr_ret;
+ info->id = id;
qxl_release_unmap(qdev, *release, info);
return 0;
}
@@ -318,7 +314,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
struct qxl_bo **rbo)
{
struct qxl_bo *bo;
- int idr_ret;
+ int id;
int ret = 0;
union qxl_release_info *info;
int cur_idx;
@@ -334,11 +330,11 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
return -EINVAL;
}
- idr_ret = qxl_release_alloc(qdev, type, release);
- if (idr_ret < 0) {
+ id = qxl_release_alloc(qdev, type, release);
+ if (id < 0) {
if (rbo)
*rbo = NULL;
- return idr_ret;
+ return id;
}
mutex_lock(&qdev->release_mutex);
@@ -375,7 +371,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
}
info = qxl_release_map(qdev, *release);
- info->id = idr_ret;
+ info->id = id;
qxl_release_unmap(qdev, *release, info);
return ret;
@@ -386,13 +382,9 @@ struct qxl_release *qxl_release_from_id_locked(struct qxl_device *qdev,
{
struct qxl_release *release;
- spin_lock(&qdev->release_idr_lock);
- release = idr_find(&qdev->release_idr, id);
- spin_unlock(&qdev->release_idr_lock);
- if (!release) {
- DRM_ERROR("failed to find id in release_idr\n");
- return NULL;
- }
+ release = xa_load(&qdev->releases, id);
+ if (!release)
+ DRM_ERROR("failed to find id in releases\n");
return release;
}
Signed-off-by: Matthew Wilcox <willy@infradead.org> --- drivers/gpu/drm/qxl/qxl_drv.h | 3 +- drivers/gpu/drm/qxl/qxl_kms.c | 3 +- drivers/gpu/drm/qxl/qxl_release.c | 54 +++++++++++++------------------ 3 files changed, 25 insertions(+), 35 deletions(-)