@@ -677,7 +677,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
spin_lock_init(&dev_priv->cursor_lock);
for (i = vmw_res_context; i < vmw_res_max; ++i) {
- idr_init(&dev_priv->res_idr[i]);
+ xa_init_flags(&dev_priv->resources[i], XA_FLAGS_ALLOC1);
INIT_LIST_HEAD(&dev_priv->res_lru[i]);
}
@@ -988,9 +988,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
out_err4:
memunmap(dev_priv->mmio_virt);
out_err0:
- for (i = vmw_res_context; i < vmw_res_max; ++i)
- idr_destroy(&dev_priv->res_idr[i]);
-
if (dev_priv->ctx.staged_bindings)
vmw_binding_state_free(dev_priv->ctx.staged_bindings);
kfree(dev_priv);
@@ -1000,7 +997,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
static void vmw_driver_unload(struct drm_device *dev)
{
struct vmw_private *dev_priv = vmw_priv(dev);
- enum vmw_res_type i;
unregister_pm_notifier(&dev_priv->pm_nb);
@@ -1039,9 +1035,6 @@ static void vmw_driver_unload(struct drm_device *dev)
if (dev_priv->ctx.staged_bindings)
vmw_binding_state_free(dev_priv->ctx.staged_bindings);
- for (i = vmw_res_context; i < vmw_res_max; ++i)
- idr_destroy(&dev_priv->res_idr[i]);
-
kfree(dev_priv);
}
@@ -484,7 +484,8 @@ struct vmw_private {
*/
spinlock_t resource_lock;
- struct idr res_idr[vmw_res_max];
+ struct xarray resources[vmw_res_max];
+
/*
* Block lastclose from racing with firstopen.
*/
@@ -56,13 +56,11 @@ vmw_resource_reference_unless_doomed(struct vmw_resource *res)
void vmw_resource_release_id(struct vmw_resource *res)
{
struct vmw_private *dev_priv = res->dev_priv;
- struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+ struct xarray *xa = &dev_priv->resources[res->func->res_type];
- spin_lock(&dev_priv->resource_lock);
if (res->id != -1)
- idr_remove(idr, res->id);
+ xa_erase(xa, res->id);
res->id = -1;
- spin_unlock(&dev_priv->resource_lock);
}
static void vmw_resource_release(struct kref *kref)
@@ -70,8 +68,7 @@ static void vmw_resource_release(struct kref *kref)
struct vmw_resource *res =
container_of(kref, struct vmw_resource, kref);
struct vmw_private *dev_priv = res->dev_priv;
- int id;
- struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+ struct xarray *xa = &dev_priv->resources[res->func->res_type];
spin_lock(&dev_priv->resource_lock);
list_del_init(&res->lru_head);
@@ -101,16 +98,12 @@ static void vmw_resource_release(struct kref *kref)
res->hw_destroy(res);
}
- id = res->id;
+ if (res->id != -1)
+ xa_erase(xa, res->id);
if (res->res_free != NULL)
res->res_free(res);
else
kfree(res);
-
- spin_lock(&dev_priv->resource_lock);
- if (id != -1)
- idr_remove(idr, id);
- spin_unlock(&dev_priv->resource_lock);
}
void vmw_resource_unreference(struct vmw_resource **p_res)
@@ -133,21 +126,11 @@ void vmw_resource_unreference(struct vmw_resource **p_res)
int vmw_resource_alloc_id(struct vmw_resource *res)
{
struct vmw_private *dev_priv = res->dev_priv;
- int ret;
- struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+ struct xarray *xa = &dev_priv->resources[res->func->res_type];
BUG_ON(res->id != -1);
- idr_preload(GFP_KERNEL);
- spin_lock(&dev_priv->resource_lock);
-
- ret = idr_alloc(idr, res, 1, 0, GFP_NOWAIT);
- if (ret >= 0)
- res->id = ret;
-
- spin_unlock(&dev_priv->resource_lock);
- idr_preload_end();
- return ret < 0 ? ret : 0;
+ return xa_alloc(xa, &res->id, res, xa_limit_31b, GFP_NOWAIT);
}
/**
Signed-off-by: Matthew Wilcox <willy@infradead.org> --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 9 +------ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 3 ++- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 31 ++++++------------------ 3 files changed, 10 insertions(+), 33 deletions(-)