summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <koverstreet@google.com>2013-06-16 17:09:25 -0700
committerKent Overstreet <koverstreet@google.com>2013-06-17 19:36:54 -0700
commitcbb1cb646122276c3910caf3150f80b4c3f581d0 (patch)
treec944c3a3f533efd3f3114e2266e7cc064b632740
parentc1ae6e9b4db00023b9caed72af49a93abad46452 (diff)
idr: Convert code to ida_simple_get()
A lot of drivers were open coding ida_simple_get() - by converting them we can get rid of (crappy) ida_pre_get(), ida_get_new(), ida_remove() interfaces. The ida_simple_*() interfaces do their own locking, which means we can remove a fair amount of code. Additionally, some code was open coding ida_get_cyclic() (c.f. idr_alloc_cyclic()) - after digging into the git logs this seems to have entirely been a performance optimization. This patch removes the cyclic allocation - cyclic allocation as performance optimization is rather sketchy, and in a couple patches we're reimplementing ida from scratch and the new implementation should be a good deal faster. Signed-off-by: Kent Overstreet <koverstreet@google.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Tejun Heo <tj@kernel.org> Cc: Fengguang Wu <fengguang.wu@intel.com> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Matthew Wilcox <willy@linux.intel.com> Cc: Joshua Morris <josh.h.morris@us.ibm.com> Cc: Philip Kelleher <pjk1939@linux.vnet.ibm.com> Cc: David Airlie <airlied@linux.ie> Cc: "Michał Mirosław" <mirq-linux@rere.qmqm.pl> Cc: Boaz Harrosh <bharrosh@panasas.com> Cc: Benny Halevy <bhalevy@tonian.com> Cc: "James E.J. Bottomley" <JBottomley@parallels.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: Li Zefan <lizefan@huawei.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: Asai Thambi S P <asamymuthupa@micron.com> Cc: Selvan Mani <smani@micron.com> Cc: Sam Bradshaw <sbradshaw@micron.com> Cc: Wei Yongjun <yongjun_wei@trendmicro.com.cn> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> Cc: David Howells <dhowells@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Dave Jones <davej@redhat.com> Cc: Dave Airlie <airlied@redhat.com> Cc: Joerg Roedel <joro@8bytes.org> Cc: Alex Williamson <alex.williamson@redhat.com> Cc: Varun Sethi <Varun.Sethi@freescale.com> Cc: Alexey Kardashevskiy <aik@ozlabs.ru> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Alan Cox <alan@linux.intel.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Serge Hallyn <serge.hallyn@canonical.com> Cc: Mauro Carvalho Chehab <mchehab@redhat.com> Cc: Stephen Rothwell <sfr@canb.auug.org.au>
-rw-r--r--arch/powerpc/mm/icswx_pid.c38
-rw-r--r--arch/powerpc/mm/mmu_context_hash64.c30
-rw-r--r--drivers/base/soc.c22
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c30
-rw-r--r--drivers/block/nvme-core.c37
-rw-r--r--drivers/block/rsxx/core.c23
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c33
-rw-r--r--drivers/iommu/iommu.c22
-rw-r--r--drivers/misc/cb710/core.c21
-rw-r--r--drivers/scsi/osd/osd_uld.c13
-rw-r--r--drivers/scsi/sd.c23
-rw-r--r--fs/devpts/inode.c24
-rw-r--r--fs/namespace.c49
-rw-r--r--fs/nfs/nfs4state.c31
-rw-r--r--fs/proc/generic.c31
-rw-r--r--fs/super.c37
-rw-r--r--fs/sysfs/dir.c22
-rw-r--r--include/linux/idr.h15
-rw-r--r--kernel/cgroup.c29
-rw-r--r--lib/idr.c14
-rw-r--r--net/core/net_namespace.c19
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);
}
/**