Sedat Dilek (62):
      kbuild: deb-pkg: Try to determine distribution
      kbuild: deb-pkg: Bump year in debian/copyright file
      kbuild: deb-pkg: Update git repository URL in debian/copyright file
      Merge tag 'next-20130207' of git://git.kernel.org/.../next/linux-next into Linux-Next-v20130207
      Revert "nfs4client: convert to idr_alloc()"
      Revert "sctp: convert to idr_alloc()"
      Revert "mac80211: convert to idr_alloc()"
      Revert "net/9p: convert to idr_alloc()"
      Revert "posix-timers: convert to idr_alloc()"
      Revert "events: convert to idr_alloc()"
      Revert "cgroup: convert to idr_alloc()"
      Revert "ipc: convert to idr_alloc()"
      Revert "ocfs2: convert to idr_alloc()"
      Revert "inotify: convert to idr_alloc()"
      Revert "dlm: convert to idr_alloc()"
      Revert "vfio: convert to idr_alloc()"
      Revert "uio: convert to idr_alloc()"
      Revert "thermal: convert to idr_alloc()"
      Revert "scsi/lpfc: convert to idr_alloc()"
      Revert "target/iscsi: convert to idr_alloc()"
      Revert "scsi: convert to idr_alloc()"
      Revert "scsi/bfa: convert to idr_alloc()"
      Revert "rpmsg: convert to idr_alloc()"
      Revert "remoteproc: convert to idr_alloc()"
      Revert "pps: convert to idr_alloc()"
      Revert "power: convert to idr_alloc()"
      Revert "ppp: convert to idr_alloc()"
      Revert "macvtap: convert to idr_alloc()"
      Revert "mtd: convert to idr_alloc()"
      Revert "mmc: convert to idr_alloc()"
      Revert "misc/tifm_core: convert to idr_alloc()"
      Revert "misc/c2port: convert to idr_alloc()"
      Revert "mfd: convert to idr_alloc()"
      Revert "memstick: convert to idr_alloc()"
      Revert "dm: convert to idr_alloc()"
      Revert "IB/qib: convert to idr_alloc()"
      Revert "IB/ocrdma: convert to idr_alloc()"
      Revert "IB/mlx4: convert to idr_alloc()"
      Revert "IB/ipath: convert to idr_alloc()"
      Revert "IB/ehca: convert to idr_alloc()"
      Revert "IB/cxgb4: convert to idr_alloc()"
      Revert "IB/cxgb3: convert to idr_alloc()"
      Revert "IB/amso1100: convert to idr_alloc()"
      Revert "IB/core: convert to idr_alloc()"
      Revert "i2c: convert to idr_alloc()"
      Revert "drm/vmwgfx: convert to idr_alloc()"
      Revert "drm/via: convert to idr_alloc()"
      Revert "drm/sis: convert to idr_alloc()"
      Revert "drm/i915: convert to idr_alloc()"
      Revert "drm/exynos: convert to idr_alloc()"
      Revert "drm: convert to idr_alloc()"
      Revert "gpio: convert to idr_alloc()"
      Revert "firewire: convert to idr_alloc()"
      Revert "dmaengine: convert to idr_alloc()"
      Revert "dca: convert to idr_alloc()"
      Revert "drbd: convert to idr_alloc()"
      Revert "atm/nicstar: convert to idr_alloc()"
      Revert "block/loop: convert to idr_alloc()"
      Revert "block: convert to idr_alloc()"
      Revert "idr: implement idr_preload[_end]() and idr_alloc()"
      Merge branch 'deb-pkg-fixes' into 3.8.0-rc6-next20130207-2-iniza-small
      Merge branch 'revert-idr-from-akpm' into 3.8.0-rc6-next20130207-2-iniza-small

 block/bsg.c                                |  26 +++--
 block/genhd.c                              |  21 +++-
 drivers/atm/nicstar.c                      |  24 +++-
 drivers/block/drbd/drbd_main.c             |  29 ++---
 drivers/block/loop.c                       |  23 +++-
 drivers/dca/dca-sysfs.c                    |  23 ++--
 drivers/dma/dmaengine.c                    |  16 ++-
 drivers/firewire/core-cdev.c               |  19 ++--
 drivers/firewire/core-device.c             |   8 +-
 drivers/gpio/gpiolib.c                     |  11 +-
 drivers/gpu/drm/drm_context.c              |  17 ++-
 drivers/gpu/drm/drm_crtc.c                 |  19 +++-
 drivers/gpu/drm/drm_gem.c                  |  35 +++---
 drivers/gpu/drm/drm_stub.c                 |  19 +++-
 drivers/gpu/drm/exynos/exynos_drm_ipp.c    |  16 ++-
 drivers/gpu/drm/i915/i915_gem_context.c    |  21 +++-
 drivers/gpu/drm/sis/sis_mm.c               |  13 ++-
 drivers/gpu/drm/via/via_mm.c               |  13 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c   |  17 +--
 drivers/i2c/i2c-core.c                     |  45 ++++++--
 drivers/infiniband/core/cm.c               |  22 ++--
 drivers/infiniband/core/cma.c              |  24 ++--
 drivers/infiniband/core/sa_query.c         |  18 ++-
 drivers/infiniband/core/ucm.c              |  16 ++-
 drivers/infiniband/core/ucma.c             |  32 ++++--
 drivers/infiniband/core/uverbs_cmd.c       |  17 +--
 drivers/infiniband/hw/amso1100/c2_qp.c     |  19 ++--
 drivers/infiniband/hw/cxgb3/iwch.h         |  24 ++--
 drivers/infiniband/hw/cxgb4/iw_cxgb4.h     |  27 +++--
 drivers/infiniband/hw/ehca/ehca_cq.c       |  27 +++--
 drivers/infiniband/hw/ehca/ehca_qp.c       |  34 +++---
 drivers/infiniband/hw/ipath/ipath_driver.c |  16 ++-
 drivers/infiniband/hw/mlx4/cm.c            |  32 +++---
 drivers/infiniband/hw/ocrdma/ocrdma_main.c |  14 ++-
 drivers/infiniband/hw/qib/qib_init.c       |  21 ++--
 drivers/md/dm.c                            |  54 ++++++---
 drivers/memstick/core/memstick.c           |  21 ++--
 drivers/memstick/core/mspro_block.c        |  17 ++-
 drivers/mfd/rtsx_pcr.c                     |  13 ++-
 drivers/misc/c2port/core.c                 |  22 ++--
 drivers/misc/tifm_core.c                   |  11 +-
 drivers/mmc/core/host.c                    |  11 +-
 drivers/mtd/mtdcore.c                      |   9 +-
 drivers/net/macvtap.c                      |  21 +++-
 drivers/net/ppp/ppp_generic.c              |  33 +++++-
 drivers/power/bq2415x_charger.c            |  11 +-
 drivers/power/bq27x00_battery.c            |   9 +-
 drivers/power/ds2782_battery.c             |   9 +-
 drivers/pps/kapi.c                         |   2 +-
 drivers/pps/pps.c                          |  36 +++---
 drivers/remoteproc/remoteproc_core.c       |  10 +-
 drivers/rpmsg/virtio_rpmsg_bus.c           |  30 +++--
 drivers/scsi/bfa/bfad_im.c                 |  15 ++-
 drivers/scsi/ch.c                          |  21 ++--
 drivers/scsi/lpfc/lpfc_init.c              |  12 +-
 drivers/scsi/sg.c                          |  43 +++++---
 drivers/scsi/st.c                          |  27 +++--
 drivers/target/iscsi/iscsi_target.c        |  15 ++-
 drivers/target/iscsi/iscsi_target_login.c  |  15 ++-
 drivers/thermal/cpu_cooling.c              |  17 ++-
 drivers/thermal/thermal_sys.c              |  17 ++-
 drivers/uio/uio.c                          |  19 +++-
 drivers/vfio/vfio.c                        |  17 ++-
 fs/dlm/lock.c                              |  18 ++-
 fs/dlm/recover.c                           |  27 ++---
 fs/nfs/nfs4client.c                        |  13 ++-
 fs/notify/inotify/inotify_user.c           |  24 ++--
 fs/ocfs2/cluster/tcp.c                     |  32 +++---
 include/linux/idr.h                        |  14 ---
 ipc/util.c                                 |  30 +++--
 kernel/cgroup.c                            |  27 +++--
 kernel/events/core.c                       |  10 +-
 kernel/posix-timers.c                      |  18 +--
 lib/idr.c                                  | 171 ++---------------------------
 net/9p/util.c                              |  17 ++-
 net/mac80211/main.c                        |   2 +
 net/mac80211/tx.c                          |  18 ++-
 net/sctp/associola.c                       |  31 +++---
 scripts/package/builddeb                   |  19 +++-
 79 files changed, 1049 insertions(+), 717 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index 420a5a9..e334bd9 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -996,7 +996,7 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
 {
 	struct bsg_class_device *bcd;
 	dev_t dev;
-	int ret;
+	int ret, minor;
 	struct device *class_dev = NULL;
 	const char *devname;
 
@@ -1016,16 +1016,23 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
 
 	mutex_lock(&bsg_mutex);
 
-	ret = idr_alloc(&bsg_minor_idr, bcd, 0, BSG_MAX_DEVS, GFP_KERNEL);
-	if (ret < 0) {
-		if (ret == -ENOSPC) {
-			printk(KERN_ERR "bsg: too many bsg devices\n");
-			ret = -EINVAL;
-		}
+	ret = idr_pre_get(&bsg_minor_idr, GFP_KERNEL);
+	if (!ret) {
+		ret = -ENOMEM;
 		goto unlock;
 	}
 
-	bcd->minor = ret;
+	ret = idr_get_new(&bsg_minor_idr, bcd, &minor);
+	if (ret < 0)
+		goto unlock;
+
+	if (minor >= BSG_MAX_DEVS) {
+		printk(KERN_ERR "bsg: too many bsg devices\n");
+		ret = -EINVAL;
+		goto remove_idr;
+	}
+
+	bcd->minor = minor;
 	bcd->queue = q;
 	bcd->parent = get_device(parent);
 	bcd->release = release;
@@ -1051,7 +1058,8 @@ unregister_class_dev:
 	device_unregister(class_dev);
 put_dev:
 	put_device(parent);
-	idr_remove(&bsg_minor_idr, bcd->minor);
+remove_idr:
+	idr_remove(&bsg_minor_idr, minor);
 unlock:
 	mutex_unlock(&bsg_mutex);
 	return ret;
diff --git a/block/genhd.c b/block/genhd.c
index a1ed52a..d4e7370 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -411,7 +411,7 @@ static int blk_mangle_minor(int minor)
 int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
 {
 	struct gendisk *disk = part_to_disk(part);
-	int idx;
+	int idx, rc;
 
 	/* in consecutive minor range? */
 	if (part->partno < disk->minors) {
@@ -420,11 +420,20 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
 	}
 
 	/* allocate ext devt */
-	mutex_lock(&ext_devt_mutex);
-	idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_KERNEL);
-	mutex_unlock(&ext_devt_mutex);
-	if (idx < 0)
-		return idx == -ENOSPC ? -EBUSY : idx;
+	do {
+		if (!idr_pre_get(&ext_devt_idr, GFP_KERNEL))
+			return -ENOMEM;
+		mutex_lock(&ext_devt_mutex);
+		rc = idr_get_new(&ext_devt_idr, part, &idx);
+		if (!rc && idx >= NR_EXT_DEVT) {
+			idr_remove(&ext_devt_idr, idx);
+			rc = -EBUSY;
+		}
+		mutex_unlock(&ext_devt_mutex);
+	} while (rc == -EAGAIN);
+
+	if (rc)
+		return rc;
 
 	*devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
 	return 0;
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 6587dc2..628787e 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -949,10 +949,11 @@ static void free_scq(ns_dev *card, scq_info *scq, struct atm_vcc *vcc)
 static void push_rxbufs(ns_dev * card, struct sk_buff *skb)
 {
 	struct sk_buff *handle1, *handle2;
-	int id1, id2;
+	u32 id1 = 0, id2 = 0;
 	u32 addr1, addr2;
 	u32 stat;
 	unsigned long flags;
+	int err;
 
 	/* *BARF* */
 	handle2 = NULL;
@@ -1025,12 +1026,23 @@ static void push_rxbufs(ns_dev * card, struct sk_buff *skb)
 				card->lbfqc += 2;
 		}
 
-		id1 = idr_alloc(&card->idr, handle1, 0, 0, GFP_ATOMIC);
-		if (id1 < 0)
-			goto out;
+		do {
+			if (!idr_pre_get(&card->idr, GFP_ATOMIC)) {
+				printk(KERN_ERR
+				       "nicstar%d: no free memory for idr\n",
+				       card->index);
+				goto out;
+			}
+
+			if (!id1)
+				err = idr_get_new_above(&card->idr, handle1, 0, &id1);
+
+			if (!id2 && err == 0)
+				err = idr_get_new_above(&card->idr, handle2, 0, &id2);
+
+		} while (err == -EAGAIN);
 
-		id2 = idr_alloc(&card->idr, handle2, 0, 0, GFP_ATOMIC);
-		if (id2 < 0)
+		if (err)
 			goto out;
 
 		spin_lock_irqsave(&card->res_lock, flags);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e98da67..8c13eeb 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2660,24 +2660,25 @@ enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor,
 	mdev->read_requests = RB_ROOT;
 	mdev->write_requests = RB_ROOT;
 
-	minor_got = idr_alloc(&minors, mdev, minor, minor + 1, GFP_KERNEL);
-	if (minor_got < 0) {
-		if (minor_got == -ENOSPC) {
-			err = ERR_MINOR_EXISTS;
-			drbd_msg_put_info("requested minor exists already");
-		}
+	if (!idr_pre_get(&minors, GFP_KERNEL))
+		goto out_no_minor_idr;
+	if (idr_get_new_above(&minors, mdev, minor, &minor_got))
 		goto out_no_minor_idr;
+	if (minor_got != minor) {
+		err = ERR_MINOR_EXISTS;
+		drbd_msg_put_info("requested minor exists already");
+		goto out_idr_remove_minor;
 	}
 
-	vnr_got = idr_alloc(&tconn->volumes, mdev, vnr, vnr + 1, GFP_KERNEL);
-	if (vnr_got < 0) {
-		if (vnr_got == -ENOSPC) {
-			err = ERR_INVALID_REQUEST;
-			drbd_msg_put_info("requested volume exists already");
-		}
+	if (!idr_pre_get(&tconn->volumes, GFP_KERNEL))
+		goto out_idr_remove_minor;
+	if (idr_get_new_above(&tconn->volumes, mdev, vnr, &vnr_got))
 		goto out_idr_remove_minor;
+	if (vnr_got != vnr) {
+		err = ERR_INVALID_REQUEST;
+		drbd_msg_put_info("requested volume exists already");
+		goto out_idr_remove_vol;
 	}
-
 	add_disk(disk);
 	kref_init(&mdev->kref); /* one ref for both idrs and the the add_disk */
 
@@ -2688,6 +2689,8 @@ enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor,
 
 	return NO_ERROR;
 
+out_idr_remove_vol:
+	idr_remove(&tconn->volumes, vnr_got);
 out_idr_remove_minor:
 	idr_remove(&minors, minor_got);
 	synchronize_rcu();
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 56a3963..dc3891e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1611,17 +1611,30 @@ static int loop_add(struct loop_device **l, int i)
 	if (!lo)
 		goto out;
 
-	/* allocate id, if @id >= 0, we're requesting that specific id */
+	if (!idr_pre_get(&loop_index_idr, GFP_KERNEL))
+		goto out_free_dev;
+
 	if (i >= 0) {
-		err = idr_alloc(&loop_index_idr, lo, i, i + 1, GFP_KERNEL);
-		if (err == -ENOSPC)
+		int m;
+
+		/* create specific i in the index */
+		err = idr_get_new_above(&loop_index_idr, lo, i, &m);
+		if (err >= 0 && i != m) {
+			idr_remove(&loop_index_idr, m);
 			err = -EEXIST;
+		}
+	} else if (i == -1) {
+		int m;
+
+		/* get next free nr */
+		err = idr_get_new(&loop_index_idr, lo, &m);
+		if (err >= 0)
+			i = m;
 	} else {
-		err = idr_alloc(&loop_index_idr, lo, 0, 0, GFP_KERNEL);
+		err = -EINVAL;
 	}
 	if (err < 0)
 		goto out_free_dev;
-	i = err;
 
 	lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
 	if (!lo->lo_queue)
diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
index 126cf29..591b659 100644
--- a/drivers/dca/dca-sysfs.c
+++ b/drivers/dca/dca-sysfs.c
@@ -53,19 +53,22 @@ void dca_sysfs_remove_req(struct dca_provider *dca, int slot)
 int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev)
 {
 	struct device *cd;
-	int ret;
+	int err = 0;
 
-	idr_preload(GFP_KERNEL);
+idr_try_again:
+	if (!idr_pre_get(&dca_idr, GFP_KERNEL))
+		return -ENOMEM;
 	spin_lock(&dca_idr_lock);
-
-	ret = idr_alloc(&dca_idr, dca, 0, 0, GFP_NOWAIT);
-	if (ret >= 0)
-		dca->id = ret;
-
+	err = idr_get_new(&dca_idr, dca, &dca->id);
 	spin_unlock(&dca_idr_lock);
-	idr_preload_end();
-	if (ret < 0)
-		return ret;
+	switch (err) {
+	case 0:
+		break;
+	case -EAGAIN:
+		goto idr_try_again;
+	default:
+		return err;
+	}
 
 	cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id);
 	if (IS_ERR(cd)) {
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index b2728d6..242b8c0 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -686,14 +686,18 @@ static int get_dma_id(struct dma_device *device)
 {
 	int rc;
 
+ idr_retry:
+	if (!idr_pre_get(&dma_idr, GFP_KERNEL))
+		return -ENOMEM;
 	mutex_lock(&dma_list_mutex);
-
-	rc = idr_alloc(&dma_idr, NULL, 0, 0, GFP_KERNEL);
-	if (rc >= 0)
-		device->dev_id = rc;
-
+	rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
 	mutex_unlock(&dma_list_mutex);
-	return rc < 0 ? rc : 0;
+	if (rc == -EAGAIN)
+		goto idr_retry;
+	else if (rc != 0)
+		return rc;
+
+	return 0;
 }
 
 /**
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 27ac423..68c3138 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -487,28 +487,27 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
 static int add_client_resource(struct client *client,
 			       struct client_resource *resource, gfp_t gfp_mask)
 {
-	bool preload = gfp_mask & __GFP_WAIT;
 	unsigned long flags;
 	int ret;
 
-	if (preload)
-		idr_preload(gfp_mask);
-	spin_lock_irqsave(&client->lock, flags);
+ retry:
+	if (idr_pre_get(&client->resource_idr, gfp_mask) == 0)
+		return -ENOMEM;
 
+	spin_lock_irqsave(&client->lock, flags);
 	if (client->in_shutdown)
 		ret = -ECANCELED;
 	else
-		ret = idr_alloc(&client->resource_idr, resource, 0, 0,
-				GFP_NOWAIT);
+		ret = idr_get_new(&client->resource_idr, resource,
+				  &resource->handle);
 	if (ret >= 0) {
-		resource->handle = ret;
 		client_get(client);
 		schedule_if_iso_resource(resource);
 	}
-
 	spin_unlock_irqrestore(&client->lock, flags);
-	if (preload)
-		idr_preload_end();
+
+	if (ret == -EAGAIN)
+		goto retry;
 
 	return ret < 0 ? ret : 0;
 }
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index b946330..af3e8aa 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -1017,7 +1017,13 @@ static void fw_device_init(struct work_struct *work)
 
 	fw_device_get(device);
 	down_write(&fw_device_rwsem);
-	ret = idr_alloc(&fw_device_idr, device, 0, 1 << MINORBITS, GFP_KERNEL);
+	ret = idr_pre_get(&fw_device_idr, GFP_KERNEL) ?
+	      idr_get_new(&fw_device_idr, device, &minor) :
+	      -ENOMEM;
+	if (minor >= 1 << MINORBITS) {
+		idr_remove(&fw_device_idr, minor);
+		minor = -ENOSPC;
+	}
 	up_write(&fw_device_rwsem);
 
 	if (ret < 0)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 9b37b90..e14eb88 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -358,10 +358,15 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
 			goto err_out;
 		}
 
-		ret = idr_alloc(&dirent_idr, value_sd, 1, 0, GFP_KERNEL);
-		if (ret < 0)
+		do {
+			ret = -ENOMEM;
+			if (idr_pre_get(&dirent_idr, GFP_KERNEL))
+				ret = idr_get_new_above(&dirent_idr, value_sd,
+							1, &id);
+		} while (ret == -EAGAIN);
+
+		if (ret)
 			goto free_sd;
-		id = ret;
 
 		desc->flags &= GPIO_FLAGS_MASK;
 		desc->flags |= (unsigned long)id << ID_SHIFT;
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 725968d..75f62c5 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -74,13 +74,24 @@ void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
  */
 static int drm_ctxbitmap_next(struct drm_device * dev)
 {
+	int new_id;
 	int ret;
 
+again:
+	if (idr_pre_get(&dev->ctx_idr, GFP_KERNEL) == 0) {
+		DRM_ERROR("Out of memory expanding drawable idr\n");
+		return -ENOMEM;
+	}
 	mutex_lock(&dev->struct_mutex);
-	ret = idr_alloc(&dev->ctx_idr, NULL, DRM_RESERVED_CONTEXTS, 0,
-			GFP_KERNEL);
+	ret = idr_get_new_above(&dev->ctx_idr, NULL,
+				DRM_RESERVED_CONTEXTS, &new_id);
 	mutex_unlock(&dev->struct_mutex);
-	return ret;
+	if (ret == -EAGAIN)
+		goto again;
+	else if (ret)
+		return ret;
+
+	return new_id;
 }
 
 /**
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 838c9b6..775102d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -252,21 +252,32 @@ char *drm_get_connector_status_name(enum drm_connector_status status)
 static int drm_mode_object_get(struct drm_device *dev,
 			       struct drm_mode_object *obj, uint32_t obj_type)
 {
+	int new_id = 0;
 	int ret;
 
+again:
+	if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
+		DRM_ERROR("Ran out memory getting a mode number\n");
+		return -ENOMEM;
+	}
+
 	mutex_lock(&dev->mode_config.idr_mutex);
-	ret = idr_alloc(&dev->mode_config.crtc_idr, obj, 1, 0, GFP_KERNEL);
-	if (ret >= 0) {
+	ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
+
+	if (!ret) {
 		/*
 		 * Set up the object linking under the protection of the idr
 		 * lock so that other users can't see inconsistent state.
 		 */
-		obj->id = ret;
+		obj->id = new_id;
 		obj->type = obj_type;
 	}
 	mutex_unlock(&dev->mode_config.idr_mutex);
 
-	return ret < 0 ? ret : 0;
+	if (ret == -EAGAIN)
+		goto again;
+
+	return ret;
 }
 
 /**
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 6577514..e775859 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -270,19 +270,21 @@ drm_gem_handle_create(struct drm_file *file_priv,
 	int ret;
 
 	/*
-	 * Get the user-visible handle using idr.  Preload and perform
-	 * allocation under our spinlock.
+	 * Get the user-visible handle using idr.
 	 */
-	idr_preload(GFP_KERNEL);
-	spin_lock(&file_priv->table_lock);
-
-	ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
+again:
+	/* ensure there is space available to allocate a handle */
+	if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0)
+		return -ENOMEM;
 
+	/* do the allocation under our spinlock */
+	spin_lock(&file_priv->table_lock);
+	ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep);
 	spin_unlock(&file_priv->table_lock);
-	idr_preload_end();
-	if (ret < 0)
+	if (ret == -EAGAIN)
+		goto again;
+	else if (ret)
 		return ret;
-	*handlep = ret;
 
 	drm_gem_object_handle_reference(obj);
 
@@ -449,15 +451,22 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
 	if (obj == NULL)
 		return -ENOENT;
 
-	idr_preload(GFP_KERNEL);
+again:
+	if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
 	spin_lock(&dev->object_name_lock);
 	if (!obj->name) {
-		ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_NOWAIT);
-		obj->name = ret;
+		ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
+					&obj->name);
 		args->name = (uint64_t) obj->name;
 		spin_unlock(&dev->object_name_lock);
 
-		if (ret < 0)
+		if (ret == -EAGAIN)
+			goto again;
+		else if (ret)
 			goto err;
 
 		/* Allocate a reference for the name table.  */
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 7d30802..200e104 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -109,6 +109,7 @@ EXPORT_SYMBOL(drm_ut_debug_printk);
 
 static int drm_minor_get_id(struct drm_device *dev, int type)
 {
+	int new_id;
 	int ret;
 	int base = 0, limit = 63;
 
@@ -120,11 +121,25 @@ static int drm_minor_get_id(struct drm_device *dev, int type)
                 limit = base + 255;
         }
 
+again:
+	if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) {
+		DRM_ERROR("Out of memory expanding drawable idr\n");
+		return -ENOMEM;
+	}
 	mutex_lock(&dev->struct_mutex);
-	ret = idr_alloc(&drm_minors_idr, NULL, base, limit, GFP_KERNEL);
+	ret = idr_get_new_above(&drm_minors_idr, NULL,
+				base, &new_id);
 	mutex_unlock(&dev->struct_mutex);
+	if (ret == -EAGAIN)
+		goto again;
+	else if (ret)
+		return ret;
 
-	return ret == -ENOSPC ? -EINVAL : ret;
+	if (new_id >= limit) {
+		idr_remove(&drm_minors_idr, new_id);
+		return -EINVAL;
+	}
+	return new_id;
 }
 
 struct drm_master *drm_master_create(struct drm_minor *minor)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 1adce07..90398df 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -137,15 +137,21 @@ static int ipp_create_id(struct idr *id_idr, struct mutex *lock, void *obj,
 
 	DRM_DEBUG_KMS("%s\n", __func__);
 
+again:
+	/* ensure there is space available to allocate a handle */
+	if (idr_pre_get(id_idr, GFP_KERNEL) == 0) {
+		DRM_ERROR("failed to get idr.\n");
+		return -ENOMEM;
+	}
+
 	/* do the allocation under our mutexlock */
 	mutex_lock(lock);
-	ret = idr_alloc(id_idr, obj, 1, 0, GFP_KERNEL);
+	ret = idr_get_new_above(id_idr, obj, 1, (int *)idp);
 	mutex_unlock(lock);
-	if (ret < 0)
-		return ret;
+	if (ret == -EAGAIN)
+		goto again;
 
-	*idp = ret;
-	return 0;
+	return ret;
 }
 
 static void *ipp_find_obj(struct idr *id_idr, struct mutex *lock, u32 id)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 27e586a..a3f06bc 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -144,7 +144,7 @@ create_hw_context(struct drm_device *dev,
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct i915_hw_context *ctx;
-	int ret;
+	int ret, id;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (ctx == NULL)
@@ -169,11 +169,22 @@ create_hw_context(struct drm_device *dev,
 
 	ctx->file_priv = file_priv;
 
-	ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0,
-			GFP_KERNEL);
-	if (ret < 0)
+again:
+	if (idr_pre_get(&file_priv->context_idr, GFP_KERNEL) == 0) {
+		ret = -ENOMEM;
+		DRM_DEBUG_DRIVER("idr allocation failed\n");
+		goto err_out;
+	}
+
+	ret = idr_get_new_above(&file_priv->context_idr, ctx,
+				DEFAULT_CONTEXT_ID + 1, &id);
+	if (ret == 0)
+		ctx->id = id;
+
+	if (ret == -EAGAIN)
+		goto again;
+	else if (ret)
 		goto err_out;
-	ctx->id = ret;
 
 	return ctx;
 
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
index 9a43d98..2b2f78c 100644
--- a/drivers/gpu/drm/sis/sis_mm.c
+++ b/drivers/gpu/drm/sis/sis_mm.c
@@ -128,10 +128,17 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
 	if (retval)
 		goto fail_alloc;
 
-	retval = idr_alloc(&dev_priv->object_idr, item, 1, 0, GFP_KERNEL);
-	if (retval < 0)
+again:
+	if (idr_pre_get(&dev_priv->object_idr, GFP_KERNEL) == 0) {
+		retval = -ENOMEM;
+		goto fail_idr;
+	}
+
+	retval = idr_get_new_above(&dev_priv->object_idr, item, 1, &user_key);
+	if (retval == -EAGAIN)
+		goto again;
+	if (retval)
 		goto fail_idr;
-	user_key = retval;
 
 	list_add(&item->owner_list, &file_priv->obj_list);
 	mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index 0ab93ff..0d55432 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -148,10 +148,17 @@ int via_mem_alloc(struct drm_device *dev, void *data,
 	if (retval)
 		goto fail_alloc;
 
-	retval = idr_alloc(&dev_priv->object_idr, item, 1, 0, GFP_KERNEL);
-	if (retval < 0)
+again:
+	if (idr_pre_get(&dev_priv->object_idr, GFP_KERNEL) == 0) {
+		retval = -ENOMEM;
+		goto fail_idr;
+	}
+
+	retval = idr_get_new_above(&dev_priv->object_idr, item, 1, &user_key);
+	if (retval == -EAGAIN)
+		goto again;
+	if (retval)
 		goto fail_idr;
-	user_key = retval;
 
 	list_add(&item->owner_list, &file_priv->obj_list);
 	mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index c9d0676..e01a17b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -177,16 +177,17 @@ int vmw_resource_alloc_id(struct vmw_resource *res)
 
 	BUG_ON(res->id != -1);
 
-	idr_preload(GFP_KERNEL);
-	write_lock(&dev_priv->resource_lock);
+	do {
+		if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
+			return -ENOMEM;
 
-	ret = idr_alloc(idr, res, 1, 0, GFP_NOWAIT);
-	if (ret >= 0)
-		res->id = ret;
+		write_lock(&dev_priv->resource_lock);
+		ret = idr_get_new_above(idr, res, 1, &res->id);
+		write_unlock(&dev_priv->resource_lock);
 
-	write_unlock(&dev_priv->resource_lock);
-	idr_preload_end();
-	return ret < 0 ? ret : 0;
+	} while (ret == -EAGAIN);
+
+	return ret;
 }
 
 /**
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 795c916..66a30f7 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -935,16 +935,25 @@ out_list:
  */
 int i2c_add_adapter(struct i2c_adapter *adapter)
 {
-	int res;
+	int	id, res = 0;
+
+retry:
+	if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
+		return -ENOMEM;
 
 	mutex_lock(&core_lock);
-	res = idr_alloc(&i2c_adapter_idr, adapter,
-			__i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
+	/* "above" here means "above or equal to", sigh */
+	res = idr_get_new_above(&i2c_adapter_idr, adapter,
+				__i2c_first_dynamic_bus_num, &id);
 	mutex_unlock(&core_lock);
-	if (res < 0)
+
+	if (res < 0) {
+		if (res == -EAGAIN)
+			goto retry;
 		return res;
+	}
 
-	adapter->nr = res;
+	adapter->nr = id;
 	return i2c_register_adapter(adapter);
 }
 EXPORT_SYMBOL(i2c_add_adapter);
@@ -975,17 +984,33 @@ EXPORT_SYMBOL(i2c_add_adapter);
 int i2c_add_numbered_adapter(struct i2c_adapter *adap)
 {
 	int	id;
+	int	status;
 
 	if (adap->nr == -1) /* -1 means dynamically assign bus id */
 		return i2c_add_adapter(adap);
+	if (adap->nr & ~MAX_IDR_MASK)
+		return -EINVAL;
+
+retry:
+	if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
+		return -ENOMEM;
 
 	mutex_lock(&core_lock);
-	id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,
-		       GFP_KERNEL);
+	/* "above" here means "above or equal to", sigh;
+	 * we need the "equal to" result to force the result
+	 */
+	status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id);
+	if (status == 0 && id != adap->nr) {
+		status = -EBUSY;
+		idr_remove(&i2c_adapter_idr, id);
+	}
 	mutex_unlock(&core_lock);
-	if (id < 0)
-		return id == -ENOSPC ? -EBUSY : id;
-	return 0;
+	if (status == -EAGAIN)
+		goto retry;
+
+	if (status == 0)
+		status = i2c_register_adapter(adap);
+	return status;
 }
 EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
 
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 98281fe..394fea2 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -382,21 +382,20 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
 static int cm_alloc_id(struct cm_id_private *cm_id_priv)
 {
 	unsigned long flags;
-	int id;
+	int ret, id;
 	static int next_id;
 
-	idr_preload(GFP_KERNEL);
-	spin_lock_irqsave(&cm.lock, flags);
-
-	id = idr_alloc(&cm.local_id_table, cm_id_priv, next_id, 0, GFP_NOWAIT);
-	if (id >= 0)
-		next_id = ((unsigned) id + 1) & MAX_IDR_MASK;
-
-	spin_unlock_irqrestore(&cm.lock, flags);
-	idr_preload_end();
+	do {
+		spin_lock_irqsave(&cm.lock, flags);
+		ret = idr_get_new_above(&cm.local_id_table, cm_id_priv,
+					next_id, &id);
+		if (!ret)
+			next_id = ((unsigned) id + 1) & MAX_IDR_MASK;
+		spin_unlock_irqrestore(&cm.lock, flags);
+	} while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) );
 
 	cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand;
-	return id < 0 ? id : 0;
+	return ret;
 }
 
 static void cm_free_id(__be32 local_id)
@@ -3845,6 +3844,7 @@ static int __init ib_cm_init(void)
 	cm.remote_sidr_table = RB_ROOT;
 	idr_init(&cm.local_id_table);
 	get_random_bytes(&cm.random_id_operand, sizeof cm.random_id_operand);
+	idr_pre_get(&cm.local_id_table, GFP_KERNEL);
 	INIT_LIST_HEAD(&cm.timewait_list);
 
 	ret = class_register(&cm_class);
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 71c2c71..0822536 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -2143,23 +2143,33 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
 			  unsigned short snum)
 {
 	struct rdma_bind_list *bind_list;
-	int ret;
+	int port, ret;
 
 	bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL);
 	if (!bind_list)
 		return -ENOMEM;
 
-	ret = idr_alloc(ps, bind_list, snum, snum + 1, GFP_KERNEL);
-	if (ret < 0)
-		goto err;
+	do {
+		ret = idr_get_new_above(ps, bind_list, snum, &port);
+	} while ((ret == -EAGAIN) && idr_pre_get(ps, GFP_KERNEL));
+
+	if (ret)
+		goto err1;
+
+	if (port != snum) {
+		ret = -EADDRNOTAVAIL;
+		goto err2;
+	}
 
 	bind_list->ps = ps;
-	bind_list->port = (unsigned short)ret;
+	bind_list->port = (unsigned short) port;
 	cma_bind_port(bind_list, id_priv);
 	return 0;
-err:
+err2:
+	idr_remove(ps, port);
+err1:
 	kfree(bind_list);
-	return ret == -ENOSPC ? -EADDRNOTAVAIL : ret;
+	return ret;
 }
 
 static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv)
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 934f45e..a8905ab 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -611,21 +611,19 @@ static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
 
 static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
 {
-	bool preload = gfp_mask & __GFP_WAIT;
 	unsigned long flags;
 	int ret, id;
 
-	if (preload)
-		idr_preload(gfp_mask);
+retry:
+	if (!idr_pre_get(&query_idr, gfp_mask))
+		return -ENOMEM;
 	spin_lock_irqsave(&idr_lock, flags);
-
-	id = idr_alloc(&query_idr, query, 0, 0, GFP_NOWAIT);
-
+	ret = idr_get_new(&query_idr, query, &id);
 	spin_unlock_irqrestore(&idr_lock, flags);
-	if (preload)
-		idr_preload_end();
-	if (id < 0)
-		return id;
+	if (ret == -EAGAIN)
+		goto retry;
+	if (ret)
+		return ret;
 
 	query->mad_buf->timeout_ms  = timeout_ms;
 	query->mad_buf->context[0] = query;
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index f2f6393..49b15ac 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -176,6 +176,7 @@ static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx)
 static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
 {
 	struct ib_ucm_context *ctx;
+	int result;
 
 	ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
 	if (!ctx)
@@ -186,10 +187,17 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
 	ctx->file = file;
 	INIT_LIST_HEAD(&ctx->events);
 
-	mutex_lock(&ctx_id_mutex);
-	ctx->id = idr_alloc(&ctx_id_table, ctx, 0, 0, GFP_KERNEL);
-	mutex_unlock(&ctx_id_mutex);
-	if (ctx->id < 0)
+	do {
+		result = idr_pre_get(&ctx_id_table, GFP_KERNEL);
+		if (!result)
+			goto error;
+
+		mutex_lock(&ctx_id_mutex);
+		result = idr_get_new(&ctx_id_table, ctx, &ctx->id);
+		mutex_unlock(&ctx_id_mutex);
+	} while (result == -EAGAIN);
+
+	if (result)
 		goto error;
 
 	list_add_tail(&ctx->file_list, &file->ctxs);
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 5ca44cd..2709ff5 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -145,6 +145,7 @@ static void ucma_put_ctx(struct ucma_context *ctx)
 static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
 {
 	struct ucma_context *ctx;
+	int ret;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx)
@@ -155,10 +156,17 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
 	INIT_LIST_HEAD(&ctx->mc_list);
 	ctx->file = file;
 
-	mutex_lock(&mut);
-	ctx->id = idr_alloc(&ctx_idr, ctx, 0, 0, GFP_KERNEL);
-	mutex_unlock(&mut);
-	if (ctx->id < 0)
+	do {
+		ret = idr_pre_get(&ctx_idr, GFP_KERNEL);
+		if (!ret)
+			goto error;
+
+		mutex_lock(&mut);
+		ret = idr_get_new(&ctx_idr, ctx, &ctx->id);
+		mutex_unlock(&mut);
+	} while (ret == -EAGAIN);
+
+	if (ret)
 		goto error;
 
 	list_add_tail(&ctx->list, &file->ctx_list);
@@ -172,15 +180,23 @@ error:
 static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
 {
 	struct ucma_multicast *mc;
+	int ret;
 
 	mc = kzalloc(sizeof(*mc), GFP_KERNEL);
 	if (!mc)
 		return NULL;
 
-	mutex_lock(&mut);
-	mc->id = idr_alloc(&multicast_idr, mc, 0, 0, GFP_KERNEL);
-	mutex_unlock(&mut);
-	if (mc->id < 0)
+	do {
+		ret = idr_pre_get(&multicast_idr, GFP_KERNEL);
+		if (!ret)
+			goto error;
+
+		mutex_lock(&mut);
+		ret = idr_get_new(&multicast_idr, mc, &mc->id);
+		mutex_unlock(&mut);
+	} while (ret == -EAGAIN);
+
+	if (ret)
 		goto error;
 
 	mc->ctx = ctx;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 83bc309..0cb0007 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -124,17 +124,18 @@ static int idr_add_uobj(struct idr *idr, struct ib_uobject *uobj)
 {
 	int ret;
 
-	idr_preload(GFP_KERNEL);
-	spin_lock(&ib_uverbs_idr_lock);
-
-	ret = idr_alloc(idr, uobj, 0, 0, GFP_NOWAIT);
-	if (ret >= 0)
-		uobj->id = ret;
+retry:
+	if (!idr_pre_get(idr, GFP_KERNEL))
+		return -ENOMEM;
 
+	spin_lock(&ib_uverbs_idr_lock);
+	ret = idr_get_new(idr, uobj, &uobj->id);
 	spin_unlock(&ib_uverbs_idr_lock);
-	idr_preload_end();
 
-	return ret < 0 ? ret : 0;
+	if (ret == -EAGAIN)
+		goto retry;
+
+	return ret;
 }
 
 void idr_remove_uobj(struct idr *idr, struct ib_uobject *uobj)
diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c
index 0ab826b..28cd5cb 100644
--- a/drivers/infiniband/hw/amso1100/c2_qp.c
+++ b/drivers/infiniband/hw/amso1100/c2_qp.c
@@ -382,17 +382,14 @@ static int c2_alloc_qpn(struct c2_dev *c2dev, struct c2_qp *qp)
 {
 	int ret;
 
-	idr_preload(GFP_KERNEL);
-	spin_lock_irq(&c2dev->qp_table.lock);
-
-	ret = idr_alloc(&c2dev->qp_table.idr, qp, c2dev->qp_table.last++, 0,
-			GFP_NOWAIT);
-	if (ret >= 0)
-		qp->qpn = ret;
-
-	spin_unlock_irq(&c2dev->qp_table.lock);
-	idr_preload_end();
-	return ret < 0 ? ret : 0;
+        do {
+		spin_lock_irq(&c2dev->qp_table.lock);
+		ret = idr_get_new_above(&c2dev->qp_table.idr, qp,
+					c2dev->qp_table.last++, &qp->qpn);
+		spin_unlock_irq(&c2dev->qp_table.lock);
+        } while ((ret == -EAGAIN) &&
+	 	 idr_pre_get(&c2dev->qp_table.idr, GFP_KERNEL));
+	return ret;
 }
 
 static void c2_free_qpn(struct c2_dev *c2dev, int qpn)
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h
index 8378622..a1c4457 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.h
+++ b/drivers/infiniband/hw/cxgb3/iwch.h
@@ -153,17 +153,19 @@ static inline int insert_handle(struct iwch_dev *rhp, struct idr *idr,
 				void *handle, u32 id)
 {
 	int ret;
-
-	idr_preload(GFP_KERNEL);
-	spin_lock_irq(&rhp->lock);
-
-	ret = idr_alloc(idr, handle, id, id + 1, GFP_NOWAIT);
-
-	spin_unlock_irq(&rhp->lock);
-	idr_preload_end();
-
-	BUG_ON(ret == -ENOSPC);
-	return ret < 0 ? ret : 0;
+	int newid;
+
+	do {
+		if (!idr_pre_get(idr, GFP_KERNEL)) {
+			return -ENOMEM;
+		}
+		spin_lock_irq(&rhp->lock);
+		ret = idr_get_new_above(idr, handle, id, &newid);
+		BUG_ON(newid != id);
+		spin_unlock_irq(&rhp->lock);
+	} while (ret == -EAGAIN);
+
+	return ret;
 }
 
 static inline void remove_handle(struct iwch_dev *rhp, struct idr *idr, u32 id)
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 7f862da..9c1644f 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -260,21 +260,20 @@ static inline int _insert_handle(struct c4iw_dev *rhp, struct idr *idr,
 				 void *handle, u32 id, int lock)
 {
 	int ret;
+	int newid;
 
-	if (lock) {
-		idr_preload(GFP_KERNEL);
-		spin_lock_irq(&rhp->lock);
-	}
-
-	ret = idr_alloc(idr, handle, id, id + 1, GFP_ATOMIC);
-
-	if (lock) {
-		spin_unlock_irq(&rhp->lock);
-		idr_preload_end();
-	}
-
-	BUG_ON(ret == -ENOSPC);
-	return ret < 0 ? ret : 0;
+	do {
+		if (!idr_pre_get(idr, lock ? GFP_KERNEL : GFP_ATOMIC))
+			return -ENOMEM;
+		if (lock)
+			spin_lock_irq(&rhp->lock);
+		ret = idr_get_new_above(idr, handle, id, &newid);
+		BUG_ON(!ret && newid != id);
+		if (lock)
+			spin_unlock_irq(&rhp->lock);
+	} while (ret == -EAGAIN);
+
+	return ret;
 }
 
 static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 212150c..8f52901 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -128,7 +128,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
 	void *vpage;
 	u32 counter;
 	u64 rpage, cqx_fec, h_ret;
-	int ipz_rc, i;
+	int ipz_rc, ret, i;
 	unsigned long flags;
 
 	if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
@@ -163,19 +163,32 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
 	adapter_handle = shca->ipz_hca_handle;
 	param.eq_handle = shca->eq.ipz_eq_handle;
 
-	idr_preload(GFP_KERNEL);
-	write_lock_irqsave(&ehca_cq_idr_lock, flags);
-	my_cq->token = idr_alloc(&ehca_cq_idr, my_cq, 0, 0x2000000, GFP_NOWAIT);
-	write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
-	idr_preload_end();
+	do {
+		if (!idr_pre_get(&ehca_cq_idr, GFP_KERNEL)) {
+			cq = ERR_PTR(-ENOMEM);
+			ehca_err(device, "Can't reserve idr nr. device=%p",
+				 device);
+			goto create_cq_exit1;
+		}
+
+		write_lock_irqsave(&ehca_cq_idr_lock, flags);
+		ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token);
+		write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+	} while (ret == -EAGAIN);
 
-	if (my_cq->token < 0) {
+	if (ret) {
 		cq = ERR_PTR(-ENOMEM);
 		ehca_err(device, "Can't allocate new idr entry. device=%p",
 			 device);
 		goto create_cq_exit1;
 	}
 
+	if (my_cq->token > 0x1FFFFFF) {
+		cq = ERR_PTR(-ENOMEM);
+		ehca_err(device, "Invalid number of cq. device=%p", device);
+		goto create_cq_exit2;
+	}
+
 	/*
 	 * CQs maximum depth is 4GB-64, but we need additional 20 as buffer
 	 * for receiving errors CQEs.
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 00d6861..1493939 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -636,26 +636,30 @@ static struct ehca_qp *internal_create_qp(
 		my_qp->send_cq =
 			container_of(init_attr->send_cq, struct ehca_cq, ib_cq);
 
-	idr_preload(GFP_KERNEL);
-	write_lock_irqsave(&ehca_qp_idr_lock, flags);
-
-	ret = idr_alloc(&ehca_qp_idr, my_qp, 0, 0x2000000, GFP_NOWAIT);
-	if (ret >= 0)
-		my_qp->token = ret;
-
-	write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
-	idr_preload_end();
-	if (ret < 0) {
-		if (ret == -ENOSPC) {
-			ret = -EINVAL;
-			ehca_err(pd->device, "Invalid number of qp");
-		} else {
+	do {
+		if (!idr_pre_get(&ehca_qp_idr, GFP_KERNEL)) {
 			ret = -ENOMEM;
-			ehca_err(pd->device, "Can't allocate new idr entry.");
+			ehca_err(pd->device, "Can't reserve idr resources.");
+			goto create_qp_exit0;
 		}
+
+		write_lock_irqsave(&ehca_qp_idr_lock, flags);
+		ret = idr_get_new(&ehca_qp_idr, my_qp, &my_qp->token);
+		write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
+	} while (ret == -EAGAIN);
+
+	if (ret) {
+		ret = -ENOMEM;
+		ehca_err(pd->device, "Can't allocate new idr entry.");
 		goto create_qp_exit0;
 	}
 
+	if (my_qp->token > 0x1FFFFFF) {
+		ret = -EINVAL;
+		ehca_err(pd->device, "Invalid number of qp");
+		goto create_qp_exit1;
+	}
+
 	if (has_srq)
 		parms.srq_token = my_qp->token;
 
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index fcdaeea..7b371f5 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -194,6 +194,11 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev)
 	struct ipath_devdata *dd;
 	int ret;
 
+	if (!idr_pre_get(&unit_table, GFP_KERNEL)) {
+		dd = ERR_PTR(-ENOMEM);
+		goto bail;
+	}
+
 	dd = vzalloc(sizeof(*dd));
 	if (!dd) {
 		dd = ERR_PTR(-ENOMEM);
@@ -201,10 +206,9 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev)
 	}
 	dd->ipath_unit = -1;
 
-	idr_preload(GFP_KERNEL);
 	spin_lock_irqsave(&ipath_devs_lock, flags);
 
-	ret = idr_alloc(&unit_table, dd, 0, 0, GFP_KERNEL);
+	ret = idr_get_new(&unit_table, dd, &dd->ipath_unit);
 	if (ret < 0) {
 		printk(KERN_ERR IPATH_DRV_NAME
 		       ": Could not allocate unit ID: error %d\n", -ret);
@@ -212,7 +216,6 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev)
 		dd = ERR_PTR(ret);
 		goto bail_unlock;
 	}
-	dd->ipath_unit = ret;
 
 	dd->pcidev = pdev;
 	pci_set_drvdata(pdev, dd);
@@ -221,7 +224,7 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev)
 
 bail_unlock:
 	spin_unlock_irqrestore(&ipath_devs_lock, flags);
-	idr_preload_end();
+
 bail:
 	return dd;
 }
@@ -2500,6 +2503,11 @@ static int __init infinipath_init(void)
 	 * the PCI subsystem.
 	 */
 	idr_init(&unit_table);
+	if (!idr_pre_get(&unit_table, GFP_KERNEL)) {
+		printk(KERN_ERR IPATH_DRV_NAME ": idr_pre_get() failed\n");
+		ret = -ENOMEM;
+		goto bail;
+	}
 
 	ret = pci_register_driver(&ipath_driver);
 	if (ret < 0) {
diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c
index 80e59ed..dbc99d4 100644
--- a/drivers/infiniband/hw/mlx4/cm.c
+++ b/drivers/infiniband/hw/mlx4/cm.c
@@ -203,7 +203,7 @@ static void sl_id_map_add(struct ib_device *ibdev, struct id_map_entry *new)
 static struct id_map_entry *
 id_map_alloc(struct ib_device *ibdev, int slave_id, u32 sl_cm_id)
 {
-	int ret;
+	int ret, id;
 	static int next_id;
 	struct id_map_entry *ent;
 	struct mlx4_ib_sriov *sriov = &to_mdev(ibdev)->sriov;
@@ -220,23 +220,25 @@ id_map_alloc(struct ib_device *ibdev, int slave_id, u32 sl_cm_id)
 	ent->dev = to_mdev(ibdev);
 	INIT_DELAYED_WORK(&ent->timeout, id_map_ent_timeout);
 
-	idr_preload(GFP_KERNEL);
-	spin_lock(&to_mdev(ibdev)->sriov.id_map_lock);
+	do {
+		spin_lock(&to_mdev(ibdev)->sriov.id_map_lock);
+		ret = idr_get_new_above(&sriov->pv_id_table, ent,
+					next_id, &id);
+		if (!ret) {
+			next_id = ((unsigned) id + 1) & MAX_IDR_MASK;
+			ent->pv_cm_id = (u32)id;
+			sl_id_map_add(ibdev, ent);
+		}
 
-	ret = idr_alloc(&sriov->pv_id_table, ent, next_id, 0, GFP_NOWAIT);
-	if (ret >= 0) {
-		next_id = ((unsigned)ret + 1) & MAX_IDR_MASK;
-		ent->pv_cm_id = (u32)ret;
-		sl_id_map_add(ibdev, ent);
+		spin_unlock(&sriov->id_map_lock);
+	} while (ret == -EAGAIN && idr_pre_get(&sriov->pv_id_table, GFP_KERNEL));
+	/*the function idr_get_new_above can return -ENOSPC, so don't insert in that case.*/
+	if (!ret) {
+		spin_lock(&sriov->id_map_lock);
 		list_add_tail(&ent->list, &sriov->cm_list);
-	}
-
-	spin_unlock(&sriov->id_map_lock);
-	idr_preload_end();
-
-	if (ret >= 0)
+		spin_unlock(&sriov->id_map_lock);
 		return ent;
-
+	}
 	/*error flow*/
 	kfree(ent);
 	mlx4_ib_warn(ibdev, "No more space in the idr (err:0x%x)\n", ret);
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
index 48928c8..c4e0131 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
@@ -51,6 +51,18 @@ static DEFINE_IDR(ocrdma_dev_id);
 
 static union ib_gid ocrdma_zero_sgid;
 
+static int ocrdma_get_instance(void)
+{
+	int instance = 0;
+
+	/* Assign an unused number */
+	if (!idr_pre_get(&ocrdma_dev_id, GFP_KERNEL))
+		return -1;
+	if (idr_get_new(&ocrdma_dev_id, NULL, &instance))
+		return -1;
+	return instance;
+}
+
 void ocrdma_get_guid(struct ocrdma_dev *dev, u8 *guid)
 {
 	u8 mac_addr[6];
@@ -404,7 +416,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
 		goto idr_err;
 
 	memcpy(&dev->nic_info, dev_info, sizeof(*dev_info));
-	dev->id = idr_alloc(&ocrdma_dev_id, NULL, 0, 0, GFP_KERNEL);
+	dev->id = ocrdma_get_instance();
 	if (dev->id < 0)
 		goto idr_err;
 
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c
index 50e33aa..ddf066d 100644
--- a/drivers/infiniband/hw/qib/qib_init.c
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -1060,23 +1060,22 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
 	struct qib_devdata *dd;
 	int ret;
 
+	if (!idr_pre_get(&qib_unit_table, GFP_KERNEL)) {
+		dd = ERR_PTR(-ENOMEM);
+		goto bail;
+	}
+
 	dd = (struct qib_devdata *) ib_alloc_device(sizeof(*dd) + extra);
 	if (!dd) {
 		dd = ERR_PTR(-ENOMEM);
 		goto bail;
 	}
 
-	idr_preload(GFP_KERNEL);
 	spin_lock_irqsave(&qib_devs_lock, flags);
-
-	ret = idr_alloc(&qib_unit_table, dd, 0, 0, GFP_NOWAIT);
-	if (ret >= 0) {
-		dd->unit = ret;
+	ret = idr_get_new(&qib_unit_table, dd, &dd->unit);
+	if (ret >= 0)
 		list_add(&dd->list, &qib_dev_list);
-	}
-
 	spin_unlock_irqrestore(&qib_devs_lock, flags);
-	idr_preload_end();
 
 	if (ret < 0) {
 		qib_early_err(&pdev->dev,
@@ -1181,6 +1180,11 @@ static int __init qlogic_ib_init(void)
 	 * the PCI subsystem.
 	 */
 	idr_init(&qib_unit_table);
+	if (!idr_pre_get(&qib_unit_table, GFP_KERNEL)) {
+		pr_err("idr_pre_get() failed\n");
+		ret = -ENOMEM;
+		goto bail_cq_wq;
+	}
 
 	ret = pci_register_driver(&qib_driver);
 	if (ret < 0) {
@@ -1195,6 +1199,7 @@ static int __init qlogic_ib_init(void)
 
 bail_unit:
 	idr_destroy(&qib_unit_table);
+bail_cq_wq:
 	destroy_workqueue(qib_cq_wq);
 bail_dev:
 	qib_dev_cleanup();
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index ac74b81..c644eb6 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1801,38 +1801,62 @@ static void free_minor(int minor)
  */
 static int specific_minor(int minor)
 {
-	int r;
+	int r, m;
 
 	if (minor >= (1 << MINORBITS))
 		return -EINVAL;
 
-	idr_preload(GFP_KERNEL);
+	r = idr_pre_get(&_minor_idr, GFP_KERNEL);
+	if (!r)
+		return -ENOMEM;
+
 	spin_lock(&_minor_lock);
 
-	r = idr_alloc(&_minor_idr, MINOR_ALLOCED, minor, minor + 1, GFP_NOWAIT);
+	if (idr_find(&_minor_idr, minor)) {
+		r = -EBUSY;
+		goto out;
+	}
+
+	r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m);
+	if (r)
+		goto out;
 
+	if (m != minor) {
+		idr_remove(&_minor_idr, m);
+		r = -EBUSY;
+		goto out;
+	}
+
+out:
 	spin_unlock(&_minor_lock);
-	idr_preload_end();
-	if (r < 0)
-		return r == -ENOSPC ? -EBUSY : r;
-	return 0;
+	return r;
 }
 
 static int next_free_minor(int *minor)
 {
-	int r;
+	int r, m;
+
+	r = idr_pre_get(&_minor_idr, GFP_KERNEL);
+	if (!r)
+		return -ENOMEM;
 
-	idr_preload(GFP_KERNEL);
 	spin_lock(&_minor_lock);
 
-	r = idr_alloc(&_minor_idr, MINOR_ALLOCED, 0, 1 << MINORBITS, GFP_NOWAIT);
+	r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m);
+	if (r)
+		goto out;
+
+	if (m >= (1 << MINORBITS)) {
+		idr_remove(&_minor_idr, m);
+		r = -ENOSPC;
+		goto out;
+	}
+
+	*minor = m;
 
+out:
 	spin_unlock(&_minor_lock);
-	idr_preload_end();
-	if (r < 0)
-		return r;
-	*minor = r;
-	return 0;
+	return r;
 }
 
 static const struct block_device_operations dm_blk_dops;
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index ffcb10a..56ff19c 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -512,17 +512,18 @@ int memstick_add_host(struct memstick_host *host)
 {
 	int rc;
 
-	idr_preload(GFP_KERNEL);
-	spin_lock(&memstick_host_lock);
-
-	rc = idr_alloc(&memstick_host_idr, host, 0, 0, GFP_NOWAIT);
-	if (rc >= 0)
-		host->id = rc;
+	while (1) {
+		if (!idr_pre_get(&memstick_host_idr, GFP_KERNEL))
+			return -ENOMEM;
 
-	spin_unlock(&memstick_host_lock);
-	idr_preload_end();
-	if (rc < 0)
-		return rc;
+		spin_lock(&memstick_host_lock);
+		rc = idr_get_new(&memstick_host_idr, host, &host->id);
+		spin_unlock(&memstick_host_lock);
+		if (!rc)
+			break;
+		else if (rc != -EAGAIN)
+			return rc;
+	}
 
 	dev_set_name(&host->dev, "memstick%u", host->id);
 
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index f12b78d..9729b92 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -1213,10 +1213,21 @@ static int mspro_block_init_disk(struct memstick_dev *card)
 	msb->page_size = be16_to_cpu(sys_info->unit_size);
 
 	mutex_lock(&mspro_block_disk_lock);
-	disk_id = idr_alloc(&mspro_block_disk_idr, card, 0, 256, GFP_KERNEL);
+	if (!idr_pre_get(&mspro_block_disk_idr, GFP_KERNEL)) {
+		mutex_unlock(&mspro_block_disk_lock);
+		return -ENOMEM;
+	}
+
+	rc = idr_get_new(&mspro_block_disk_idr, card, &disk_id);
 	mutex_unlock(&mspro_block_disk_lock);
-	if (disk_id < 0)
-		return disk_id;
+
+	if (rc)
+		return rc;
+
+	if ((disk_id << MSPRO_BLOCK_PART_SHIFT) > 255) {
+		rc = -ENOSPC;
+		goto out_release_id;
+	}
 
 	msb->disk = alloc_disk(1 << MSPRO_BLOCK_PART_SHIFT);
 	if (!msb->disk) {
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 45e97b4..822237e 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -1061,14 +1061,15 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
 	}
 	handle->pcr = pcr;
 
-	idr_preload(GFP_KERNEL);
+	if (!idr_pre_get(&rtsx_pci_idr, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto free_handle;
+	}
+
 	spin_lock(&rtsx_pci_lock);
-	ret = idr_alloc(&rtsx_pci_idr, pcr, 0, 0, GFP_NOWAIT);
-	if (ret >= 0)
-		pcr->id = ret;
+	ret = idr_get_new(&rtsx_pci_idr, pcr, &pcr->id);
 	spin_unlock(&rtsx_pci_lock);
-	idr_preload_end();
-	if (ret < 0)
+	if (ret)
 		goto free_handle;
 
 	pcr->pci = pcidev;
diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c
index f32550a..f428d86 100644
--- a/drivers/misc/c2port/core.c
+++ b/drivers/misc/c2port/core.c
@@ -885,7 +885,7 @@ struct c2port_device *c2port_device_register(char *name,
 					struct c2port_ops *ops, void *devdata)
 {
 	struct c2port_device *c2dev;
-	int ret;
+	int id, ret;
 
 	if (unlikely(!ops) || unlikely(!ops->access) || \
 		unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
@@ -897,18 +897,22 @@ struct c2port_device *c2port_device_register(char *name,
 	if (unlikely(!c2dev))
 		return ERR_PTR(-ENOMEM);
 
-	idr_preload(GFP_KERNEL);
+	ret = idr_pre_get(&c2port_idr, GFP_KERNEL);
+	if (!ret) {
+		ret = -ENOMEM;
+		goto error_idr_get_new;
+	}
+
 	spin_lock_irq(&c2port_idr_lock);
-	ret = idr_alloc(&c2port_idr, c2dev, 0, 0, GFP_NOWAIT);
+	ret = idr_get_new(&c2port_idr, c2dev, &id);
 	spin_unlock_irq(&c2port_idr_lock);
-	idr_preload_end();
 
 	if (ret < 0)
-		goto error_idr_alloc;
-	c2dev->id = ret;
+		goto error_idr_get_new;
+	c2dev->id = id;
 
 	c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
-				   "c2port%d", c2dev->id);
+					"c2port%d", id);
 	if (unlikely(IS_ERR(c2dev->dev))) {
 		ret = PTR_ERR(c2dev->dev);
 		goto error_device_create;
@@ -942,10 +946,10 @@ error_device_create_bin_file:
 
 error_device_create:
 	spin_lock_irq(&c2port_idr_lock);
-	idr_remove(&c2port_idr, c2dev->id);
+	idr_remove(&c2port_idr, id);
 	spin_unlock_irq(&c2port_idr_lock);
 
-error_idr_alloc:
+error_idr_get_new:
 	kfree(c2dev);
 
 	return ERR_PTR(ret);
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index 0ab7c92..0bd5349 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -196,14 +196,13 @@ int tifm_add_adapter(struct tifm_adapter *fm)
 {
 	int rc;
 
-	idr_preload(GFP_KERNEL);
+	if (!idr_pre_get(&tifm_adapter_idr, GFP_KERNEL))
+		return -ENOMEM;
+
 	spin_lock(&tifm_adapter_lock);
-	rc = idr_alloc(&tifm_adapter_idr, fm, 0, 0, GFP_NOWAIT);
-	if (rc >= 0)
-		fm->id = rc;
+	rc = idr_get_new(&tifm_adapter_idr, fm, &fm->id);
 	spin_unlock(&tifm_adapter_lock);
-	idr_preload_end();
-	if (rc < 0)
+	if (rc)
 		return rc;
 
 	dev_set_name(&fm->dev, "tifm%u", fm->id);
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 1117de7..ee2e16b 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -306,20 +306,19 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 	int err;
 	struct mmc_host *host;
 
+	if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
+		return NULL;
+
 	host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
 	if (!host)
 		return NULL;
 
 	/* scanning will be enabled when we're ready */
 	host->rescan_disable = 1;
-	idr_preload(GFP_KERNEL);
 	spin_lock(&mmc_host_lock);
-	err = idr_alloc(&mmc_host_idr, host, 0, 0, GFP_NOWAIT);
-	if (err >= 0)
-		host->index = err;
+	err = idr_get_new(&mmc_host_idr, host, &host->index);
 	spin_unlock(&mmc_host_lock);
-	idr_preload_end();
-	if (err < 0)
+	if (err)
 		goto free;
 
 	dev_set_name(&host->class_dev, "mmc%d", host->index);
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 61d5f56..ec794a7 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -349,8 +349,13 @@ int add_mtd_device(struct mtd_info *mtd)
 	BUG_ON(mtd->writesize == 0);
 	mutex_lock(&mtd_table_mutex);
 
-	i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
-	if (i < 0)
+	do {
+		if (!idr_pre_get(&mtd_idr, GFP_KERNEL))
+			goto fail_locked;
+		error = idr_get_new(&mtd_idr, mtd, &i);
+	} while (error == -EAGAIN);
+
+	if (error)
 		goto fail_locked;
 
 	mtd->index = i;
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 1814cfe..b181dfb 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -279,17 +279,28 @@ static int macvtap_receive(struct sk_buff *skb)
 static int macvtap_get_minor(struct macvlan_dev *vlan)
 {
 	int retval = -ENOMEM;
+	int id;
 
 	mutex_lock(&minor_lock);
-	retval = idr_alloc(&minor_idr, vlan, 1, MACVTAP_NUM_DEVS, GFP_KERNEL);
-	if (retval >= 0) {
-		vlan->minor = retval;
-	} else if (retval == -ENOSPC) {
+	if (idr_pre_get(&minor_idr, GFP_KERNEL) == 0)
+		goto exit;
+
+	retval = idr_get_new_above(&minor_idr, vlan, 1, &id);
+	if (retval < 0) {
+		if (retval == -EAGAIN)
+			retval = -ENOMEM;
+		goto exit;
+	}
+	if (id < MACVTAP_NUM_DEVS) {
+		vlan->minor = id;
+	} else {
 		printk(KERN_ERR "too many macvtap devices\n");
 		retval = -EINVAL;
+		idr_remove(&minor_idr, id);
 	}
+exit:
 	mutex_unlock(&minor_lock);
-	return retval < 0 ? retval : 0;
+	return retval;
 }
 
 static void macvtap_free_minor(struct macvlan_dev *vlan)
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 7efdb91..0b2706a 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -2946,21 +2946,46 @@ static void __exit ppp_cleanup(void)
  * by holding all_ppp_mutex
  */
 
+static int __unit_alloc(struct idr *p, void *ptr, int n)
+{
+	int unit, err;
+
+again:
+	if (!idr_pre_get(p, GFP_KERNEL)) {
+		pr_err("PPP: No free memory for idr\n");
+		return -ENOMEM;
+	}
+
+	err = idr_get_new_above(p, ptr, n, &unit);
+	if (err < 0) {
+		if (err == -EAGAIN)
+			goto again;
+		return err;
+	}
+
+	return unit;
+}
+
 /* associate pointer with specified number */
 static int unit_set(struct idr *p, void *ptr, int n)
 {
 	int unit;
 
-	unit = idr_alloc(p, ptr, n, n + 1, GFP_KERNEL);
-	if (unit == -ENOSPC)
-		unit = -EINVAL;
+	unit = __unit_alloc(p, ptr, n);
+	if (unit < 0)
+		return unit;
+	else if (unit != n) {
+		idr_remove(p, unit);
+		return -EINVAL;
+	}
+
 	return unit;
 }
 
 /* get new free unit number and associate pointer with it */
 static int unit_get(struct idr *p, void *ptr)
 {
-	return idr_alloc(p, ptr, 0, 0, GFP_KERNEL);
+	return __unit_alloc(p, ptr, 0);
 }
 
 /* put unit number back to a pool */
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
index 3f00568..ca70365 100644
--- a/drivers/power/bq2415x_charger.c
+++ b/drivers/power/bq2415x_charger.c
@@ -1504,11 +1504,16 @@ static int bq2415x_probe(struct i2c_client *client,
 	}
 
 	/* Get new ID for the new device */
+	ret = idr_pre_get(&bq2415x_id, GFP_KERNEL);
+	if (ret == 0)
+		return -ENOMEM;
+
 	mutex_lock(&bq2415x_id_mutex);
-	num = idr_alloc(&bq2415x_id, client, 0, 0, GFP_KERNEL);
+	ret = idr_get_new(&bq2415x_id, client, &num);
 	mutex_unlock(&bq2415x_id_mutex);
-	if (num < 0)
-		return num;
+
+	if (ret < 0)
+		return ret;
 
 	name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num);
 	if (!name) {
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 26037ca..8ccf5d7 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -791,11 +791,14 @@ static int bq27x00_battery_probe(struct i2c_client *client,
 	int retval = 0;
 
 	/* Get new ID for the new battery device */
+	retval = idr_pre_get(&battery_id, GFP_KERNEL);
+	if (retval == 0)
+		return -ENOMEM;
 	mutex_lock(&battery_mutex);
-	num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL);
+	retval = idr_get_new(&battery_id, client, &num);
 	mutex_unlock(&battery_mutex);
-	if (num < 0)
-		return num;
+	if (retval < 0)
+		return retval;
 
 	name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num);
 	if (!name) {
diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c
index c09e772..e7301b3 100644
--- a/drivers/power/ds2782_battery.c
+++ b/drivers/power/ds2782_battery.c
@@ -395,12 +395,17 @@ static int ds278x_battery_probe(struct i2c_client *client,
 	}
 
 	/* Get an ID for this battery */
+	ret = idr_pre_get(&battery_id, GFP_KERNEL);
+	if (ret == 0) {
+		ret = -ENOMEM;
+		goto fail_id;
+	}
+
 	mutex_lock(&battery_lock);
-	ret = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL);
+	ret = idr_get_new(&battery_id, client, &num);
 	mutex_unlock(&battery_lock);
 	if (ret < 0)
 		goto fail_id;
-	num = ret;
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info) {
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index cdad4d9..f197e8e 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -102,7 +102,7 @@ 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()
+	/* These initializations must be done before calling idr_get_new()
 	 * in order to avoid reces into pps_event().
 	 */
 	pps->params.api_version = PPS_API_VERS;
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index de8e663..2420d5a 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -290,22 +290,30 @@ int pps_register_cdev(struct pps_device *pps)
 	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.
-	 */
-	err = idr_alloc(&pps_idr, pps, 0, PPS_MAX_SOURCES, GFP_KERNEL);
-	if (err < 0) {
-		if (err == -ENOSPC) {
-			pr_err("%s: too many PPS sources in the system\n",
-			       pps->info.name);
-			err = -EBUSY;
-		}
-		goto out_unlock;
+	/* Get new ID for the new PPS source */
+	if (idr_pre_get(&pps_idr, GFP_KERNEL) == 0) {
+		mutex_unlock(&pps_idr_lock);
+		return -ENOMEM;
 	}
-	pps->id = err;
+
+	/* Now really allocate the PPS source.
+	 * After idr_get_new() calling the new source will be freely available
+	 * into the kernel.
+	 */
+	err = idr_get_new(&pps_idr, pps, &pps->id);
 	mutex_unlock(&pps_idr_lock);
 
+	if (err < 0)
+		return err;
+
+	pps->id &= MAX_IDR_MASK;
+	if (pps->id >= PPS_MAX_SOURCES) {
+		pr_err("%s: too many PPS sources in the system\n",
+					pps->info.name);
+		err = -EBUSY;
+		goto free_idr;
+	}
+
 	devt = MKDEV(MAJOR(pps_devt), pps->id);
 
 	cdev_init(&pps->cdev, &pps_cdev_fops);
@@ -337,8 +345,8 @@ del_cdev:
 free_idr:
 	mutex_lock(&pps_idr_lock);
 	idr_remove(&pps_idr, pps->id);
-out_unlock:
 	mutex_unlock(&pps_idr_lock);
+
 	return err;
 }
 
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 29387df..634d367 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -199,6 +199,11 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	/* actual size of vring (in bytes) */
 	size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
 
+	if (!idr_pre_get(&rproc->notifyids, GFP_KERNEL)) {
+		dev_err(dev, "idr_pre_get failed\n");
+		return -ENOMEM;
+	}
+
 	/*
 	 * Allocate non-cacheable memory for the vring. In the future
 	 * this call will also configure the IOMMU for us
@@ -216,13 +221,12 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	 * TODO: let the rproc know the notifyid of this vring
 	 * TODO: support predefined notifyids (via resource table)
 	 */
-	ret = idr_alloc(&rproc->notifyids, rvring, 0, 0, GFP_KERNEL);
+	ret = idr_get_new(&rproc->notifyids, rvring, &notifyid);
 	if (ret) {
-		dev_err(dev, "idr_alloc failed: %d\n", ret);
+		dev_err(dev, "idr_get_new failed: %d\n", ret);
 		dma_free_coherent(dev->parent, size, va, dma);
 		return ret;
 	}
-	notifyid = ret;
 
 	/* Store largest notifyid */
 	rproc->max_notifyid = max(rproc->max_notifyid, notifyid);
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index a59684b..aaa6840 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -213,10 +213,13 @@ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp,
 		struct rpmsg_channel *rpdev, rpmsg_rx_cb_t cb,
 		void *priv, u32 addr)
 {
-	int id_min, id_max, id;
+	int err, tmpaddr, request;
 	struct rpmsg_endpoint *ept;
 	struct device *dev = rpdev ? &rpdev->dev : &vrp->vdev->dev;
 
+	if (!idr_pre_get(&vrp->endpoints, GFP_KERNEL))
+		return NULL;
+
 	ept = kzalloc(sizeof(*ept), GFP_KERNEL);
 	if (!ept) {
 		dev_err(dev, "failed to kzalloc a new ept\n");
@@ -231,28 +234,31 @@ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp,
 	ept->priv = priv;
 
 	/* do we need to allocate a local address ? */
-	if (addr == RPMSG_ADDR_ANY) {
-		id_min = RPMSG_RESERVED_ADDRESSES;
-		id_max = 0;
-	} else {
-		id_min = addr;
-		id_max = addr + 1;
-	}
+	request = addr == RPMSG_ADDR_ANY ? RPMSG_RESERVED_ADDRESSES : addr;
 
 	mutex_lock(&vrp->endpoints_lock);
 
 	/* bind the endpoint to an rpmsg address (and allocate one if needed) */
-	id = idr_alloc(&vrp->endpoints, ept, id_min, id_max, GFP_KERNEL);
-	if (id < 0) {
-		dev_err(dev, "idr_alloc failed: %d\n", id);
+	err = idr_get_new_above(&vrp->endpoints, ept, request, &tmpaddr);
+	if (err) {
+		dev_err(dev, "idr_get_new_above failed: %d\n", err);
 		goto free_ept;
 	}
-	ept->addr = id;
+
+	/* make sure the user's address request is fulfilled, if relevant */
+	if (addr != RPMSG_ADDR_ANY && tmpaddr != addr) {
+		dev_err(dev, "address 0x%x already in use\n", addr);
+		goto rem_idr;
+	}
+
+	ept->addr = tmpaddr;
 
 	mutex_unlock(&vrp->endpoints_lock);
 
 	return ept;
 
+rem_idr:
+	idr_remove(&vrp->endpoints, request);
 free_ept:
 	mutex_unlock(&vrp->endpoints_lock);
 	kref_put(&ept->refcount, __ept_release);
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 5864f98..8f92732 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -523,13 +523,20 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
 	int error = 1;
 
 	mutex_lock(&bfad_mutex);
-	error = idr_alloc(&bfad_im_port_index, im_port, 0, 0, GFP_KERNEL);
-	if (error < 0) {
+	if (!idr_pre_get(&bfad_im_port_index, GFP_KERNEL)) {
 		mutex_unlock(&bfad_mutex);
-		printk(KERN_WARNING "idr_alloc failure\n");
+		printk(KERN_WARNING "idr_pre_get failure\n");
 		goto out;
 	}
-	im_port->idr_id = error;
+
+	error = idr_get_new(&bfad_im_port_index, im_port,
+					 &im_port->idr_id);
+	if (error) {
+		mutex_unlock(&bfad_mutex);
+		printk(KERN_WARNING "idr_get_new failure\n");
+		goto out;
+	}
+
 	mutex_unlock(&bfad_mutex);
 
 	im_port->shost = bfad_scsi_host_alloc(im_port, bfad);
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 2a32374..a15474e 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -895,7 +895,7 @@ static int ch_probe(struct device *dev)
 {
 	struct scsi_device *sd = to_scsi_device(dev);
 	struct device *class_dev;
-	int ret;
+	int minor, ret = -ENOMEM;
 	scsi_changer *ch;
 
 	if (sd->type != TYPE_MEDIUM_CHANGER)
@@ -905,19 +905,22 @@ static int ch_probe(struct device *dev)
 	if (NULL == ch)
 		return -ENOMEM;
 
-	idr_preload(GFP_KERNEL);
+	if (!idr_pre_get(&ch_index_idr, GFP_KERNEL))
+		goto free_ch;
+
 	spin_lock(&ch_index_lock);
-	ret = idr_alloc(&ch_index_idr, ch, 0, CH_MAX_DEVS + 1, GFP_NOWAIT);
+	ret = idr_get_new(&ch_index_idr, ch, &minor);
 	spin_unlock(&ch_index_lock);
-	idr_preload_end();
 
-	if (ret < 0) {
-		if (ret == -ENOSPC)
-			ret = -ENODEV;
+	if (ret)
 		goto free_ch;
+
+	if (minor > CH_MAX_DEVS) {
+		ret = -ENODEV;
+		goto remove_idr;
 	}
 
-	ch->minor = ret;
+	ch->minor = minor;
 	sprintf(ch->name,"ch%d",ch->minor);
 
 	class_dev = device_create(ch_sysfs_class, dev,
@@ -941,7 +944,7 @@ static int ch_probe(struct device *dev)
 
 	return 0;
 remove_idr:
-	idr_remove(&ch_index_idr, ch->minor);
+	idr_remove(&ch_index_idr, minor);
 free_ch:
 	kfree(ch);
 	return ret;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 314b4f6..26ca2ef 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -3165,10 +3165,14 @@ destroy_port(struct lpfc_vport *vport)
 int
 lpfc_get_instance(void)
 {
-	int ret;
-
-	ret = idr_alloc(&lpfc_hba_index, NULL, 0, 0, GFP_KERNEL);
-	return ret < 0 ? -1 : ret;
+	int instance = 0;
+
+	/* Assign an unused number */
+	if (!idr_pre_get(&lpfc_hba_index, GFP_KERNEL))
+		return -1;
+	if (idr_get_new(&lpfc_hba_index, NULL, &instance))
+		return -1;
+	return instance;
 }
 
 /**
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index df5e961..afa5bfc 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1392,23 +1392,24 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
 		return ERR_PTR(-ENOMEM);
 	}
 
-	idr_preload(GFP_KERNEL);
+	if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) {
+		printk(KERN_WARNING "idr expansion Sg_device failure\n");
+		error = -ENOMEM;
+		goto out;
+	}
+
 	write_lock_irqsave(&sg_index_lock, iflags);
 
-	error = idr_alloc(&sg_index_idr, sdp, 0, SG_MAX_DEVS, GFP_NOWAIT);
-	if (error < 0) {
-		if (error == -ENOSPC) {
-			sdev_printk(KERN_WARNING, scsidp,
-				    "Unable to attach sg device type=%d, minor number exceeds %d\n",
-				    scsidp->type, SG_MAX_DEVS - 1);
-			error = -ENODEV;
-		} else {
-			printk(KERN_WARNING
-			       "idr allocation Sg_device failure: %d\n", error);
-		}
-		goto out_unlock;
+	error = idr_get_new(&sg_index_idr, sdp, &k);
+	if (error) {
+		write_unlock_irqrestore(&sg_index_lock, iflags);
+		printk(KERN_WARNING "idr allocation Sg_device failure: %d\n",
+		       error);
+		goto out;
 	}
-	k = error;
+
+	if (unlikely(k >= SG_MAX_DEVS))
+		goto overflow;
 
 	SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k));
 	sprintf(disk->disk_name, "sg%d", k);
@@ -1420,17 +1421,25 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
 	sdp->sg_tablesize = queue_max_segments(q);
 	sdp->index = k;
 	kref_init(&sdp->d_ref);
-	error = 0;
 
-out_unlock:
 	write_unlock_irqrestore(&sg_index_lock, iflags);
-	idr_preload_end();
 
+	error = 0;
+ out:
 	if (error) {
 		kfree(sdp);
 		return ERR_PTR(error);
 	}
 	return sdp;
+
+ overflow:
+	idr_remove(&sg_index_idr, k);
+	write_unlock_irqrestore(&sg_index_lock, iflags);
+	sdev_printk(KERN_WARNING, scsidp,
+		    "Unable to attach sg device type=%d, minor "
+		    "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1);
+	error = -ENODEV;
+	goto out;
 }
 
 static int
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 7c6edca..98156a9 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4076,7 +4076,7 @@ static int st_probe(struct device *dev)
 	struct st_modedef *STm;
 	struct st_partstat *STps;
 	struct st_buffer *buffer;
-	int i, error;
+	int i, dev_num, error;
 	char *stp;
 
 	if (SDp->type != TYPE_TAPE)
@@ -4178,17 +4178,27 @@ static int st_probe(struct device *dev)
 	    tpnt->blksize_changed = 0;
 	mutex_init(&tpnt->lock);
 
-	idr_preload(GFP_KERNEL);
+	if (!idr_pre_get(&st_index_idr, GFP_KERNEL)) {
+		pr_warn("st: idr expansion failed\n");
+		error = -ENOMEM;
+		goto out_put_disk;
+	}
+
 	spin_lock(&st_index_lock);
-	error = idr_alloc(&st_index_idr, tpnt, 0, ST_MAX_TAPES + 1, GFP_NOWAIT);
+	error = idr_get_new(&st_index_idr, tpnt, &dev_num);
 	spin_unlock(&st_index_lock);
-	idr_preload_end();
-	if (error < 0) {
+	if (error) {
 		pr_warn("st: idr allocation failed: %d\n", error);
 		goto out_put_disk;
 	}
-	tpnt->index = error;
-	sprintf(disk->disk_name, "st%d", tpnt->index);
+
+	if (dev_num > ST_MAX_TAPES) {
+		pr_err("st: Too many tape devices (max. %d).\n", ST_MAX_TAPES);
+		goto out_put_index;
+	}
+
+	tpnt->index = dev_num;
+	sprintf(disk->disk_name, "st%d", dev_num);
 
 	dev_set_drvdata(dev, tpnt);
 
@@ -4208,8 +4218,9 @@ static int st_probe(struct device *dev)
 
 out_remove_devs:
 	remove_cdevs(tpnt);
+out_put_index:
 	spin_lock(&st_index_lock);
-	idr_remove(&st_index_idr, tpnt->index);
+	idr_remove(&st_index_idr, dev_num);
 	spin_unlock(&st_index_lock);
 out_put_disk:
 	put_disk(disk);
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index f1fdf4f..339f97f 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -144,24 +144,23 @@ struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *buf)
 	spin_lock_init(&tiqn->login_stats.lock);
 	spin_lock_init(&tiqn->logout_stats.lock);
 
+	if (!idr_pre_get(&tiqn_idr, GFP_KERNEL)) {
+		pr_err("idr_pre_get() for tiqn_idr failed\n");
+		kfree(tiqn);
+		return ERR_PTR(-ENOMEM);
+	}
 	tiqn->tiqn_state = TIQN_STATE_ACTIVE;
 
-	idr_preload(GFP_KERNEL);
 	spin_lock(&tiqn_lock);
-
-	ret = idr_alloc(&tiqn_idr, NULL, 0, 0, GFP_NOWAIT);
+	ret = idr_get_new(&tiqn_idr, NULL, &tiqn->tiqn_index);
 	if (ret < 0) {
-		pr_err("idr_alloc() failed for tiqn->tiqn_index\n");
+		pr_err("idr_get_new() failed for tiqn->tiqn_index\n");
 		spin_unlock(&tiqn_lock);
-		idr_preload_end();
 		kfree(tiqn);
 		return ERR_PTR(ret);
 	}
-	tiqn->tiqn_index = ret;
 	list_add_tail(&tiqn->tiqn_list, &g_tiqn_list);
-
 	spin_unlock(&tiqn_lock);
-	idr_preload_end();
 
 	pr_debug("CORE[0] - Added iSCSI Target IQN: %s\n", tiqn->tiqn);
 
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 2535d4d..fdb632f 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -247,16 +247,19 @@ static int iscsi_login_zero_tsih_s1(
 	spin_lock_init(&sess->session_usage_lock);
 	spin_lock_init(&sess->ttt_lock);
 
-	idr_preload(GFP_KERNEL);
+	if (!idr_pre_get(&sess_idr, GFP_KERNEL)) {
+		pr_err("idr_pre_get() for sess_idr failed\n");
+		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+				ISCSI_LOGIN_STATUS_NO_RESOURCES);
+		kfree(sess);
+		return -ENOMEM;
+	}
 	spin_lock_bh(&sess_idr_lock);
-	ret = idr_alloc(&sess_idr, NULL, 0, 0, GFP_NOWAIT);
-	if (ret >= 0)
-		sess->session_index = ret;
+	ret = idr_get_new(&sess_idr, NULL, &sess->session_index);
 	spin_unlock_bh(&sess_idr_lock);
-	idr_preload_end();
 
 	if (ret < 0) {
-		pr_err("idr_alloc() for sess_idr failed\n");
+		pr_err("idr_get_new() for sess_idr failed\n");
 		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 				ISCSI_LOGIN_STATUS_NO_RESOURCES);
 		kfree(sess);
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 8dc44cb..455c77a 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -73,14 +73,21 @@ static struct cpufreq_cooling_device *notify_device;
  */
 static int get_idr(struct idr *idr, int *id)
 {
-	int ret;
+	int err;
+again:
+	if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
+		return -ENOMEM;
 
 	mutex_lock(&cooling_cpufreq_lock);
-	ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
+	err = idr_get_new(idr, NULL, id);
 	mutex_unlock(&cooling_cpufreq_lock);
-	if (unlikely(ret < 0))
-		return ret;
-	*id = ret;
+
+	if (unlikely(err == -EAGAIN))
+		goto again;
+	else if (unlikely(err))
+		return err;
+
+	*id = *id & MAX_IDR_MASK;
 	return 0;
 }
 
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 2eaaaa6..6472e7e 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -131,16 +131,23 @@ EXPORT_SYMBOL_GPL(thermal_unregister_governor);
 
 static int get_idr(struct idr *idr, struct mutex *lock, int *id)
 {
-	int ret;
+	int err;
+
+again:
+	if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
+		return -ENOMEM;
 
 	if (lock)
 		mutex_lock(lock);
-	ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
+	err = idr_get_new(idr, NULL, id);
 	if (lock)
 		mutex_unlock(lock);
-	if (unlikely(ret < 0))
-		return ret;
-	*id = ret;
+	if (unlikely(err == -EAGAIN))
+		goto again;
+	else if (unlikely(err))
+		return err;
+
+	*id = *id & MAX_IDR_MASK;
 	return 0;
 }
 
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index c8b9262..5110f36 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -369,15 +369,26 @@ static void uio_dev_del_attributes(struct uio_device *idev)
 static int uio_get_minor(struct uio_device *idev)
 {
 	int retval = -ENOMEM;
+	int id;
 
 	mutex_lock(&minor_lock);
-	retval = idr_alloc(&uio_idr, idev, 0, UIO_MAX_DEVICES, GFP_KERNEL);
-	if (retval >= 0) {
-		idev->minor = retval;
-	} else if (retval == -ENOSPC) {
+	if (idr_pre_get(&uio_idr, GFP_KERNEL) == 0)
+		goto exit;
+
+	retval = idr_get_new(&uio_idr, idev, &id);
+	if (retval < 0) {
+		if (retval == -EAGAIN)
+			retval = -ENOMEM;
+		goto exit;
+	}
+	if (id < UIO_MAX_DEVICES) {
+		idev->minor = id;
+	} else {
 		dev_err(idev->dev, "too many uio devices\n");
 		retval = -EINVAL;
+		idr_remove(&uio_idr, id);
 	}
+exit:
 	mutex_unlock(&minor_lock);
 	return retval;
 }
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 7f61abf..12c264d 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -139,8 +139,23 @@ EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver);
  */
 static int vfio_alloc_group_minor(struct vfio_group *group)
 {
+	int ret, minor;
+
+again:
+	if (unlikely(idr_pre_get(&vfio.group_idr, GFP_KERNEL) == 0))
+		return -ENOMEM;
+
 	/* index 0 is used by /dev/vfio/vfio */
-	return idr_alloc(&vfio.group_idr, group, 1, MINORMASK + 1, GFP_KERNEL);
+	ret = idr_get_new_above(&vfio.group_idr, group, 1, &minor);
+	if (ret == -EAGAIN)
+		goto again;
+	if (ret || minor > MINORMASK) {
+		if (minor > MINORMASK)
+			idr_remove(&vfio.group_idr, minor);
+		return -ENOSPC;
+	}
+
+	return minor;
 }
 
 static void vfio_free_group_minor(int minor)
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 1b11466..f750165 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -1183,7 +1183,7 @@ static void detach_lkb(struct dlm_lkb *lkb)
 static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
 {
 	struct dlm_lkb *lkb;
-	int rv;
+	int rv, id;
 
 	lkb = dlm_allocate_lkb(ls);
 	if (!lkb)
@@ -1199,13 +1199,19 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
 	mutex_init(&lkb->lkb_cb_mutex);
 	INIT_WORK(&lkb->lkb_cb_work, dlm_callback_work);
 
-	idr_preload(GFP_NOFS);
+ retry:
+	rv = idr_pre_get(&ls->ls_lkbidr, GFP_NOFS);
+	if (!rv)
+		return -ENOMEM;
+
 	spin_lock(&ls->ls_lkbidr_spin);
-	rv = idr_alloc(&ls->ls_lkbidr, lkb, 1, 0, GFP_NOWAIT);
-	if (rv >= 0)
-		lkb->lkb_id = rv;
+	rv = idr_get_new_above(&ls->ls_lkbidr, lkb, 1, &id);
+	if (!rv)
+		lkb->lkb_id = id;
 	spin_unlock(&ls->ls_lkbidr_spin);
-	idr_preload_end();
+
+	if (rv == -EAGAIN)
+		goto retry;
 
 	if (rv < 0) {
 		log_error(ls, "create_lkb idr error %d", rv);
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c
index a6bc63f..236d108 100644
--- a/fs/dlm/recover.c
+++ b/fs/dlm/recover.c
@@ -305,26 +305,27 @@ static int recover_idr_empty(struct dlm_ls *ls)
 static int recover_idr_add(struct dlm_rsb *r)
 {
 	struct dlm_ls *ls = r->res_ls;
-	int rv;
+	int rv, id;
+
+	rv = idr_pre_get(&ls->ls_recover_idr, GFP_NOFS);
+	if (!rv)
+		return -ENOMEM;
 
-	idr_preload(GFP_NOFS);
 	spin_lock(&ls->ls_recover_idr_lock);
 	if (r->res_id) {
-		rv = -1;
-		goto out_unlock;
+		spin_unlock(&ls->ls_recover_idr_lock);
+		return -1;
 	}
-	rv = idr_alloc(&ls->ls_recover_idr, r, 1, 0, GFP_NOWAIT);
-	if (rv < 0)
-		goto out_unlock;
-
-	r->res_id = rv;
+	rv = idr_get_new_above(&ls->ls_recover_idr, r, 1, &id);
+	if (rv) {
+		spin_unlock(&ls->ls_recover_idr_lock);
+		return rv;
+	}
+	r->res_id = id;
 	ls->ls_recover_list_count++;
 	dlm_hold_rsb(r);
-	rv = 0;
-out_unlock:
 	spin_unlock(&ls->ls_recover_idr_lock);
-	idr_preload_end();
-	return rv;
+	return 0;
 }
 
 static void recover_idr_del(struct dlm_rsb *r)
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 47d1008..2e9779b 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -29,14 +29,15 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
 
 	if (clp->rpc_ops->version != 4 || minorversion != 0)
 		return ret;
-	idr_preload(GFP_KERNEL);
+retry:
+	if (!idr_pre_get(&nn->cb_ident_idr, GFP_KERNEL))
+		return -ENOMEM;
 	spin_lock(&nn->nfs_client_lock);
-	ret = idr_alloc(&nn->cb_ident_idr, clp, 0, 0, GFP_NOWAIT);
-	if (ret >= 0)
-		clp->cl_cb_ident = ret;
+	ret = idr_get_new(&nn->cb_ident_idr, clp, &clp->cl_cb_ident);
 	spin_unlock(&nn->nfs_client_lock);
-	idr_preload_end();
-	return ret < 0 ? ret : 0;
+	if (ret == -EAGAIN)
+		goto retry;
+	return ret;
 }
 
 #ifdef CONFIG_NFS_V4_1
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index e0f7c12..07f7a92 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -364,20 +364,22 @@ static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock,
 {
 	int ret;
 
-	idr_preload(GFP_KERNEL);
-	spin_lock(idr_lock);
+	do {
+		if (unlikely(!idr_pre_get(idr, GFP_KERNEL)))
+			return -ENOMEM;
 
-	ret = idr_alloc(idr, i_mark, *last_wd + 1, 0, GFP_NOWAIT);
-	if (ret >= 0) {
+		spin_lock(idr_lock);
+		ret = idr_get_new_above(idr, i_mark, *last_wd + 1,
+					&i_mark->wd);
 		/* we added the mark to the idr, take a reference */
-		i_mark->wd = ret;
-		*last_wd = i_mark->wd;
-		fsnotify_get_mark(&i_mark->fsn_mark);
-	}
+		if (!ret) {
+			*last_wd = i_mark->wd;
+			fsnotify_get_mark(&i_mark->fsn_mark);
+		}
+		spin_unlock(idr_lock);
+	} while (ret == -EAGAIN);
 
-	spin_unlock(idr_lock);
-	idr_preload_end();
-	return ret < 0 ? ret : 0;
+	return ret;
 }
 
 static struct inotify_inode_mark *inotify_idr_find_locked(struct fsnotify_group *group,
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 33b8924..a1d83c5 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -304,22 +304,28 @@ static u8 o2net_num_from_nn(struct o2net_node *nn)
 
 static int o2net_prep_nsw(struct o2net_node *nn, struct o2net_status_wait *nsw)
 {
-	int ret;
+	int ret = 0;
 
-	spin_lock(&nn->nn_lock);
-	ret = idr_alloc(&nn->nn_status_idr, nsw, 0, 0, GFP_ATOMIC);
-	if (ret >= 0) {
-		nsw->ns_id = ret;
-		list_add_tail(&nsw->ns_node_item, &nn->nn_status_list);
+	do {
+		if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) {
+			ret = -EAGAIN;
+			break;
+		}
+		spin_lock(&nn->nn_lock);
+		ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id);
+		if (ret == 0)
+			list_add_tail(&nsw->ns_node_item,
+				      &nn->nn_status_list);
+		spin_unlock(&nn->nn_lock);
+	} while (ret == -EAGAIN);
+
+	if (ret == 0)  {
+		init_waitqueue_head(&nsw->ns_wq);
+		nsw->ns_sys_status = O2NET_ERR_NONE;
+		nsw->ns_status = 0;
 	}
-	spin_unlock(&nn->nn_lock);
-	if (ret < 0)
-		return ret;
 
-	init_waitqueue_head(&nsw->ns_wq);
-	nsw->ns_sys_status = O2NET_ERR_NONE;
-	nsw->ns_status = 0;
-	return 0;
+	return ret;
 }
 
 static void o2net_complete_nsw_locked(struct o2net_node *nn,
diff --git a/include/linux/idr.h b/include/linux/idr.h
index 8d3ffe1..92e84f7 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -94,29 +94,15 @@ struct idr {
 void *idr_find(struct idr *idp, int id);
 int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
 int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
-void idr_preload(gfp_t gfp_mask);
-int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask);
 int idr_for_each(struct idr *idp,
 		 int (*fn)(int id, void *p, void *data), void *data);
 void *idr_get_next(struct idr *idp, int *nextid);
 void *idr_replace(struct idr *idp, void *ptr, int id);
 void idr_remove(struct idr *idp, int id);
-void idr_free(struct idr *idp, int id);
 void idr_destroy(struct idr *idp);
 void idr_init(struct idr *idp);
 
 /**
- * idr_preload_end - end preload section started with idr_preload()
- *
- * Each idr_preload() should be matched with an invocation of this
- * function.  See idr_preload() for details.
- */
-static inline void idr_preload_end(void)
-{
-	preempt_enable();
-}
-
-/**
  * idr_get_new - allocate new idr entry
  * @idp: idr handle
  * @ptr: pointer you want associated with the id
diff --git a/ipc/util.c b/ipc/util.c
index 91ce0bc..74e1d9c 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -252,7 +252,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
 {
 	kuid_t euid;
 	kgid_t egid;
-	int id;
+	int id, err;
 	int next_id = ids->next_id;
 
 	if (size > IPCMNI)
@@ -261,21 +261,17 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
 	if (ids->in_use >= size)
 		return -ENOSPC;
 
-	idr_preload(GFP_KERNEL);
-
 	spin_lock_init(&new->lock);
 	new->deleted = 0;
 	rcu_read_lock();
 	spin_lock(&new->lock);
 
-	id = idr_alloc(&ids->ipcs_idr, new,
-		       (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0,
-		       GFP_NOWAIT);
-	idr_preload_end();
-	if (id < 0) {
+	err = idr_get_new_above(&ids->ipcs_idr, new,
+				(next_id < 0) ? 0 : ipcid_to_idx(next_id), &id);
+	if (err) {
 		spin_unlock(&new->lock);
 		rcu_read_unlock();
-		return id;
+		return err;
 	}
 
 	ids->in_use++;
@@ -311,10 +307,19 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
 		struct ipc_ops *ops, struct ipc_params *params)
 {
 	int err;
+retry:
+	err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
+
+	if (!err)
+		return -ENOMEM;
 
 	down_write(&ids->rw_mutex);
 	err = ops->getnew(ns, params);
 	up_write(&ids->rw_mutex);
+
+	if (err == -EAGAIN)
+		goto retry;
+
 	return err;
 }
 
@@ -370,7 +375,9 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
 {
 	struct kern_ipc_perm *ipcp;
 	int flg = params->flg;
-	int err = 0;
+	int err;
+retry:
+	err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
 
 	/*
 	 * Take the lock as a writer since we are potentially going to add
@@ -406,6 +413,9 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
 	}
 	up_write(&ids->rw_mutex);
 
+	if (err == -EAGAIN)
+		goto retry;
+
 	return err;
 }
 
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 3710ba8..5bff65a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -5282,7 +5282,7 @@ EXPORT_SYMBOL_GPL(free_css_id);
 static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
 {
 	struct css_id *newid;
-	int ret, size;
+	int myid, error, size;
 
 	BUG_ON(!ss->use_id);
 
@@ -5290,24 +5290,35 @@ static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
 	newid = kzalloc(size, GFP_KERNEL);
 	if (!newid)
 		return ERR_PTR(-ENOMEM);
-
-	idr_preload(GFP_KERNEL);
+	/* get id */
+	if (unlikely(!idr_pre_get(&ss->idr, GFP_KERNEL))) {
+		error = -ENOMEM;
+		goto err_out;
+	}
 	spin_lock(&ss->id_lock);
 	/* Don't use 0. allocates an ID of 1-65535 */
-	ret = idr_alloc(&ss->idr, newid, 1, CSS_ID_MAX + 1, GFP_NOWAIT);
+	error = idr_get_new_above(&ss->idr, newid, 1, &myid);
 	spin_unlock(&ss->id_lock);
-	idr_preload_end();
 
 	/* Returns error when there are no free spaces for new ID.*/
-	if (ret < 0)
+	if (error) {
+		error = -ENOSPC;
 		goto err_out;
+	}
+	if (myid > CSS_ID_MAX)
+		goto remove_idr;
 
-	newid->id = ret;
+	newid->id = myid;
 	newid->depth = depth;
 	return newid;
+remove_idr:
+	error = -ENOSPC;
+	spin_lock(&ss->id_lock);
+	idr_remove(&ss->idr, myid);
+	spin_unlock(&ss->id_lock);
 err_out:
 	kfree(newid);
-	return ERR_PTR(ret);
+	return ERR_PTR(error);
 
 }
 
diff --git a/kernel/events/core.c b/kernel/events/core.c
index d6df1b9..19e9809 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5963,9 +5963,13 @@ int perf_pmu_register(struct pmu *pmu, char *name, int type)
 	pmu->name = name;
 
 	if (type < 0) {
-		type = idr_alloc(&pmu_idr, pmu, PERF_TYPE_MAX, 0, GFP_KERNEL);
-		if (type < 0) {
-			ret = type;
+		int err = idr_pre_get(&pmu_idr, GFP_KERNEL);
+		if (!err)
+			goto free_pdc;
+
+		err = idr_get_new_above(&pmu_idr, pmu, PERF_TYPE_MAX, &type);
+		if (err) {
+			ret = err;
 			goto free_pdc;
 		}
 	}
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index b51bb08..10349d5 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -552,22 +552,24 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
 		return -EAGAIN;
 
 	spin_lock_init(&new_timer->it_lock);
-
-	idr_preload(GFP_KERNEL);
+ retry:
+	if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) {
+		error = -EAGAIN;
+		goto out;
+	}
 	spin_lock_irq(&idr_lock);
-	error = idr_alloc(&posix_timers_id, new_timer, 0, 0, GFP_NOWAIT);
+	error = idr_get_new(&posix_timers_id, new_timer, &new_timer_id);
 	spin_unlock_irq(&idr_lock);
-	idr_preload_end();
-	if (error < 0) {
+	if (error) {
+		if (error == -EAGAIN)
+			goto retry;
 		/*
 		 * Weird looking, but we return EAGAIN if the IDR is
 		 * full (proper POSIX return value for this)
 		 */
-		if (error == -ENOSPC)
-			error = -EAGAIN;
+		error = -EAGAIN;
 		goto out;
 	}
-	new_timer_id = error;
 
 	it_id_set = IT_ID_SET;
 	new_timer->it_id = (timer_t) new_timer_id;
diff --git a/lib/idr.c b/lib/idr.c
index 5115705..b13aae5 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -35,12 +35,8 @@
 #include <linux/string.h>
 #include <linux/idr.h>
 #include <linux/spinlock.h>
-#include <linux/percpu.h>
-#include <linux/hardirq.h>
 
 static struct kmem_cache *idr_layer_cache;
-static DEFINE_PER_CPU(struct idr_layer *, idr_preload_head);
-static DEFINE_PER_CPU(int, idr_preload_cnt);
 static DEFINE_SPINLOCK(simple_ida_lock);
 
 static struct idr_layer *get_from_free_list(struct idr *idp)
@@ -58,50 +54,6 @@ static struct idr_layer *get_from_free_list(struct idr *idp)
 	return(p);
 }
 
-/**
- * idr_layer_alloc - allocate a new idr_layer
- * @gfp_mask: allocation mask
- * @layer_idr: optional idr to allocate from
- *
- * If @layer_idr is %NULL, directly allocate one using @gfp_mask or fetch
- * one from the per-cpu preload buffer.  If @layer_idr is not %NULL, fetch
- * an idr_layer from @idr->id_free.
- *
- * @layer_idr is to maintain backward compatibility with the old alloc
- * interface - idr_pre_get() and idr_get_new*() - and will be removed
- * together with per-pool preload buffer.
- */
-static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
-{
-	struct idr_layer *new;
-
-	/* this is the old path, bypass to get_from_free_list() */
-	if (layer_idr)
-		return get_from_free_list(layer_idr);
-
-	/* try to allocate directly from kmem_cache */
-	new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
-	if (new)
-		return new;
-
-	/*
-	 * Try to fetch one from the per-cpu preload buffer if in process
-	 * context.  See idr_preload() for details.
-	 */
-	if (in_interrupt())
-		return NULL;
-
-	preempt_disable();
-	new = __this_cpu_read(idr_preload_head);
-	if (new) {
-		__this_cpu_write(idr_preload_head, new->ary[0]);
-		__this_cpu_dec(idr_preload_cnt);
-		new->ary[0] = NULL;
-	}
-	preempt_enable();
-	return new;
-}
-
 static void idr_layer_rcu_free(struct rcu_head *head)
 {
 	struct idr_layer *layer;
@@ -187,8 +139,6 @@ EXPORT_SYMBOL(idr_pre_get);
  * @starting_id: id to start search at
  * @id: pointer to the allocated handle
  * @pa: idr_layer[MAX_IDR_LEVEL] used as backtrack buffer
- * @gfp_mask: allocation mask for idr_layer_alloc()
- * @layer_idr: optional idr passed to idr_layer_alloc()
  *
  * Allocate an id in range [@starting_id, INT_MAX] from @idp without
  * growing its depth.  Returns
@@ -198,8 +148,7 @@ EXPORT_SYMBOL(idr_pre_get);
  *  -ENOSPC if the id space is exhausted,
  *  -ENOMEM if more idr_layers need to be allocated.
  */
-static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa,
-		     gfp_t gfp_mask, struct idr *layer_idr)
+static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
 {
 	int n, m, sh;
 	struct idr_layer *p, *new;
@@ -253,7 +202,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa,
 		 * Create the layer below if it is missing.
 		 */
 		if (!p->ary[m]) {
-			new = idr_layer_alloc(gfp_mask, layer_idr);
+			new = get_from_free_list(idp);
 			if (!new)
 				return -ENOMEM;
 			new->layer = l-1;
@@ -269,8 +218,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa,
 }
 
 static int idr_get_empty_slot(struct idr *idp, int starting_id,
-			      struct idr_layer **pa, gfp_t gfp_mask,
-			      struct idr *layer_idr)
+			      struct idr_layer **pa)
 {
 	struct idr_layer *p, *new;
 	int layers, v, id;
@@ -281,7 +229,7 @@ build_up:
 	p = idp->top;
 	layers = idp->layers;
 	if (unlikely(!p)) {
-		if (!(p = idr_layer_alloc(gfp_mask, layer_idr)))
+		if (!(p = get_from_free_list(idp)))
 			return -ENOMEM;
 		p->layer = 0;
 		layers = 1;
@@ -300,7 +248,7 @@ build_up:
 			p->layer++;
 			continue;
 		}
-		if (!(new = idr_layer_alloc(gfp_mask, layer_idr))) {
+		if (!(new = get_from_free_list(idp))) {
 			/*
 			 * The allocation failed.  If we built part of
 			 * the structure tear it down.
@@ -324,7 +272,7 @@ build_up:
 	}
 	rcu_assign_pointer(idp->top, p);
 	idp->layers = layers;
-	v = sub_alloc(idp, &id, pa, gfp_mask, layer_idr);
+	v = sub_alloc(idp, &id, pa);
 	if (v == -EAGAIN)
 		goto build_up;
 	return(v);
@@ -364,7 +312,7 @@ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
 	struct idr_layer *pa[MAX_IDR_LEVEL];
 	int rv;
 
-	rv = idr_get_empty_slot(idp, starting_id, pa, 0, idp);
+	rv = idr_get_empty_slot(idp, starting_id, pa);
 	if (rv < 0)
 		return rv == -ENOMEM ? -EAGAIN : rv;
 
@@ -374,109 +322,6 @@ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
 }
 EXPORT_SYMBOL(idr_get_new_above);
 
-/**
- * idr_preload - preload for idr_alloc()
- * @gfp_mask: allocation mask to use for preloading
- *
- * Preload per-cpu layer buffer for idr_alloc().  Can only be used from
- * process context and each idr_preload() invocation should be matched with
- * idr_preload_end().  Note that preemption is disabled while preloaded.
- *
- * The first idr_alloc() in the preloaded section can be treated as if it
- * were invoked with @gfp_mask used for preloading.  This allows using more
- * permissive allocation masks for idrs protected by spinlocks.
- *
- * For example, if idr_alloc() below fails, the failure can be treated as
- * if idr_alloc() were called with GFP_KERNEL rather than GFP_NOWAIT.
- *
- *	idr_preload(GFP_KERNEL);
- *	spin_lock(lock);
- *
- *	id = idr_alloc(idr, ptr, start, end, GFP_NOWAIT);
- *
- *	spin_unlock(lock);
- *	idr_preload_end();
- *	if (id < 0)
- *		error;
- */
-void idr_preload(gfp_t gfp_mask)
-{
-	/*
-	 * Consuming preload buffer from non-process context breaks preload
-	 * allocation guarantee.  Disallow usage from those contexts.
-	 */
-	WARN_ON_ONCE(in_interrupt());
-	might_sleep_if(gfp_mask & __GFP_WAIT);
-
-	preempt_disable();
-
-	/*
-	 * idr_alloc() is likely to succeed w/o full idr_layer buffer and
-	 * return value from idr_alloc() needs to be checked for failure
-	 * anyway.  Silently give up if allocation fails.  The caller can
-	 * treat failures from idr_alloc() as if idr_alloc() were called
-	 * with @gfp_mask which should be enough.
-	 */
-	while (__this_cpu_read(idr_preload_cnt) < MAX_IDR_FREE) {
-		struct idr_layer *new;
-
-		preempt_enable();
-		new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
-		preempt_disable();
-		if (!new)
-			break;
-
-		/* link the new one to per-cpu preload list */
-		new->ary[0] = __this_cpu_read(idr_preload_head);
-		__this_cpu_write(idr_preload_head, new);
-		__this_cpu_inc(idr_preload_cnt);
-	}
-}
-EXPORT_SYMBOL(idr_preload);
-
-/**
- * idr_alloc - allocate new idr entry
- * @idr: the (initialized) idr
- * @ptr: pointer to be associated with the new id
- * @start: the minimum id (inclusive)
- * @end: the maximum id (exclusive, 0 for max)
- * @gfp_mask: memory allocation flags
- *
- * Allocate an id in [start, end) and associate it with @ptr.  If no ID is
- * available in the specified range, returns -ENOSPC.  On memory allocation
- * failure, returns -ENOMEM.
- *
- * The user is responsible for exclusively synchronizing all operations
- * which may modify @idr.  However, read-only accesses such as idr_find()
- * or iteration can be performed under RCU read lock provided the user
- * destroys @ptr in RCU-safe way after removal from idr.
- */
-int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask)
-{
-	int max = end ? end - 1 : INT_MAX;	/* inclusive upper limit */
-	struct idr_layer *pa[MAX_IDR_LEVEL];
-	int id;
-
-	might_sleep_if(gfp_mask & __GFP_WAIT);
-
-	/* sanity checks */
-	if (WARN_ON_ONCE(start < 0 || end < 0))
-		return -EINVAL;
-	if (unlikely(max < start))
-		return -ENOSPC;
-
-	/* allocate id */
-	id = idr_get_empty_slot(idr, start, pa, gfp_mask, NULL);
-	if (unlikely(id < 0))
-		return id;
-	if (unlikely(id > max))
-		return -ENOSPC;
-
-	idr_fill_slot(ptr, id, pa);
-	return id;
-}
-EXPORT_SYMBOL_GPL(idr_alloc);
-
 static void idr_remove_warning(int id)
 {
 	printk(KERN_WARNING
@@ -924,7 +769,7 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
 
  restart:
 	/* get vacant slot */
-	t = idr_get_empty_slot(&ida->idr, idr_id, pa, 0, &ida->idr);
+	t = idr_get_empty_slot(&ida->idr, idr_id, pa);
 	if (t < 0)
 		return t == -ENOMEM ? -EAGAIN : t;
 
diff --git a/net/9p/util.c b/net/9p/util.c
index 59f278e..6ceeeb3 100644
--- a/net/9p/util.c
+++ b/net/9p/util.c
@@ -87,18 +87,23 @@ EXPORT_SYMBOL(p9_idpool_destroy);
 
 int p9_idpool_get(struct p9_idpool *p)
 {
-	int i;
+	int i = 0;
+	int error;
 	unsigned long flags;
 
-	idr_preload(GFP_NOFS);
+retry:
+	if (idr_pre_get(&p->pool, GFP_NOFS) == 0)
+		return -1;
+
 	spin_lock_irqsave(&p->lock, flags);
 
 	/* no need to store exactly p, we just need something non-null */
-	i = idr_alloc(&p->pool, p, 0, 0, GFP_NOWAIT);
-
+	error = idr_get_new(&p->pool, p, &i);
 	spin_unlock_irqrestore(&p->lock, flags);
-	idr_preload_end();
-	if (i < 0)
+
+	if (error == -EAGAIN)
+		goto retry;
+	else if (error)
 		return -1;
 
 	p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 632f2a7..2bdd454 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -647,6 +647,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 
 	spin_lock_init(&local->ack_status_lock);
 	idr_init(&local->ack_status_frames);
+	/* preallocate at least one entry */
+	idr_pre_get(&local->ack_status_frames, GFP_KERNEL);
 
 	sta_info_init(local);
 
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5a62468..a2cb6a3 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1999,14 +1999,24 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 		skb = skb_clone(skb, GFP_ATOMIC);
 		if (skb) {
 			unsigned long flags;
-			int id;
+			int id, r;
 
 			spin_lock_irqsave(&local->ack_status_lock, flags);
-			id = idr_alloc(&local->ack_status_frames, orig_skb,
-				       1, 0x10000, GFP_ATOMIC);
+			r = idr_get_new_above(&local->ack_status_frames,
+					      orig_skb, 1, &id);
+			if (r == -EAGAIN) {
+				idr_pre_get(&local->ack_status_frames,
+					    GFP_ATOMIC);
+				r = idr_get_new_above(&local->ack_status_frames,
+						      orig_skb, 1, &id);
+			}
+			if (WARN_ON(!id) || id > 0xffff) {
+				idr_remove(&local->ack_status_frames, id);
+				r = -ERANGE;
+			}
 			spin_unlock_irqrestore(&local->ack_status_lock, flags);
 
-			if (id >= 0) {
+			if (!r) {
 				info_id = id;
 				info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
 			} else if (skb_shared(skb)) {
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 43cd0dd..2f95f5a 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1591,31 +1591,32 @@ int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
 /* Set an association id for a given association */
 int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
 {
-	bool preload = gfp & __GFP_WAIT;
-	int ret;
+	int assoc_id;
+	int error = 0;
 
 	/* If the id is already assigned, keep it. */
 	if (asoc->assoc_id)
-		return 0;
+		return error;
+retry:
+	if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
+		return -ENOMEM;
 
-	if (preload)
-		idr_preload(gfp);
 	spin_lock_bh(&sctp_assocs_id_lock);
-	/* 0 is not a valid id, idr_low is always >= 1 */
-	ret = idr_alloc(&sctp_assocs_id, asoc, idr_low, 0, GFP_NOWAIT);
-	if (ret >= 0) {
-		idr_low = ret + 1;
+	error = idr_get_new_above(&sctp_assocs_id, (void *)asoc,
+				    idr_low, &assoc_id);
+	if (!error) {
+		idr_low = assoc_id + 1;
 		if (idr_low == INT_MAX)
 			idr_low = 1;
 	}
 	spin_unlock_bh(&sctp_assocs_id_lock);
-	if (preload)
-		idr_preload_end();
-	if (ret < 0)
-		return ret;
+	if (error == -EAGAIN)
+		goto retry;
+	else if (error)
+		return error;
 
-	asoc->assoc_id = (sctp_assoc_t)ret;
-	return 0;
+	asoc->assoc_id = (sctp_assoc_t) assoc_id;
+	return error;
 }
 
 /* Free the ASCONF queue */
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index acb8650..7d7c9d8 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -172,9 +172,22 @@ else
 fi
 maintainer="$name <$email>"
 
+# Try to determine distribution
+if [ -e $(which lsb_release) ]; then
+       codename=$(lsb_release --codename --short)
+       if [ "$codename" != "" ]; then
+		distribution=$codename
+       else
+		distribution="UNRELEASED"
+		echo "WARNING: The distribution could NOT be determined!"
+       fi
+else
+       echo "HINT: Install lsb_release binary, this helps to identify your distribution!"
+fi
+
 # Generate a simple changelog template
 cat <<EOF > debian/changelog
-linux-upstream ($packageversion) unstable; urgency=low
+linux-upstream ($packageversion) $distribution; urgency=low
 
   * Custom built Linux kernel.
 
@@ -188,10 +201,10 @@ This is a packacked upstream version of the Linux kernel.
 The sources may be found at most Linux ftp sites, including:
 ftp://ftp.kernel.org/pub/linux/kernel
 
-Copyright: 1991 - 2009 Linus Torvalds and others.
+Copyright: 1991 - 2013 Linus Torvalds and others.
 
 The git repository for mainline kernel development is at:
-git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
+git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
