From: Matthew Wilcox Date: Mon, 18 Feb 2019 21:29:20 +0000 (-0500) Subject: pps: Convert pps_idr to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=3bf1580b76a56c487cc3365d7d9c579fb1734d9d;p=users%2Fwilly%2Fxarray.git pps: Convert pps_idr to XArray The pps_idr_lock mutex is unnecessary thanks to the included xa_lock. Signed-off-by: Matthew Wilcox --- diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c index d9d566f70ed1..cd3172a69d2f 100644 --- a/drivers/pps/kapi.c +++ b/drivers/pps/kapi.c @@ -89,8 +89,9 @@ struct pps_device *pps_register_source(struct pps_source_info *info, goto pps_register_source_exit; } - /* These initializations must be done before calling idr_alloc() - * in order to avoid reces into pps_event(). + /* + * These initializations must be done before calling + * pps_register_cdev() in order to avoid races in pps_event(). */ pps->params.api_version = PPS_API_VERS; pps->params.mode = default_params; diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 22a65ad4e46e..c7215782893d 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c @@ -12,12 +12,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include "kc.h" @@ -28,8 +28,7 @@ static dev_t pps_devt; static struct class *pps_class; -static DEFINE_MUTEX(pps_idr_lock); -static DEFINE_IDR(pps_idr); +static DEFINE_XARRAY_ALLOC(pps_devs); /* * Char device methods @@ -336,9 +335,7 @@ static void pps_device_destruct(struct device *dev) /* Now we can release the ID for re-use */ pr_debug("deallocating pps%d\n", pps->id); - mutex_lock(&pps_idr_lock); - idr_remove(&pps_idr, pps->id); - mutex_unlock(&pps_idr_lock); + xa_erase(&pps_devs, pps->id); kfree(dev); kfree(pps); @@ -349,22 +346,19 @@ int pps_register_cdev(struct pps_device *pps) int err; dev_t devt; - mutex_lock(&pps_idr_lock); /* - * Get new ID for the new PPS source. After idr_alloc() calling - * the new source will be freely available into the kernel. + * Get new ID for the new PPS source. After this call + * the new source will be freely available in the kernel. */ - err = idr_alloc(&pps_idr, pps, 0, PPS_MAX_SOURCES, GFP_KERNEL); + err = xa_alloc(&pps_devs, &pps->id, pps, + XA_LIMIT(0, PPS_MAX_SOURCES - 1), GFP_KERNEL); if (err < 0) { - if (err == -ENOSPC) { + if (err == -EBUSY) { pr_err("%s: too many PPS sources in the system\n", pps->info.name); - err = -EBUSY; } - goto out_unlock; + goto out; } - pps->id = err; - mutex_unlock(&pps_idr_lock); devt = MKDEV(MAJOR(pps_devt), pps->id); @@ -375,7 +369,7 @@ int pps_register_cdev(struct pps_device *pps) if (err) { pr_err("%s: failed to add char device %d:%d\n", pps->info.name, MAJOR(pps_devt), pps->id); - goto free_idr; + goto erase; } pps->dev = device_create(pps_class, pps->info.dev, devt, pps, "pps%d", pps->id); @@ -394,12 +388,9 @@ int pps_register_cdev(struct pps_device *pps) del_cdev: cdev_del(&pps->cdev); - -free_idr: - mutex_lock(&pps_idr_lock); - idr_remove(&pps_idr, pps->id); -out_unlock: - mutex_unlock(&pps_idr_lock); +erase: + xa_erase(&pps_devs, pps->id); +out: return err; } @@ -425,19 +416,17 @@ void pps_unregister_cdev(struct pps_device *pps) * * The cookie is automatically set to NULL in pps_unregister_source() * so that it will not be used again, even if the pps device cannot - * be removed from the idr due to pending references holding the minor + * be removed from the array due to pending references holding the minor * number in use. */ struct pps_device *pps_lookup_dev(void const *cookie) { struct pps_device *pps; - unsigned id; + unsigned long id; - rcu_read_lock(); - idr_for_each_entry(&pps_idr, pps, id) + xa_for_each(&pps_devs, id, pps) if (cookie == pps->lookup_cookie) break; - rcu_read_unlock(); return pps; } EXPORT_SYMBOL(pps_lookup_dev);