From: Matthew Wilcox Date: Tue, 8 Jan 2019 14:15:14 +0000 (-0500) Subject: drm: Convert aux_idr to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=18ba7d8f9c8c531865e18ed13fc073261cc3cd7f;p=users%2Fwilly%2Fxarray.git drm: Convert aux_idr to XArray Signed-off-by: Matthew Wilcox --- diff --git a/drivers/gpu/drm/drm_dp_aux_dev.c b/drivers/gpu/drm/drm_dp_aux_dev.c index 5be28e3295f3..aecd5e75b476 100644 --- a/drivers/gpu/drm/drm_dp_aux_dev.c +++ b/drivers/gpu/drm/drm_dp_aux_dev.c @@ -51,8 +51,8 @@ struct drm_dp_aux_dev { #define DRM_AUX_MINORS 256 #define AUX_MAX_OFFSET (1 << 20) -static DEFINE_IDR(aux_idr); -static DEFINE_MUTEX(aux_idr_mutex); +static DEFINE_XARRAY_ALLOC(aux_xa); +static u32 aux_xa_next; static struct class *drm_dp_aux_dev_class; static int drm_dev_major = -1; @@ -60,11 +60,11 @@ static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index) { struct drm_dp_aux_dev *aux_dev = NULL; - mutex_lock(&aux_idr_mutex); - aux_dev = idr_find(&aux_idr, index); + xa_lock(&aux_xa); + aux_dev = xa_load(&aux_xa, index); if (!kref_get_unless_zero(&aux_dev->refcount)) aux_dev = NULL; - mutex_unlock(&aux_idr_mutex); + xa_unlock(&aux_xa); return aux_dev; } @@ -72,7 +72,7 @@ static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index) static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux) { struct drm_dp_aux_dev *aux_dev; - int index; + int err; aux_dev = kzalloc(sizeof(*aux_dev), GFP_KERNEL); if (!aux_dev) @@ -81,15 +81,12 @@ static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux) atomic_set(&aux_dev->usecount, 1); kref_init(&aux_dev->refcount); - mutex_lock(&aux_idr_mutex); - index = idr_alloc_cyclic(&aux_idr, aux_dev, 0, DRM_AUX_MINORS, - GFP_KERNEL); - mutex_unlock(&aux_idr_mutex); - if (index < 0) { + err = xa_alloc_cyclic(&aux_xa, &aux_dev->index, aux_dev, + XA_LIMIT(0, DRM_AUX_MINORS), &aux_xa_next, GFP_KERNEL); + if (err < 0) { kfree(aux_dev); - return ERR_PTR(index); + return ERR_PTR(err); } - aux_dev->index = index; return aux_dev; } @@ -248,22 +245,19 @@ static const struct file_operations auxdev_fops = { static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux *aux) { - struct drm_dp_aux_dev *iter, *aux_dev = NULL; - int id; + struct drm_dp_aux_dev *aux_dev; + unsigned long id; /* don't increase kref count here because this function should only be * used by drm_dp_aux_unregister_devnode. Thus, it will always have at * least one reference - the one that drm_dp_aux_register_devnode * created */ - mutex_lock(&aux_idr_mutex); - idr_for_each_entry(&aux_idr, iter, id) { - if (iter->aux == aux) { - aux_dev = iter; + xa_for_each(&aux_xa, id, aux_dev) { + if (aux_dev->aux == aux) break; - } } - mutex_unlock(&aux_idr_mutex); + return aux_dev; } @@ -276,9 +270,7 @@ void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux) if (!aux_dev) /* attach must have failed */ return; - mutex_lock(&aux_idr_mutex); - idr_remove(&aux_idr, aux_dev->index); - mutex_unlock(&aux_idr_mutex); + xa_erase(&aux_xa, aux_dev->index); atomic_dec(&aux_dev->usecount); wait_var_event(&aux_dev->usecount, !atomic_read(&aux_dev->usecount));