diff options
-rw-r--r-- | arch/powerpc/mm/icswx_pid.c | 38 | ||||
-rw-r--r-- | arch/powerpc/mm/mmu_context_hash64.c | 30 | ||||
-rw-r--r-- | drivers/base/soc.c | 22 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 30 | ||||
-rw-r--r-- | drivers/block/nvme-core.c | 37 | ||||
-rw-r--r-- | drivers/block/rsxx/core.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 33 | ||||
-rw-r--r-- | drivers/iommu/iommu.c | 22 | ||||
-rw-r--r-- | drivers/misc/cb710/core.c | 21 | ||||
-rw-r--r-- | drivers/scsi/osd/osd_uld.c | 13 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 23 | ||||
-rw-r--r-- | fs/devpts/inode.c | 24 | ||||
-rw-r--r-- | fs/namespace.c | 49 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 31 | ||||
-rw-r--r-- | fs/proc/generic.c | 31 | ||||
-rw-r--r-- | fs/super.c | 37 | ||||
-rw-r--r-- | fs/sysfs/dir.c | 22 | ||||
-rw-r--r-- | include/linux/idr.h | 15 | ||||
-rw-r--r-- | kernel/cgroup.c | 29 | ||||
-rw-r--r-- | lib/idr.c | 14 | ||||
-rw-r--r-- | net/core/net_namespace.c | 19 |
21 files changed, 129 insertions, 434 deletions
diff --git a/arch/powerpc/mm/icswx_pid.c b/arch/powerpc/mm/icswx_pid.c index 91e30eb7d054..41239fb9eb9e 100644 --- a/arch/powerpc/mm/icswx_pid.c +++ b/arch/powerpc/mm/icswx_pid.c @@ -23,45 +23,15 @@ #define COP_PID_MIN (COP_PID_NONE + 1) #define COP_PID_MAX (0xFFFF) -static DEFINE_SPINLOCK(mmu_context_acop_lock); static DEFINE_IDA(cop_ida); -static int new_cop_pid(struct ida *ida, int min_id, int max_id, - spinlock_t *lock) -{ - int index; - int err; - -again: - if (!ida_pre_get(ida, GFP_KERNEL)) - return -ENOMEM; - - spin_lock(lock); - err = ida_get_new_above(ida, min_id, &index); - spin_unlock(lock); - - if (err == -EAGAIN) - goto again; - else if (err) - return err; - - if (index > max_id) { - spin_lock(lock); - ida_remove(ida, index); - spin_unlock(lock); - return -ENOMEM; - } - - return index; -} - int get_cop_pid(struct mm_struct *mm) { int pid; if (mm->context.cop_pid == COP_PID_NONE) { - pid = new_cop_pid(&cop_ida, COP_PID_MIN, COP_PID_MAX, - &mmu_context_acop_lock); + pid = ida_simple_get(&cop_ida, COP_PID_MIN, + COP_PID_MAX, GFP_KERNEL); if (pid >= 0) mm->context.cop_pid = pid; } @@ -81,7 +51,5 @@ int disable_cop_pid(struct mm_struct *mm) void free_cop_pid(int free_pid) { - spin_lock(&mmu_context_acop_lock); - ida_remove(&cop_ida, free_pid); - spin_unlock(&mmu_context_acop_lock); + ida_simple_remove(&cop_ida, free_pid); } diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c index 178876aef40f..42efac1895c3 100644 --- a/arch/powerpc/mm/mmu_context_hash64.c +++ b/arch/powerpc/mm/mmu_context_hash64.c @@ -27,35 +27,11 @@ #include "icswx.h" -static DEFINE_SPINLOCK(mmu_context_lock); static DEFINE_IDA(mmu_context_ida); int __init_new_context(void) { - int index; - int err; - -again: - if (!ida_pre_get(&mmu_context_ida, GFP_KERNEL)) - return -ENOMEM; - - spin_lock(&mmu_context_lock); - err = ida_get_new_above(&mmu_context_ida, 1, &index); - spin_unlock(&mmu_context_lock); - - if (err == -EAGAIN) - goto again; - else if (err) - return err; - - if (index > MAX_USER_CONTEXT) { - spin_lock(&mmu_context_lock); - ida_remove(&mmu_context_ida, index); - spin_unlock(&mmu_context_lock); - return -ENOMEM; - } - - return index; + return ida_simple_get(ida, 1, MAX_USER_CONTEXT, GFP_KERNEL); } EXPORT_SYMBOL_GPL(__init_new_context); @@ -94,9 +70,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) void __destroy_context(int context_id) { - spin_lock(&mmu_context_lock); - ida_remove(&mmu_context_ida, context_id); - spin_unlock(&mmu_context_lock); + ida_simple_remove(&mmu_context_ida, context_id); } EXPORT_SYMBOL_GPL(__destroy_context); diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 72b5e7280d14..72b9dc281e57 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -16,7 +16,6 @@ #include <linux/err.h> static DEFINE_IDA(soc_ida); -static DEFINE_SPINLOCK(soc_lock); static ssize_t soc_info_get(struct device *dev, struct device_attribute *attr, @@ -121,22 +120,11 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr goto out1; } - /* Fetch a unique (reclaimable) SOC ID. */ - do { - if (!ida_pre_get(&soc_ida, GFP_KERNEL)) { - ret = -ENOMEM; - goto out2; - } - - spin_lock(&soc_lock); - ret = ida_get_new(&soc_ida, &soc_dev->soc_dev_num); - spin_unlock(&soc_lock); - - } while (ret == -EAGAIN); - - if (ret) + ret = ida_simple_get(&soc_ida, 0, 0, GFP_KERNEL); + if (ret < 0) goto out2; + soc->dev->soc_dev_num = ret; soc_dev->attr = soc_dev_attr; soc_dev->dev.bus = &soc_bus_type; soc_dev->dev.groups = soc_attr_groups; @@ -151,7 +139,7 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr return soc_dev; out3: - ida_remove(&soc_ida, soc_dev->soc_dev_num); + ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); out2: kfree(soc_dev); out1: @@ -161,7 +149,7 @@ out1: /* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */ void soc_device_unregister(struct soc_device *soc_dev) { - ida_remove(&soc_ida, soc_dev->soc_dev_num); + ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); device_unregister(&soc_dev->dev); } diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 847107ef0cce..c0b43909cd58 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -95,7 +95,6 @@ static struct dentry *dfs_device_status; static u32 cpu_use[NR_CPUS]; -static DEFINE_SPINLOCK(rssd_index_lock); static DEFINE_IDA(rssd_index_ida); static int mtip_block_initialize(struct driver_data *dd); @@ -3981,18 +3980,11 @@ static int mtip_block_initialize(struct driver_data *dd) goto alloc_disk_error; } - /* Generate the disk name, implemented same as in sd.c */ - do { - if (!ida_pre_get(&rssd_index_ida, GFP_KERNEL)) - goto ida_get_error; - - spin_lock(&rssd_index_lock); - rv = ida_get_new(&rssd_index_ida, &index); - spin_unlock(&rssd_index_lock); - } while (rv == -EAGAIN); + rv = ida_simple_get(&rssd_index_ida, 0, 0, GFP_KERNEL); + if (rv < 0) + goto ida_alloc_error; - if (rv) - goto ida_get_error; + index = rv; rv = rssd_disk_name_format("rssd", index, @@ -4110,11 +4102,9 @@ read_capacity_error: block_queue_alloc_init_error: disk_index_error: - spin_lock(&rssd_index_lock); - ida_remove(&rssd_index_ida, index); - spin_unlock(&rssd_index_lock); + ida_simple_remove(&rssd_index_ida, index); -ida_get_error: +ida_alloc_error: put_disk(dd->disk); alloc_disk_error: @@ -4165,9 +4155,7 @@ static int mtip_block_remove(struct driver_data *dd) put_disk(dd->disk); } - spin_lock(&rssd_index_lock); - ida_remove(&rssd_index_ida, dd->index); - spin_unlock(&rssd_index_lock); + ida_simple_remove(&rssd_index_ida, dd->index); blk_cleanup_queue(dd->queue); dd->disk = NULL; @@ -4207,9 +4195,7 @@ static int mtip_block_shutdown(struct driver_data *dd) dd->queue = NULL; } - spin_lock(&rssd_index_lock); - ida_remove(&rssd_index_ida, dd->index); - spin_unlock(&rssd_index_lock); + ida_simple_remove(&rssd_index_ida, dd->index); mtip_hw_shutdown(dd); return 0; diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 8efdfaa44a59..d882b91c1fdf 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1519,27 +1519,12 @@ static DEFINE_IDA(nvme_index_ida); static int nvme_get_ns_idx(void) { - int index, error; - - do { - if (!ida_pre_get(&nvme_index_ida, GFP_KERNEL)) - return -1; - - spin_lock(&dev_list_lock); - error = ida_get_new(&nvme_index_ida, &index); - spin_unlock(&dev_list_lock); - } while (error == -EAGAIN); - - if (error) - index = -1; - return index; + return ida_simple_get(&nvme_index_ida, 0, 0, GFP_KERNEL); } static void nvme_put_ns_idx(int index) { - spin_lock(&dev_list_lock); - ida_remove(&nvme_index_ida, index); - spin_unlock(&dev_list_lock); + ida_simple_remove(&nvme_index_ida, index); } static void nvme_config_discard(struct nvme_ns *ns) @@ -1821,18 +1806,10 @@ static DEFINE_IDA(nvme_instance_ida); static int nvme_set_instance(struct nvme_dev *dev) { - int instance, error; + int instance; - do { - if (!ida_pre_get(&nvme_instance_ida, GFP_KERNEL)) - return -ENODEV; - - spin_lock(&dev_list_lock); - error = ida_get_new(&nvme_instance_ida, &instance); - spin_unlock(&dev_list_lock); - } while (error == -EAGAIN); - - if (error) + instance = ida_simple_get(&nvme_index_ida, 0, 0, GFP_KERNEL); + if (instance < 0) return -ENODEV; dev->instance = instance; @@ -1841,9 +1818,7 @@ static int nvme_set_instance(struct nvme_dev *dev) static void nvme_release_instance(struct nvme_dev *dev) { - spin_lock(&dev_list_lock); - ida_remove(&nvme_instance_ida, dev->instance); - spin_unlock(&dev_list_lock); + ida_simple_remove(&nvme_instance_ida, dev->instance); } static void nvme_free_dev(struct kref *kref) diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index 5af21f2db29c..5487be017896 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c @@ -50,7 +50,6 @@ module_param(force_legacy, uint, 0444); MODULE_PARM_DESC(force_legacy, "Force the use of legacy type PCI interrupts"); static DEFINE_IDA(rsxx_disk_ida); -static DEFINE_SPINLOCK(rsxx_ida_lock); /*----------------- Interrupt Control & Handling -------------------*/ @@ -538,19 +537,11 @@ static int rsxx_pci_probe(struct pci_dev *dev, card->dev = dev; pci_set_drvdata(dev, card); - do { - if (!ida_pre_get(&rsxx_disk_ida, GFP_KERNEL)) { - st = -ENOMEM; - goto failed_ida_get; - } + st = ida_simple_get(&rsxx_disk_ida, 0, 0, GFP_KERNEL); + if (st < 0) + goto failed_ida_alloc; - spin_lock(&rsxx_ida_lock); - st = ida_get_new(&rsxx_disk_ida, &card->disk_id); - spin_unlock(&rsxx_ida_lock); - } while (st == -EAGAIN); - - if (st) - goto failed_ida_get; + card->disk_id = st; st = pci_enable_device(dev); if (st) @@ -705,10 +696,8 @@ failed_request_regions: failed_dma_mask: pci_disable_device(dev); failed_enable: - spin_lock(&rsxx_ida_lock); - ida_remove(&rsxx_disk_ida, card->disk_id); - spin_unlock(&rsxx_ida_lock); -failed_ida_get: + ida_simple_remove(&rsxx_disk_ida, card->disk_id); +failed_ida_alloc: kfree(card); return st; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c index c5c054ae9056..a74341752d5b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c @@ -52,7 +52,6 @@ static int vmw_gmrid_man_get_node(struct ttm_mem_type_manager *man, struct vmwgfx_gmrid_man *gman = (struct vmwgfx_gmrid_man *)man->priv; int ret = 0; - int id; mem->mm_node = NULL; @@ -64,34 +63,20 @@ static int vmw_gmrid_man_get_node(struct ttm_mem_type_manager *man, goto out_err_locked; } - do { - spin_unlock(&gman->lock); - if (unlikely(ida_pre_get(&gman->gmr_ida, GFP_KERNEL) == 0)) { - ret = -ENOMEM; - goto out_err; - } - spin_lock(&gman->lock); + spin_unlock(&gman->lock); + ret = ida_simple_get(&gman->gmr_ida, 0, gman->max_gmr_ids, GFP_KERNEL); + spin_lock(&gman->lock); - ret = ida_get_new(&gman->gmr_ida, &id); - if (unlikely(ret == 0 && id >= gman->max_gmr_ids)) { - ida_remove(&gman->gmr_ida, id); - ret = 0; - goto out_err_locked; - } - } while (ret == -EAGAIN); - - if (likely(ret == 0)) { - mem->mm_node = gman; - mem->start = id; - mem->num_pages = bo->num_pages; - } else + if (ret < 0) goto out_err_locked; + mem->mm_node = gman; + mem->start = ret; + mem->num_pages = bo->num_pages; + spin_unlock(&gman->lock); return 0; -out_err: - spin_lock(&gman->lock); out_err_locked: gman->used_gmr_pages -= bo->num_pages; spin_unlock(&gman->lock); @@ -106,7 +91,7 @@ static void vmw_gmrid_man_put_node(struct ttm_mem_type_manager *man, if (mem->mm_node) { spin_lock(&gman->lock); - ida_remove(&gman->gmr_ida, mem->start); + ida_simple_remove(&gman->gmr_ida, mem->start); gman->used_gmr_pages -= mem->num_pages; spin_unlock(&gman->lock); mem->mm_node = NULL; diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d8f98b14e2fe..d12ca9b0412b 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -32,7 +32,6 @@ static struct kset *iommu_group_kset; static struct ida iommu_group_ida; -static struct mutex iommu_group_mutex; struct iommu_group { struct kobject kobj; @@ -124,9 +123,7 @@ static void iommu_group_release(struct kobject *kobj) if (group->iommu_data_release) group->iommu_data_release(group->iommu_data); - mutex_lock(&iommu_group_mutex); - ida_remove(&iommu_group_ida, group->id); - mutex_unlock(&iommu_group_mutex); + ida_simple_remove(&iommu_group_ida, group->id); kfree(group->name); kfree(group); @@ -163,26 +160,18 @@ struct iommu_group *iommu_group_alloc(void) INIT_LIST_HEAD(&group->devices); BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier); - mutex_lock(&iommu_group_mutex); - -again: - if (unlikely(0 == ida_pre_get(&iommu_group_ida, GFP_KERNEL))) { + ret = ida_simple_get(&iommu_group_ida, 0, 0, GFP_KERNEL); + if (ret < 0) { kfree(group); - mutex_unlock(&iommu_group_mutex); return ERR_PTR(-ENOMEM); } - if (-EAGAIN == ida_get_new(&iommu_group_ida, &group->id)) - goto again; - - mutex_unlock(&iommu_group_mutex); + group->id = ret; ret = kobject_init_and_add(&group->kobj, &iommu_group_ktype, NULL, "%d", group->id); if (ret) { - mutex_lock(&iommu_group_mutex); - ida_remove(&iommu_group_ida, group->id); - mutex_unlock(&iommu_group_mutex); + ida_simple_remove(&iommu_group_ida, group->id); kfree(group); return ERR_PTR(ret); } @@ -906,7 +895,6 @@ static int __init iommu_init(void) iommu_group_kset = kset_create_and_add("iommu_groups", NULL, kernel_kobj); ida_init(&iommu_group_ida); - mutex_init(&iommu_group_mutex); BUG_ON(!iommu_group_kset); diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c index 2e50f811ff59..f664afa201e7 100644 --- a/drivers/misc/cb710/core.c +++ b/drivers/misc/cb710/core.c @@ -16,7 +16,6 @@ #include <linux/gfp.h> static DEFINE_IDA(cb710_ida); -static DEFINE_SPINLOCK(cb710_ida_lock); void cb710_pci_update_config_reg(struct pci_dev *pdev, int reg, uint32_t mask, uint32_t xor) @@ -205,7 +204,6 @@ static int cb710_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct cb710_chip *chip; - unsigned long flags; u32 val; int err; int n = 0; @@ -256,18 +254,11 @@ static int cb710_probe(struct pci_dev *pdev, if (err) return err; - do { - if (!ida_pre_get(&cb710_ida, GFP_KERNEL)) - return -ENOMEM; - - spin_lock_irqsave(&cb710_ida_lock, flags); - err = ida_get_new(&cb710_ida, &chip->platform_id); - spin_unlock_irqrestore(&cb710_ida_lock, flags); - - if (err && err != -EAGAIN) - return err; - } while (err); + err = ida_simple_get(&cb710_ida, 0, 0, GFP_KERNEL); + if (err < 0) + return err; + chip->platform_id = err; dev_info(&pdev->dev, "id %d, IO 0x%p, IRQ %d\n", chip->platform_id, chip->iobase, pdev->irq); @@ -317,9 +308,7 @@ static void cb710_remove_one(struct pci_dev *pdev) BUG_ON(atomic_read(&chip->slot_refs_count) != 0); #endif - spin_lock_irqsave(&cb710_ida_lock, flags); - ida_remove(&cb710_ida, chip->platform_id); - spin_unlock_irqrestore(&cb710_ida_lock, flags); + ida_simple_remove(&cb710_ida, chip->platform_id); } static const struct pci_device_id cb710_pci_tbl[] = { diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index 0fab6b5c7b82..970031e57d1e 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c @@ -407,7 +407,7 @@ static void __remove(struct device *dev) if (oud->disk) put_disk(oud->disk); - ida_remove(&osd_minor_ida, oud->minor); + ida_simple_remove(&osd_minor_ida, oud->minor); kfree(oud); } @@ -423,12 +423,9 @@ static int osd_probe(struct device *dev) if (scsi_device->type != TYPE_OSD) return -ENODEV; - do { - if (!ida_pre_get(&osd_minor_ida, GFP_KERNEL)) - return -ENODEV; - - error = ida_get_new(&osd_minor_ida, &minor); - } while (error == -EAGAIN); + minor = ida_simple_get(&osd_minor_ida, 0, 0, GFP_KERNEL); + if (minor < 0) + return -ENODEV; if (error) return error; @@ -511,7 +508,7 @@ err_free_osd: dev_set_drvdata(dev, NULL); kfree(oud); err_retract_minor: - ida_remove(&osd_minor_ida, minor); + ida_simple_remove(&osd_minor_ida, minor); return error; } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c1c555242d0d..ae29efea4e09 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -115,7 +115,6 @@ static void scsi_disk_release(struct device *cdev); static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); static void sd_print_result(struct scsi_disk *, int); -static DEFINE_SPINLOCK(sd_index_lock); static DEFINE_IDA(sd_index_ida); /* This semaphore is used to mediate the 0->1 reference get in the @@ -2893,17 +2892,9 @@ static int sd_probe(struct device *dev) if (!gd) goto out_free; - do { - if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) - goto out_put; - - spin_lock(&sd_index_lock); - error = ida_get_new(&sd_index_ida, &index); - spin_unlock(&sd_index_lock); - } while (error == -EAGAIN); - - if (error) { - sdev_printk(KERN_WARNING, sdp, "sd_probe: memory exhausted.\n"); + index = ida_simple_get(&sd_index_ida, 0, 0, GFP_KERNEL); + if (index < 0) { + error = index; goto out_put; } @@ -2945,9 +2936,7 @@ static int sd_probe(struct device *dev) return 0; out_free_index: - spin_lock(&sd_index_lock); - ida_remove(&sd_index_ida, index); - spin_unlock(&sd_index_lock); + ida_simple_remove(&sd_index_ida, index); out_put: put_disk(gd); out_free: @@ -3003,9 +2992,7 @@ static void scsi_disk_release(struct device *dev) struct scsi_disk *sdkp = to_scsi_disk(dev); struct gendisk *disk = sdkp->disk; - spin_lock(&sd_index_lock); - ida_remove(&sd_index_ida, sdkp->index); - spin_unlock(&sd_index_lock); + ida_simple_remove(&sd_index_ida, sdkp->index); disk->private_data = NULL; put_disk(disk); diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 073d30b9d1ac..d77702a8e887 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -521,32 +521,20 @@ int devpts_new_index(struct inode *ptmx_inode) struct super_block *sb = pts_sb_from_inode(ptmx_inode); struct pts_fs_info *fsi = DEVPTS_SB(sb); int index; - int ida_ret; -retry: - if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL)) - return -ENOMEM; + index = ida_simple_get(&fsi->allocated_ptys, 0, + fsi->mount_opts.max, GFP_KERNEL); + if (index < 0) + return index; mutex_lock(&allocated_ptys_lock); if (pty_count >= pty_limit - (fsi->mount_opts.newinstance ? pty_reserve : 0)) { mutex_unlock(&allocated_ptys_lock); + ida_simple_remove(&fsi->allocated_ptys, index); return -ENOSPC; } - ida_ret = ida_get_new(&fsi->allocated_ptys, &index); - if (ida_ret < 0) { - mutex_unlock(&allocated_ptys_lock); - if (ida_ret == -EAGAIN) - goto retry; - return -EIO; - } - - if (index >= fsi->mount_opts.max) { - ida_remove(&fsi->allocated_ptys, index); - mutex_unlock(&allocated_ptys_lock); - return -ENOSPC; - } pty_count++; mutex_unlock(&allocated_ptys_lock); return index; @@ -557,8 +545,8 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx) struct super_block *sb = pts_sb_from_inode(ptmx_inode); struct pts_fs_info *fsi = DEVPTS_SB(sb); + ida_simple_remove(&fsi->allocated_ptys, idx); mutex_lock(&allocated_ptys_lock); - ida_remove(&fsi->allocated_ptys, idx); pty_count--; mutex_unlock(&allocated_ptys_lock); } diff --git a/fs/namespace.c b/fs/namespace.c index 7b1ca9ba0b0a..1cf0df48e9ba 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -32,9 +32,6 @@ static int event; static DEFINE_IDA(mnt_id_ida); static DEFINE_IDA(mnt_group_ida); -static DEFINE_SPINLOCK(mnt_id_lock); -static int mnt_id_start = 0; -static int mnt_group_start = 1; static struct list_head *mount_hashtable __read_mostly; static struct list_head *mountpoint_hashtable __read_mostly; @@ -71,29 +68,17 @@ static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) */ static int mnt_alloc_id(struct mount *mnt) { - int res; - -retry: - ida_pre_get(&mnt_id_ida, GFP_KERNEL); - spin_lock(&mnt_id_lock); - res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id); - if (!res) - mnt_id_start = mnt->mnt_id + 1; - spin_unlock(&mnt_id_lock); - if (res == -EAGAIN) - goto retry; + int res = ida_simple_get(&mnt_id_ida, 0, 0, GFP_KERNEL); + if (res < 0) + return res; - return res; + mnt->mnt_id = res; + return 0; } static void mnt_free_id(struct mount *mnt) { - int id = mnt->mnt_id; - spin_lock(&mnt_id_lock); - ida_remove(&mnt_id_ida, id); - if (mnt_id_start > id) - mnt_id_start = id; - spin_unlock(&mnt_id_lock); + ida_simple_remove(&mnt_id_ida, mnt->mnt_id); } /* @@ -103,18 +88,12 @@ static void mnt_free_id(struct mount *mnt) */ static int mnt_alloc_group_id(struct mount *mnt) { - int res; - - if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL)) - return -ENOMEM; - - res = ida_get_new_above(&mnt_group_ida, - mnt_group_start, - &mnt->mnt_group_id); - if (!res) - mnt_group_start = mnt->mnt_group_id + 1; + int res = ida_simple_get(&mnt_id_ida, 1, 0, GFP_KERNEL); + if (res < 0) + return res; - return res; + mnt->mnt_group_id = res; + return 0; } /* @@ -122,11 +101,7 @@ static int mnt_alloc_group_id(struct mount *mnt) */ void mnt_release_group_id(struct mount *mnt) { - int id = mnt->mnt_group_id; - ida_remove(&mnt_group_ida, id); - if (mnt_group_start > id) - mnt_group_start = id; - mnt->mnt_group_id = 0; + ida_simple_remove(&mnt_group_ida, mnt->mnt_group_id); } /* diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 1fab140764c4..5ed4bce576b5 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -431,7 +431,6 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new) struct rb_node **p = &server->state_owners.rb_node, *parent = NULL; struct nfs4_state_owner *sp; - int err; while (*p != NULL) { parent = *p; @@ -448,9 +447,6 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new) return sp; } } - err = ida_get_new(&server->openowner_id, &new->so_seqid.owner_id); - if (err) - return ERR_PTR(err); rb_link_node(&new->so_server_node, parent, p); rb_insert_color(&new->so_server_node, &server->state_owners); return new; @@ -463,7 +459,7 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp) if (!RB_EMPTY_NODE(&sp->so_server_node)) rb_erase(&sp->so_server_node, &server->state_owners); - ida_remove(&server->openowner_id, sp->so_seqid.owner_id); + ida_simple_remove(&server->openowner_id, sp->so_seqid.owner_id); } static void @@ -573,6 +569,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, { struct nfs_client *clp = server->nfs_client; struct nfs4_state_owner *sp, *new; + int id; spin_lock(&clp->cl_lock); sp = nfs4_find_state_owner_locked(server, cred); @@ -582,15 +579,23 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, new = nfs4_alloc_state_owner(server, cred, gfp_flags); if (new == NULL) goto out; - do { - if (ida_pre_get(&server->openowner_id, gfp_flags) == 0) - break; - spin_lock(&clp->cl_lock); - sp = nfs4_insert_state_owner_locked(new); - spin_unlock(&clp->cl_lock); - } while (sp == ERR_PTR(-EAGAIN)); - if (sp != new) + + id = ida_simple_get(&server->openowner_id, 0, 0, gfp_flags); + if (id < 0) { nfs4_free_state_owner(new); + sp = ERR_PTR(id); + goto out; + } + new->so_seqid.owner_id = id; + + spin_lock(&clp->cl_lock); + sp = nfs4_insert_state_owner_locked(new); + spin_unlock(&clp->cl_lock); + + if (sp != new) { + ida_simple_remove(&server->openowner_id, new->so_seqid.owner_id); + nfs4_free_state_owner(new); + } out: nfs4_gc_state_owners(server); return sp; diff --git a/fs/proc/generic.c b/fs/proc/generic.c index a2596afffae6..944ce2befc38 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -120,7 +120,6 @@ static int xlate_proc_name(const char *name, struct proc_dir_entry **ret, } static DEFINE_IDA(proc_inum_ida); -static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */ #define PROC_DYNAMIC_FIRST 0xF0000000U @@ -130,37 +129,19 @@ static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */ */ int proc_alloc_inum(unsigned int *inum) { - unsigned int i; - int error; - -retry: - if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL)) - return -ENOMEM; + int i = ida_simple_get(&proc_inum_ida, 0, + UINT_MAX - PROC_DYNAMIC_FIRST, + GFP_KERNEL); + if (i < 0) + return i; - spin_lock_irq(&proc_inum_lock); - error = ida_get_new(&proc_inum_ida, &i); - spin_unlock_irq(&proc_inum_lock); - if (error == -EAGAIN) - goto retry; - else if (error) - return error; - - if (i > UINT_MAX - PROC_DYNAMIC_FIRST) { - spin_lock_irq(&proc_inum_lock); - ida_remove(&proc_inum_ida, i); - spin_unlock_irq(&proc_inum_lock); - return -ENOSPC; - } *inum = PROC_DYNAMIC_FIRST + i; return 0; } void proc_free_inum(unsigned int inum) { - unsigned long flags; - spin_lock_irqsave(&proc_inum_lock, flags); - ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); - spin_unlock_irqrestore(&proc_inum_lock, flags); + ida_simple_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); } static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) diff --git a/fs/super.c b/fs/super.c index 7465d4364208..ec99b7eeeb7d 100644 --- a/fs/super.c +++ b/fs/super.c @@ -818,36 +818,18 @@ void emergency_remount(void) */ static DEFINE_IDA(unnamed_dev_ida); -static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */ -static int unnamed_dev_start = 0; /* don't bother trying below it */ int get_anon_bdev(dev_t *p) { int dev; - int error; - retry: - if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0) - return -ENOMEM; - spin_lock(&unnamed_dev_lock); - error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev); - if (!error) - unnamed_dev_start = dev + 1; - spin_unlock(&unnamed_dev_lock); - if (error == -EAGAIN) - /* We raced and lost with another CPU. */ - goto retry; - else if (error) - return -EAGAIN; - - if (dev == (1 << MINORBITS)) { - spin_lock(&unnamed_dev_lock); - ida_remove(&unnamed_dev_ida, dev); - if (unnamed_dev_start > dev) - unnamed_dev_start = dev; - spin_unlock(&unnamed_dev_lock); + dev = ida_simple_get(&unnamed_dev_ida, 0, + 1 << MINORBITS, GFP_ATOMIC); + if (dev == -ENOSPC) return -EMFILE; - } + if (dev < 0) + return dev; + *p = MKDEV(0, dev & MINORMASK); return 0; } @@ -855,12 +837,7 @@ EXPORT_SYMBOL(get_anon_bdev); void free_anon_bdev(dev_t dev) { - int slot = MINOR(dev); - spin_lock(&unnamed_dev_lock); - ida_remove(&unnamed_dev_ida, slot); - if (slot < unnamed_dev_start) - unnamed_dev_start = slot; - spin_unlock(&unnamed_dev_lock); + ida_simple_remove(&unnamed_dev_ida, MINOR(dev)); } EXPORT_SYMBOL(free_anon_bdev); diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index e8e0e71b29d5..f999dbb4db7c 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -30,7 +30,6 @@ DEFINE_SPINLOCK(sysfs_assoc_lock); #define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb); -static DEFINE_SPINLOCK(sysfs_ino_lock); static DEFINE_IDA(sysfs_ino_ida); /** @@ -234,28 +233,19 @@ static void sysfs_deactivate(struct sysfs_dirent *sd) static int sysfs_alloc_ino(unsigned int *pino) { - int ino, rc; + int ino = ida_simple_get(&sysfs_ino_ida, 2, 0, GFP_KERNEL); - retry: - spin_lock(&sysfs_ino_lock); - rc = ida_get_new_above(&sysfs_ino_ida, 2, &ino); - spin_unlock(&sysfs_ino_lock); - - if (rc == -EAGAIN) { - if (ida_pre_get(&sysfs_ino_ida, GFP_KERNEL)) - goto retry; - rc = -ENOMEM; - } + if (ino < 0) + return ino; *pino = ino; - return rc; + return 0; + } static void sysfs_free_ino(unsigned int ino) { - spin_lock(&sysfs_ino_lock); - ida_remove(&sysfs_ino_ida, ino); - spin_unlock(&sysfs_ino_lock); + ida_simple_remove(&sysfs_ino_ida, ino); } void release_sysfs_dirent(struct sysfs_dirent * sd) diff --git a/include/linux/idr.h b/include/linux/idr.h index 871a213a8477..43f915193fb6 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -219,9 +219,6 @@ struct ida { #define IDA_INIT(name) { .idr = IDR_INIT((name).idr), .free_bitmap = NULL, } #define DEFINE_IDA(name) struct ida name = IDA_INIT(name) -int ida_pre_get(struct ida *ida, gfp_t gfp_mask); -int ida_get_new_above(struct ida *ida, int starting_id, int *p_id); -void ida_remove(struct ida *ida, int id); void ida_destroy(struct ida *ida); void ida_init(struct ida *ida); @@ -229,18 +226,6 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, gfp_t gfp_mask); void ida_simple_remove(struct ida *ida, unsigned int id); -/** - * ida_get_new - allocate new ID - * @ida: idr handle - * @p_id: pointer to the allocated handle - * - * Simple wrapper around ida_get_new_above() w/ @starting_id of zero. - */ -static inline int ida_get_new(struct ida *ida, int *p_id) -{ - return ida_get_new_above(ida, 0, p_id); -} - void __init idr_init_cache(void); #endif /* __IDR_H__ */ diff --git a/kernel/cgroup.c b/kernel/cgroup.c index a7c9e6ddb979..690f67254f89 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -190,8 +190,6 @@ static LIST_HEAD(roots); static int root_count; static DEFINE_IDA(hierarchy_ida); -static int next_hierarchy_id; -static DEFINE_SPINLOCK(hierarchy_id_lock); /* dummytop is a shorthand for the dummy hierarchy's top cgroup */ #define dummytop (&rootnode.top_cgroup) @@ -1428,26 +1426,11 @@ static void init_cgroup_root(struct cgroupfs_root *root) static bool init_root_id(struct cgroupfs_root *root) { - int ret = 0; + int ret = ida_simple_get(&hierarchy_ida, 0, 0, GFP_KERNEL); + if (ret < 0) + return false; - do { - if (!ida_pre_get(&hierarchy_ida, GFP_KERNEL)) - return false; - spin_lock(&hierarchy_id_lock); - /* Try to allocate the next unused ID */ - ret = ida_get_new_above(&hierarchy_ida, next_hierarchy_id, - &root->hierarchy_id); - if (ret == -ENOSPC) - /* Try again starting from 0 */ - ret = ida_get_new(&hierarchy_ida, &root->hierarchy_id); - if (!ret) { - next_hierarchy_id = root->hierarchy_id + 1; - } else if (ret != -EAGAIN) { - /* Can only get here if the 31-bit IDR is full ... */ - BUG_ON(ret); - } - spin_unlock(&hierarchy_id_lock); - } while (ret); + root->hierarchy_id = ret; return true; } @@ -1506,9 +1489,7 @@ static void cgroup_drop_root(struct cgroupfs_root *root) return; BUG_ON(!root->hierarchy_id); - spin_lock(&hierarchy_id_lock); - ida_remove(&hierarchy_ida, root->hierarchy_id); - spin_unlock(&hierarchy_id_lock); + ida_simple_remove(&hierarchy_ida, root->hierarchy_id); ida_destroy(&root->cgroup_ida); kfree(root); } diff --git a/lib/idr.c b/lib/idr.c index cca4b9302a71..d57bb81e481d 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -912,7 +912,7 @@ static void free_bitmap(struct ida *ida, struct ida_bitmap *bitmap) * If the system is REALLY out of memory this function returns %0, * otherwise %1. */ -int ida_pre_get(struct ida *ida, gfp_t gfp_mask) +static int ida_pre_get(struct ida *ida, gfp_t gfp_mask) { /* allocate idr_layers */ if (!__idr_pre_get(&ida->idr, gfp_mask)) @@ -931,7 +931,6 @@ int ida_pre_get(struct ida *ida, gfp_t gfp_mask) return 1; } -EXPORT_SYMBOL(ida_pre_get); /** * ida_get_new_above - allocate new ID above or equal to a start id @@ -948,7 +947,7 @@ EXPORT_SYMBOL(ida_pre_get); * * @p_id returns a value in the range @starting_id ... %0x7fffffff. */ -int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) +static int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) { struct idr_layer *pa[MAX_IDR_LEVEL + 1]; struct ida_bitmap *bitmap; @@ -1019,14 +1018,8 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) return 0; } -EXPORT_SYMBOL(ida_get_new_above); -/** - * ida_remove - remove the given ID - * @ida: ida handle - * @id: ID to free - */ -void ida_remove(struct ida *ida, int id) +static void ida_remove(struct ida *ida, int id) { struct idr_layer *p = ida->idr.top; int shift = (ida->idr.layers - 1) * IDR_BITS; @@ -1067,7 +1060,6 @@ void ida_remove(struct ida *ida, int id) printk(KERN_WARNING "ida_remove called for id=%d which is not allocated.\n", id); } -EXPORT_SYMBOL(ida_remove); /** * ida_destroy - release all cached layers within an ida tree diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index f97652036754..e8c452de7e7b 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -500,22 +500,18 @@ static int register_pernet_operations(struct list_head *list, int error; if (ops->id) { -again: - error = ida_get_new_above(&net_generic_ids, 1, ops->id); - if (error < 0) { - if (error == -EAGAIN) { - ida_pre_get(&net_generic_ids, GFP_KERNEL); - goto again; - } - return error; - } + int id = ida_simple_get(&net_generic_ids, 1, 0, GFP_KERNEL); + if (id < 0) + return id; + + *ops->id = id; max_gen_ptrs = max_t(unsigned int, max_gen_ptrs, *ops->id); } error = __register_pernet_operations(list, ops); if (error) { rcu_barrier(); if (ops->id) - ida_remove(&net_generic_ids, *ops->id); + ida_simple_remove(&net_generic_ids, *ops->id); } return error; @@ -523,11 +519,10 @@ again: static void unregister_pernet_operations(struct pernet_operations *ops) { - __unregister_pernet_operations(ops); rcu_barrier(); if (ops->id) - ida_remove(&net_generic_ids, *ops->id); + ida_simple_remove(&net_generic_ids, *ops->id); } /** |