static int hl_major;
static struct class *hl_class;
-static DEFINE_IDR(hl_devs_idr);
-static DEFINE_MUTEX(hl_devs_idr_lock);
+static DEFINE_XARRAY_ALLOC(hl_devs);
static int timeout_locked = 5;
static int reset_on_lockup = 1;
struct hl_fpriv *hpriv;
int rc;
- mutex_lock(&hl_devs_idr_lock);
- hdev = idr_find(&hl_devs_idr, iminor(inode));
- mutex_unlock(&hl_devs_idr_lock);
+ hdev = xa_load(&hl_devs, iminor(inode));
if (!hdev) {
pr_err("Couldn't find device %d:%d\n",
/* Set default DMA mask to 32 bits */
hdev->dma_mask = 32;
- mutex_lock(&hl_devs_idr_lock);
-
if (minor == -1) {
- rc = idr_alloc(&hl_devs_idr, hdev, 0, HL_MAX_MINORS,
- GFP_KERNEL);
- } else {
- void *old_idr = idr_replace(&hl_devs_idr, hdev, minor);
+ rc = xa_alloc(&hl_devs, &minor, hdev,
+ XA_LIMIT(0, HL_MAX_MINORS - 1), GFP_KERNEL);
- if (IS_ERR_VALUE(old_idr)) {
- rc = PTR_ERR(old_idr);
- pr_err("Error %d when trying to replace minor %d\n",
- rc, minor);
- mutex_unlock(&hl_devs_idr_lock);
- goto free_hdev;
- }
- rc = minor;
+ } else {
+ rc = xa_insert(&hl_devs, minor, hdev, GFP_KERNEL);
}
- mutex_unlock(&hl_devs_idr_lock);
-
+free_hdev:
if (rc < 0) {
- if (rc == -ENOSPC) {
- pr_err("too many devices in the system\n");
- rc = -EBUSY;
- }
- goto free_hdev;
+ kfree(hdev);
+ } else {
+ *dev = hdev;
+ hdev->id = minor;
}
- hdev->id = rc;
-
- *dev = hdev;
-
- return 0;
-
-free_hdev:
- kfree(hdev);
return rc;
}
void destroy_hdev(struct hl_device *hdev)
{
/* Remove device from the device list */
- mutex_lock(&hl_devs_idr_lock);
- idr_remove(&hl_devs_idr, hdev->id);
- mutex_unlock(&hl_devs_idr_lock);
-
+ xa_erase(&hl_devs, hdev->id);
kfree(hdev);
}
class_destroy(hl_class);
unregister_chrdev_region(MKDEV(hl_major, 0), HL_MAX_MINORS);
- idr_destroy(&hl_devs_idr);
-
pr_debug("driver removed\n");
}