linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc()
@ 2013-02-06 19:39 Tejun Heo
  2013-02-06 19:39 ` [PATCH 01/77] idr: fix a subtle bug in idr_get_next() Tejun Heo
                   ` (77 more replies)
  0 siblings, 78 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

(If you're reading this patchset for the first time, this patchset is
 an effort to improve idr interface.  This posting is mostly for
 collecting and routing the patches towards -mm.  Please follow the
 link at the end for details on each patchset.)

Hello, Andrew.

This patchset is combination of the following three on top of
linux-next as of 20130204 (the one before idr_removal_all() got
included).

  [1] [PATCH] idr: fix a subtle bug in idr_get_next()
+ [2] [PATCHSET] idr: deprecate idr_remove_all()
+ [3] [PATCHSET] idr: implement idr_alloc() and convert existing users (w/ all updates)

Please note that we need the idr_get_next() fix before
idr_remove_all() deprecation.

The idr_alloc() part has all the posted updates rolled in and acks
added, and I think it's at least ready for testing.  Ah, right, I
skipped deprecation of idr_pre_get() and idr_get_new*() for now.  nfs
changes are being routed separately and we can do the deprecation
after after -rc1.

This patchset contains the following 77 patches.

 0001-idr-fix-a-subtle-bug-in-idr_get_next.patch
 0002-idr-make-idr_destroy-imply-idr_remove_all.patch
 0003-atm-nicstar-don-t-use-idr_remove_all.patch
 0004-block-loop-don-t-use-idr_remove_all.patch
 0005-firewire-don-t-use-idr_remove_all.patch
 0006-drm-don-t-use-idr_remove_all.patch
 0007-dm-don-t-use-idr_remove_all.patch
 0008-remoteproc-don-t-use-idr_remove_all.patch
 0009-rpmsg-don-t-use-idr_remove_all.patch
 0010-dlm-use-idr_for_each_entry-in-recover_idr_clear-erro.patch
 0011-dlm-don-t-use-idr_remove_all.patch
 0012-nfs-idr_destroy-no-longer-needs-idr_remove_all.patch
 0013-inotify-don-t-use-idr_remove_all.patch
 0014-cgroup-don-t-use-idr_remove_all.patch
 0015-idr-deprecate-idr_remove_all.patch
 0016-idr-cosmetic-updates-to-struct-initializer-definitio.patch
 0017-idr-relocate-idr_for_each_entry-and-reorganize-id-r-.patch
 0018-idr-remove-_idr_rc_to_errno-hack.patch
 0019-idr-refactor-idr_get_new_above.patch
 0020-idr-implement-idr_preload-_end-and-idr_alloc.patch
 0021-block-fix-synchronization-and-limit-check-in-blk_all.patch
 0022-block-convert-to-idr_alloc.patch
 0023-block-loop-convert-to-idr_alloc.patch
 0024-atm-nicstar-convert-to-idr_alloc.patch
 0025-drbd-convert-to-idr_alloc.patch
 0026-dca-convert-to-idr_alloc.patch
 0027-dmaengine-convert-to-idr_alloc.patch
 0028-firewire-add-minor-number-range-check-to-fw_device_i.patch
 0029-firewire-convert-to-idr_alloc.patch
 0030-gpio-convert-to-idr_alloc.patch
 0031-drm-convert-to-idr_alloc.patch
 0032-drm-exynos-convert-to-idr_alloc.patch
 0033-drm-i915-convert-to-idr_alloc.patch
 0034-drm-sis-convert-to-idr_alloc.patch
 0035-drm-via-convert-to-idr_alloc.patch
 0036-drm-vmwgfx-convert-to-idr_alloc.patch
 0037-i2c-convert-to-idr_alloc.patch
 0038-IB-core-convert-to-idr_alloc.patch
 0039-IB-amso1100-convert-to-idr_alloc.patch
 0040-IB-cxgb3-convert-to-idr_alloc.patch
 0041-IB-cxgb4-convert-to-idr_alloc.patch
 0042-IB-ehca-convert-to-idr_alloc.patch
 0043-IB-ipath-convert-to-idr_alloc.patch
 0044-IB-mlx4-convert-to-idr_alloc.patch
 0045-IB-ocrdma-convert-to-idr_alloc.patch
 0046-IB-qib-convert-to-idr_alloc.patch
 0047-dm-convert-to-idr_alloc.patch
 0048-memstick-convert-to-idr_alloc.patch
 0049-mfd-convert-to-idr_alloc.patch
 0050-misc-c2port-convert-to-idr_alloc.patch
 0051-misc-tifm_core-convert-to-idr_alloc.patch
 0052-mmc-convert-to-idr_alloc.patch
 0053-mtd-convert-to-idr_alloc.patch
 0054-macvtap-convert-to-idr_alloc.patch
 0055-ppp-convert-to-idr_alloc.patch
 0056-power-convert-to-idr_alloc.patch
 0057-pps-convert-to-idr_alloc.patch
 0058-remoteproc-convert-to-idr_alloc.patch
 0059-rpmsg-convert-to-idr_alloc.patch
 0060-scsi-bfa-convert-to-idr_alloc.patch
 0061-scsi-convert-to-idr_alloc.patch
 0062-target-iscsi-convert-to-idr_alloc.patch
 0063-scsi-lpfc-convert-to-idr_alloc.patch
 0064-thermal-convert-to-idr_alloc.patch
 0065-uio-convert-to-idr_alloc.patch
 0066-vfio-convert-to-idr_alloc.patch
 0067-dlm-convert-to-idr_alloc.patch
 0068-inotify-convert-to-idr_alloc.patch
 0069-ocfs2-convert-to-idr_alloc.patch
 0070-ipc-convert-to-idr_alloc.patch
 0071-cgroup-convert-to-idr_alloc.patch
 0072-events-convert-to-idr_alloc.patch
 0073-posix-timers-convert-to-idr_alloc.patch
 0074-net-9p-convert-to-idr_alloc.patch
 0075-mac80211-convert-to-idr_alloc.patch
 0076-sctp-convert-to-idr_alloc.patch
 0077-nfs4client-convert-to-idr_alloc.patch

and is available in the following git branch.

 git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc.git convert-to-idr_alloc

diffstat follows.

 block/bsg.c                                |   26 --
 block/genhd.c                              |   22 --
 drivers/atm/nicstar.c                      |   25 --
 drivers/block/drbd/drbd_main.c             |   29 +-
 drivers/block/loop.c                       |   24 --
 drivers/dca/dca-sysfs.c                    |   23 --
 drivers/dma/dmaengine.c                    |   16 -
 drivers/firewire/core-cdev.c               |   20 -
 drivers/firewire/core-device.c             |    4 
 drivers/gpio/gpiolib.c                     |   11 -
 drivers/gpu/drm/drm_context.c              |   19 -
 drivers/gpu/drm/drm_crtc.c                 |   20 -
 drivers/gpu/drm/drm_drv.c                  |    1 
 drivers/gpu/drm/drm_gem.c                  |   37 +--
 drivers/gpu/drm/drm_stub.c                 |   19 -
 drivers/gpu/drm/exynos/exynos_drm_ipp.c    |   20 -
 drivers/gpu/drm/i915/i915_gem_context.c    |   21 --
 drivers/gpu/drm/sis/sis_drv.c              |    1 
 drivers/gpu/drm/sis/sis_mm.c               |   13 -
 drivers/gpu/drm/via/via_map.c              |    1 
 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                            |   55 +----
 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       |   11 -
 drivers/rpmsg/virtio_rpmsg_bus.c           |   31 +--
 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/lockspace.c                         |    1 
 fs/dlm/recover.c                           |   52 ++---
 fs/nfs/client.c                            |    1 
 fs/nfs/nfs4client.c                        |   13 -
 fs/notify/inotify/inotify_fsnotify.c       |    1 
 fs/notify/inotify/inotify_user.c           |   24 +-
 fs/ocfs2/cluster/tcp.c                     |   32 +--
 include/linux/idr.h                        |  109 +++++++---
 ipc/util.c                                 |   30 --
 kernel/cgroup.c                            |   31 ---
 kernel/events/core.c                       |   10 
 kernel/posix-timers.c                      |   18 -
 lib/idr.c                                  |  298 ++++++++++++++++++++---------
 net/9p/util.c                              |   17 -
 net/mac80211/main.c                        |    2 
 net/mac80211/tx.c                          |   18 -
 net/sctp/associola.c                       |   31 +--
 84 files changed, 832 insertions(+), 1184 deletions(-)

Thanks.

--
tejun

[1] https://lkml.org/lkml/2013/2/2/145
[2] https://lkml.org/lkml/2013/1/25/759
[3] http://thread.gmane.org/gmane.linux.kernel/1434387

^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 01/77] idr: fix a subtle bug in idr_get_next()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 02/77] idr: make idr_destroy() imply idr_remove_all() Tejun Heo
                   ` (76 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, KAMEZAWA Hiroyuki, stable

The iteration logic of idr_get_next() is borrowed mostly verbatim from
idr_for_each().  It walks down the tree looking for the slot matching
the current ID.  If the matching slot is not found, the ID is
incremented by the distance of single slot at the given level and
repeats.

The implementation assumes that during the whole iteration id is
aligned to the layer boundaries of the level closest to the leaf,
which is true for all iterations starting from zero or an existing
element and thus is fine for idr_for_each().

However, idr_get_next() may be given any point and if the starting id
hits in the middle of a non-existent layer, increment to the next
layer will end up skipping the same offset into it.  For example, an
IDR with IDs filled between [64, 127] would look like the following.

          [  0  64 ... ]
       /----/   |
       |        |
      NULL    [ 64 ... 127 ]

If idr_get_next() is called with 63 as the starting point, it will try
to follow down the pointer from 0.  As it is NULL, it will then try to
proceed to the next slot in the same level by adding the slot distance
at that level which is 64 - making the next try 127.  It goes around
the loop and finds and returns 127 skipping [64, 126].

Note that this bug also triggers in idr_for_each_entry() loop which
deletes during iteration as deletions can make layers go away leaving
the iteration with unaligned ID into missing layers.

Fix it by ensuring proceeding to the next slot doesn't carry over the
unaligned offset - ie. use round_up(id + 1, slot_distance) instead of
id += slot_distance.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: David Teigland <teigland@redhat.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: stable@vger.kernel.org
---
 lib/idr.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/lib/idr.c b/lib/idr.c
index 6482390..ca5aa00 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -625,7 +625,14 @@ void *idr_get_next(struct idr *idp, int *nextidp)
 			return p;
 		}
 
-		id += 1 << n;
+		/*
+		 * Proceed to the next layer at the current level.  Unlike
+		 * idr_for_each(), @id isn't guaranteed to be aligned to
+		 * layer boundary at this point and adding 1 << n may
+		 * incorrectly skip IDs.  Make sure we jump to the
+		 * beginning of the next layer using round_up().
+		 */
+		id = round_up(id + 1, 1 << n);
 		while (n < fls(id)) {
 			n += IDR_BITS;
 			p = *--paa;
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 02/77] idr: make idr_destroy() imply idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
  2013-02-06 19:39 ` [PATCH 01/77] idr: fix a subtle bug in idr_get_next() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 03/77] atm/nicstar: don't use idr_remove_all() Tejun Heo
                   ` (75 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo

idr is silly in quite a few ways, one of which is how it's supposed to
be destroyed - idr_destroy() doesn't release IDs and doesn't even
whine if the idr isn't empty.  If the caller forgets idr_remove_all(),
it simply leaks memory.

Even ida gets this wrong and leaks memory on destruction.  There is
absoltely no reason not to call idr_remove_all() from idr_destroy().
Nobody is abusing idr_destroy() for shrinking free layer buffer and
continues to use idr after idr_destroy(), so it's safe to do
remove_all from destroy.

In the whole kernel, there is only one place where idr_remove_all() is
legitimiately used without following idr_destroy() while there are
quite a few places where the caller forgets either idr_remove_all() or
idr_destroy() leaking memory.

This patch makes idr_destroy() call idr_destroy_all() and updates the
function description accordingly.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 lib/idr.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/lib/idr.c b/lib/idr.c
index ca5aa00..b8602e0 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -436,15 +436,6 @@ EXPORT_SYMBOL(idr_remove);
 /**
  * idr_remove_all - remove all ids from the given idr tree
  * @idp: idr handle
- *
- * idr_destroy() only frees up unused, cached idp_layers, but this
- * function will remove all id mappings and leave all idp_layers
- * unused.
- *
- * A typical clean-up sequence for objects stored in an idr tree will
- * use idr_for_each() to free all objects, if necessay, then
- * idr_remove_all() to remove all ids, and idr_destroy() to free
- * up the cached idr_layers.
  */
 void idr_remove_all(struct idr *idp)
 {
@@ -484,9 +475,20 @@ EXPORT_SYMBOL(idr_remove_all);
 /**
  * idr_destroy - release all cached layers within an idr tree
  * @idp: idr handle
+ *
+ * Free all id mappings and all idp_layers.  After this function, @idp is
+ * completely unused and can be freed / recycled.  The caller is
+ * responsible for ensuring that no one else accesses @idp during or after
+ * idr_destroy().
+ *
+ * A typical clean-up sequence for objects stored in an idr tree will use
+ * idr_for_each() to free all objects, if necessay, then idr_destroy() to
+ * free up the id mappings and cached idr_layers.
  */
 void idr_destroy(struct idr *idp)
 {
+	idr_remove_all(idp);
+
 	while (idp->id_free_cnt) {
 		struct idr_layer *p = get_from_free_list(idp);
 		kmem_cache_free(idr_layer_cache, p);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 03/77] atm/nicstar: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
  2013-02-06 19:39 ` [PATCH 01/77] idr: fix a subtle bug in idr_get_next() Tejun Heo
  2013-02-06 19:39 ` [PATCH 02/77] idr: make idr_destroy() imply idr_remove_all() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 04/77] block/loop: " Tejun Heo
                   ` (74 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Chas Williams, netdev

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop its usage.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Chas Williams <chas@cmf.nrl.navy.mil>
Cc: netdev@vger.kernel.org
---
 drivers/atm/nicstar.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index ed1d2b7..628787e 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -251,7 +251,6 @@ static void nicstar_remove_one(struct pci_dev *pcidev)
 		if (card->scd2vc[j] != NULL)
 			free_scq(card, card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc);
 	}
-	idr_remove_all(&card->idr);
 	idr_destroy(&card->idr);
 	pci_free_consistent(card->pcidev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,
 			    card->rsq.org, card->rsq.dma);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 04/77] block/loop: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (2 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 03/77] atm/nicstar: don't use idr_remove_all() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 05/77] firewire: " Tejun Heo
                   ` (73 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Jens Axboe

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop its usage.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Jens Axboe <axboe@kernel.dk>
---
 drivers/block/loop.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index ae12512..3b9c32b 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1911,7 +1911,6 @@ static void __exit loop_exit(void)
 	range = max_loop ? max_loop << part_shift : 1UL << MINORBITS;
 
 	idr_for_each(&loop_index_idr, &loop_exit_cb, NULL);
-	idr_remove_all(&loop_index_idr);
 	idr_destroy(&loop_index_idr);
 
 	blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 05/77] firewire: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (3 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 04/77] block/loop: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 06/77] drm: " Tejun Heo
                   ` (72 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Stefan Richter, linux1394-devel

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop its usage.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
Cc: linux1394-devel@lists.sourceforge.net
---
 drivers/firewire/core-cdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index f8d2287..68c3138 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -1779,7 +1779,6 @@ static int fw_device_op_release(struct inode *inode, struct file *file)
 	wait_event(client->tx_flush_wait, !has_outbound_transactions(client));
 
 	idr_for_each(&client->resource_idr, shutdown_resource, client);
-	idr_remove_all(&client->resource_idr);
 	idr_destroy(&client->resource_idr);
 
 	list_for_each_entry_safe(event, next_event, &client->event_list, link)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 06/77] drm: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (4 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 05/77] firewire: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 07/77] dm: " Tejun Heo
                   ` (71 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, David Airlie, dri-devel, Inki Dae,
	Joonyoung Shim, Seung-Woo Kim, Kyungmin Park

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop its usage.

* drm_ctxbitmap_cleanup() was calling idr_remove_all() but forgetting
  idr_destroy() thus leaking all buffered free idr_layers.  Replace it
  with idr_destroy().

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: David Airlie <airlied@linux.ie>
Cc: dri-devel@lists.freedesktop.org
Cc: Inki Dae <inki.dae@samsung.com>
Cc: Joonyoung Shim <jy0922.shim@samsung.com>
Cc: Seung-Woo Kim <sw0312.kim@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/gpu/drm/drm_context.c           | 2 +-
 drivers/gpu/drm/drm_crtc.c              | 1 -
 drivers/gpu/drm/drm_drv.c               | 1 -
 drivers/gpu/drm/drm_gem.c               | 2 --
 drivers/gpu/drm/exynos/exynos_drm_ipp.c | 4 ----
 drivers/gpu/drm/sis/sis_drv.c           | 1 -
 drivers/gpu/drm/via/via_map.c           | 1 -
 7 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 45adf97..75f62c5 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -118,7 +118,7 @@ int drm_ctxbitmap_init(struct drm_device * dev)
 void drm_ctxbitmap_cleanup(struct drm_device * dev)
 {
 	mutex_lock(&dev->struct_mutex);
-	idr_remove_all(&dev->ctx_idr);
+	idr_destroy(&dev->ctx_idr);
 	mutex_unlock(&dev->struct_mutex);
 }
 
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 9c797f6..775102d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1258,7 +1258,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
 		crtc->funcs->destroy(crtc);
 	}
 
-	idr_remove_all(&dev->mode_config.crtc_idr);
 	idr_destroy(&dev->mode_config.crtc_idr);
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index be174ca..25f91cd 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -297,7 +297,6 @@ static void __exit drm_core_exit(void)
 
 	unregister_chrdev(DRM_MAJOR, "drm");
 
-	idr_remove_all(&drm_minors_idr);
 	idr_destroy(&drm_minors_idr);
 }
 
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 24efae4..e775859 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -561,8 +561,6 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
 {
 	idr_for_each(&file_private->object_idr,
 		     &drm_gem_object_release_handle, file_private);
-
-	idr_remove_all(&file_private->object_idr);
 	idr_destroy(&file_private->object_idr);
 }
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 1a55635..90398df 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -1786,8 +1786,6 @@ err_iommu:
 			drm_iommu_detach_device(drm_dev, ippdrv->dev);
 
 err_idr:
-	idr_remove_all(&ctx->ipp_idr);
-	idr_remove_all(&ctx->prop_idr);
 	idr_destroy(&ctx->ipp_idr);
 	idr_destroy(&ctx->prop_idr);
 	return ret;
@@ -1965,8 +1963,6 @@ static int ipp_remove(struct platform_device *pdev)
 	exynos_drm_subdrv_unregister(&ctx->subdrv);
 
 	/* remove,destroy ipp idr */
-	idr_remove_all(&ctx->ipp_idr);
-	idr_remove_all(&ctx->prop_idr);
 	idr_destroy(&ctx->ipp_idr);
 	idr_destroy(&ctx->prop_idr);
 
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 841065b..5a5325e 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -58,7 +58,6 @@ static int sis_driver_unload(struct drm_device *dev)
 {
 	drm_sis_private_t *dev_priv = dev->dev_private;
 
-	idr_remove_all(&dev_priv->object_idr);
 	idr_destroy(&dev_priv->object_idr);
 
 	kfree(dev_priv);
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c
index c0f1cc7..d0ab3fb 100644
--- a/drivers/gpu/drm/via/via_map.c
+++ b/drivers/gpu/drm/via/via_map.c
@@ -120,7 +120,6 @@ int via_driver_unload(struct drm_device *dev)
 {
 	drm_via_private_t *dev_priv = dev->dev_private;
 
-	idr_remove_all(&dev_priv->object_idr);
 	idr_destroy(&dev_priv->object_idr);
 
 	kfree(dev_priv);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 07/77] dm: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (5 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 06/77] drm: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 08/77] remoteproc: " Tejun Heo
                   ` (70 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Alasdair Kergon, dm-devel

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop its usage.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alasdair Kergon <agk@redhat.com>
Cc: dm-devel@redhat.com
---
 drivers/md/dm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 808f712..c644eb6 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -318,7 +318,6 @@ static void __exit dm_exit(void)
 	/*
 	 * Should be empty by this point.
 	 */
-	idr_remove_all(&_minor_idr);
 	idr_destroy(&_minor_idr);
 }
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 08/77] remoteproc: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (6 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 07/77] dm: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 09/77] rpmsg: " Tejun Heo
                   ` (69 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Ohad Ben-Cohen

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop its usage.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/remoteproc/remoteproc_core.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index dd3bfaf..634d367 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1180,7 +1180,6 @@ static void rproc_type_release(struct device *dev)
 
 	rproc_delete_debug_dir(rproc);
 
-	idr_remove_all(&rproc->notifyids);
 	idr_destroy(&rproc->notifyids);
 
 	if (rproc->index >= 0)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 09/77] rpmsg: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (7 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 08/77] remoteproc: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 10/77] dlm: use idr_for_each_entry() in recover_idr_clear() error path Tejun Heo
                   ` (68 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Ohad Ben-Cohen

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop its usage.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/rpmsg/virtio_rpmsg_bus.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index d854460..aaa6840 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -1036,7 +1036,6 @@ static void rpmsg_remove(struct virtio_device *vdev)
 	if (vrp->ns_ept)
 		__rpmsg_destroy_ept(vrp, vrp->ns_ept);
 
-	idr_remove_all(&vrp->endpoints);
 	idr_destroy(&vrp->endpoints);
 
 	vdev->config->del_vqs(vrp->vdev);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 10/77] dlm: use idr_for_each_entry() in recover_idr_clear() error path
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (8 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 09/77] rpmsg: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 11/77] dlm: don't use idr_remove_all() Tejun Heo
                   ` (67 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Christine Caulfield, David Teigland,
	cluster-devel

Convert recover_idr_clear() to use idr_for_each_entry() instead of
idr_for_each().  It's somewhat less efficient this way but it
shouldn't matter in an error path.  This is to help with deprecation
of idr_remove_all().

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Christine Caulfield <ccaulfie@redhat.com>
Cc: David Teigland <teigland@redhat.com>
Cc: cluster-devel@redhat.com
---
 fs/dlm/recover.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c
index aedea28..b2856e7 100644
--- a/fs/dlm/recover.c
+++ b/fs/dlm/recover.c
@@ -351,23 +351,20 @@ static struct dlm_rsb *recover_idr_find(struct dlm_ls *ls, uint64_t id)
 	return r;
 }
 
-static int recover_idr_clear_rsb(int id, void *p, void *data)
+static void recover_idr_clear(struct dlm_ls *ls)
 {
-	struct dlm_ls *ls = data;
-	struct dlm_rsb *r = p;
+	struct dlm_rsb *r;
+	int id;
 
-	r->res_id = 0;
-	r->res_recover_locks_count = 0;
-	ls->ls_recover_list_count--;
+	spin_lock(&ls->ls_recover_idr_lock);
 
-	dlm_put_rsb(r);
-	return 0;
-}
+	idr_for_each_entry(&ls->ls_recover_idr, r, id) {
+		r->res_id = 0;
+		r->res_recover_locks_count = 0;
+		ls->ls_recover_list_count--;
 
-static void recover_idr_clear(struct dlm_ls *ls)
-{
-	spin_lock(&ls->ls_recover_idr_lock);
-	idr_for_each(&ls->ls_recover_idr, recover_idr_clear_rsb, ls);
+		dlm_put_rsb(r);
+	}
 	idr_remove_all(&ls->ls_recover_idr);
 
 	if (ls->ls_recover_list_count != 0) {
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 11/77] dlm: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (9 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 10/77] dlm: use idr_for_each_entry() in recover_idr_clear() error path Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 12/77] nfs: idr_destroy() no longer needs idr_remove_all() Tejun Heo
                   ` (66 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Christine Caulfield, David Teigland,
	cluster-devel

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.

The conversion isn't completely trivial for recover_idr_clear() as
it's the only place in kernel which makes legitimate use of
idr_remove_all() w/o idr_destroy().  Replace it with idr_remove() call
inside idr_for_each_entry() loop.  It goes on top so that it matches
the operation order in recover_idr_del().

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Christine Caulfield <ccaulfie@redhat.com>
Cc: David Teigland <teigland@redhat.com>
Cc: cluster-devel@redhat.com
---
 fs/dlm/lockspace.c | 1 -
 fs/dlm/recover.c   | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 2e99fb0..3ca79d3 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -796,7 +796,6 @@ static int release_lockspace(struct dlm_ls *ls, int force)
 	 */
 
 	idr_for_each(&ls->ls_lkbidr, lkb_idr_free, ls);
-	idr_remove_all(&ls->ls_lkbidr);
 	idr_destroy(&ls->ls_lkbidr);
 
 	/*
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c
index b2856e7..236d108 100644
--- a/fs/dlm/recover.c
+++ b/fs/dlm/recover.c
@@ -359,13 +359,13 @@ static void recover_idr_clear(struct dlm_ls *ls)
 	spin_lock(&ls->ls_recover_idr_lock);
 
 	idr_for_each_entry(&ls->ls_recover_idr, r, id) {
+		idr_remove(&ls->ls_recover_idr, id);
 		r->res_id = 0;
 		r->res_recover_locks_count = 0;
 		ls->ls_recover_list_count--;
 
 		dlm_put_rsb(r);
 	}
-	idr_remove_all(&ls->ls_recover_idr);
 
 	if (ls->ls_recover_list_count != 0) {
 		log_error(ls, "warning: recover_list_count %d",
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 12/77] nfs: idr_destroy() no longer needs idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (10 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 11/77] dlm: don't use idr_remove_all() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 13/77] inotify: don't use idr_remove_all() Tejun Heo
                   ` (65 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, J. Bruce Fields, linux-nfs

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop reference to idr_remove_all().  Note that the code
wasn't completely correct before because idr_remove() on all entries
doesn't necessarily release all idr_layers which could lead to memory
leak.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: linux-nfs@vger.kernel.org
---
 fs/nfs/client.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 9f3c664..84d8eae 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -197,7 +197,6 @@ error_0:
 EXPORT_SYMBOL_GPL(nfs_alloc_client);
 
 #if IS_ENABLED(CONFIG_NFS_V4)
-/* idr_remove_all is not needed as all id's are removed by nfs_put_client */
 void nfs_cleanup_cb_ident_idr(struct net *net)
 {
 	struct nfs_net *nn = net_generic(net, nfs_net_id);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 13/77] inotify: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (11 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 12/77] nfs: idr_destroy() no longer needs idr_remove_all() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 14/77] cgroup: " Tejun Heo
                   ` (64 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, John McCutchan, Robert Love, Eric Paris

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop its usage.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: John McCutchan <john@johnmccutchan.com>
Cc: Robert Love <rlove@rlove.org>
Cc: Eric Paris <eparis@parisplace.org>
---
 fs/notify/inotify/inotify_fsnotify.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 871569c..4216308 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -197,7 +197,6 @@ static void inotify_free_group_priv(struct fsnotify_group *group)
 {
 	/* ideally the idr is empty and we won't hit the BUG in the callback */
 	idr_for_each(&group->inotify_data.idr, idr_callback, group);
-	idr_remove_all(&group->inotify_data.idr);
 	idr_destroy(&group->inotify_data.idr);
 	atomic_dec(&group->inotify_data.user->inotify_devs);
 	free_uid(group->inotify_data.user);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 14/77] cgroup: don't use idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (12 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 13/77] inotify: don't use idr_remove_all() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-07  1:29   ` Li Zefan
  2013-02-06 19:39 ` [PATCH 15/77] idr: deprecate idr_remove_all() Tejun Heo
                   ` (63 subsequent siblings)
  77 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Li Zefan, containers, cgroups

idr_destroy() can destroy idr by itself and idr_remove_all() is being
deprecated.  Drop its usage.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: containers@lists.linux-foundation.org
Cc: cgroups@vger.kernel.org
---
 kernel/cgroup.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 776ff75..525c508 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4582,10 +4582,8 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
 	offline_css(ss, dummytop);
 	ss->active = 0;
 
-	if (ss->use_id) {
-		idr_remove_all(&ss->idr);
+	if (ss->use_id)
 		idr_destroy(&ss->idr);
-	}
 
 	/* deassign the subsys_id */
 	subsys[ss->subsys_id] = NULL;
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 15/77] idr: deprecate idr_remove_all()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (13 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 14/77] cgroup: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 16/77] idr: cosmetic updates to struct / initializer definitions Tejun Heo
                   ` (62 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo

There was only one legitimate use of idr_remove_all() and a lot more
of incorrect uses (or lack of it).  Now that idr_destroy() implies
idr_remove_all() and all the in-kernel users updated not to use it,
there's no reason to keep it around.  Mark it deprecated so that we
can later unexport it.

idr_remove_all() is made an inline function calling __idr_remove_all()
to avoid triggering deprecated warning on EXPORT_SYMBOL().

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 include/linux/idr.h | 14 +++++++++++++-
 lib/idr.c           | 10 +++-------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index de7e190..1b932e7 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -110,10 +110,22 @@ int idr_for_each(struct idr *idp,
 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_remove_all(struct idr *idp);
 void idr_destroy(struct idr *idp);
 void idr_init(struct idr *idp);
 
+void __idr_remove_all(struct idr *idp);	/* don't use */
+
+/**
+ * idr_remove_all - remove all ids from the given idr tree
+ * @idp: idr handle
+ *
+ * If you're trying to destroy @idp, calling idr_destroy() is enough.
+ * This is going away.  Don't use.
+ */
+static inline void __deprecated idr_remove_all(struct idr *idp)
+{
+	__idr_remove_all(idp);
+}
 
 /*
  * IDA - IDR based id allocator, use when translation from id to
diff --git a/lib/idr.c b/lib/idr.c
index b8602e0..814c53c 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -433,11 +433,7 @@ void idr_remove(struct idr *idp, int id)
 }
 EXPORT_SYMBOL(idr_remove);
 
-/**
- * idr_remove_all - remove all ids from the given idr tree
- * @idp: idr handle
- */
-void idr_remove_all(struct idr *idp)
+void __idr_remove_all(struct idr *idp)
 {
 	int n, id, max;
 	int bt_mask;
@@ -470,7 +466,7 @@ void idr_remove_all(struct idr *idp)
 	}
 	idp->layers = 0;
 }
-EXPORT_SYMBOL(idr_remove_all);
+EXPORT_SYMBOL(__idr_remove_all);
 
 /**
  * idr_destroy - release all cached layers within an idr tree
@@ -487,7 +483,7 @@ EXPORT_SYMBOL(idr_remove_all);
  */
 void idr_destroy(struct idr *idp)
 {
-	idr_remove_all(idp);
+	__idr_remove_all(idp);
 
 	while (idp->id_free_cnt) {
 		struct idr_layer *p = get_from_free_list(idp);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 16/77] idr: cosmetic updates to struct / initializer definitions
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (14 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 15/77] idr: deprecate idr_remove_all() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 17/77] idr: relocate idr_for_each_entry() and reorganize id[r|a]_get_new() Tejun Heo
                   ` (61 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo

* Tab align fields like a normal person.

* Drop the unnecessary 0 inits from IDR_INIT().

This patch is purely cosmetic.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 include/linux/idr.h | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index 1b932e7..c78c26d 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -49,28 +49,24 @@
 #define MAX_IDR_FREE (MAX_IDR_LEVEL * 2)
 
 struct idr_layer {
-	unsigned long		 bitmap; /* A zero bit means "space here" */
+	unsigned long		bitmap;	/* A zero bit means "space here" */
 	struct idr_layer __rcu	*ary[1<<IDR_BITS];
-	int			 count;	 /* When zero, we can release it */
-	int			 layer;	 /* distance from leaf */
-	struct rcu_head		 rcu_head;
+	int			count;	/* When zero, we can release it */
+	int			layer;	/* distance from leaf */
+	struct rcu_head		rcu_head;
 };
 
 struct idr {
-	struct idr_layer __rcu *top;
-	struct idr_layer *id_free;
-	int		  layers; /* only valid without concurrent changes */
-	int		  id_free_cnt;
-	spinlock_t	  lock;
+	struct idr_layer __rcu	*top;
+	struct idr_layer	*id_free;
+	int			layers;	/* only valid w/o concurrent changes */
+	int			id_free_cnt;
+	spinlock_t		lock;
 };
 
-#define IDR_INIT(name)						\
-{								\
-	.top		= NULL,					\
-	.id_free	= NULL,					\
-	.layers 	= 0,					\
-	.id_free_cnt	= 0,					\
-	.lock		= __SPIN_LOCK_UNLOCKED(name.lock),	\
+#define IDR_INIT(name)							\
+{									\
+	.lock			= __SPIN_LOCK_UNLOCKED(name.lock),	\
 }
 #define DEFINE_IDR(name)	struct idr name = IDR_INIT(name)
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 17/77] idr: relocate idr_for_each_entry() and reorganize id[r|a]_get_new()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (15 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 16/77] idr: cosmetic updates to struct / initializer definitions Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 18/77] idr: remove _idr_rc_to_errno() hack Tejun Heo
                   ` (60 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo

* Move idr_for_each_entry() definition next to other idr related
  definitions.

* Make id[r|a]_get_new() inline wrappers of id[r|a]_get_new_above().

This changes the implementation of idr_get_new() but the new
implementation is trivial.  This patch doesn't introduce any
functional change.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 include/linux/idr.h | 47 +++++++++++++++++++++++++++++++++++------------
 lib/idr.c           | 49 -------------------------------------------------
 2 files changed, 35 insertions(+), 61 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index c78c26d..7c0700c 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -99,7 +99,6 @@ 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(struct idr *idp, void *ptr, int *id);
 int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
 int idr_for_each(struct idr *idp,
 		 int (*fn)(int id, void *p, void *data), void *data);
@@ -109,6 +108,30 @@ void idr_remove(struct idr *idp, int id);
 void idr_destroy(struct idr *idp);
 void idr_init(struct idr *idp);
 
+/**
+ * idr_get_new - allocate new idr entry
+ * @idp: idr handle
+ * @ptr: pointer you want associated with the id
+ * @id: pointer to the allocated handle
+ *
+ * Simple wrapper around idr_get_new_above() w/ @starting_id of zero.
+ */
+static inline int idr_get_new(struct idr *idp, void *ptr, int *id)
+{
+	return idr_get_new_above(idp, ptr, 0, id);
+}
+
+/**
+ * idr_for_each_entry - iterate over an idr's elements of a given type
+ * @idp:     idr handle
+ * @entry:   the type * to use as cursor
+ * @id:      id entry's key
+ */
+#define idr_for_each_entry(idp, entry, id)				\
+	for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \
+	     entry != NULL;                                             \
+	     ++id, entry = (typeof(entry))idr_get_next((idp), &(id)))
+
 void __idr_remove_all(struct idr *idp);	/* don't use */
 
 /**
@@ -149,7 +172,6 @@ struct ida {
 
 int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
 int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
-int ida_get_new(struct ida *ida, int *p_id);
 void ida_remove(struct ida *ida, int id);
 void ida_destroy(struct ida *ida);
 void ida_init(struct ida *ida);
@@ -158,17 +180,18 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end,
 		   gfp_t gfp_mask);
 void ida_simple_remove(struct ida *ida, unsigned int id);
 
-void __init idr_init_cache(void);
-
 /**
- * idr_for_each_entry - iterate over an idr's elements of a given type
- * @idp:     idr handle
- * @entry:   the type * to use as cursor
- * @id:      id entry's key
+ * ida_get_new - allocate new ID
+ * @ida:	idr handle
+ * @p_id:	pointer to the allocated handle
+ *
+ * Simple wrapper around ida_get_new_above() w/ @starting_id of zero.
  */
-#define idr_for_each_entry(idp, entry, id)				\
-	for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \
-	     entry != NULL;                                             \
-	     ++id, entry = (typeof(entry))idr_get_next((idp), &(id)))
+static inline int ida_get_new(struct ida *ida, int *p_id)
+{
+	return ida_get_new_above(ida, 0, p_id);
+}
+
+void __init idr_init_cache(void);
 
 #endif /* __IDR_H__ */
diff --git a/lib/idr.c b/lib/idr.c
index 814c53c..282841b 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -317,36 +317,6 @@ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
 }
 EXPORT_SYMBOL(idr_get_new_above);
 
-/**
- * idr_get_new - allocate new idr entry
- * @idp: idr handle
- * @ptr: pointer you want associated with the id
- * @id: pointer to the allocated handle
- *
- * If allocation from IDR's private freelist fails, idr_get_new_above() will
- * return %-EAGAIN.  The caller should retry the idr_pre_get() call to refill
- * IDR's preallocation and then retry the idr_get_new_above() call.
- *
- * If the idr is full idr_get_new_above() will return %-ENOSPC.
- *
- * @id returns a value in the range %0 ... %0x7fffffff
- */
-int idr_get_new(struct idr *idp, void *ptr, int *id)
-{
-	int rv;
-
-	rv = idr_get_new_above_int(idp, ptr, 0);
-	/*
-	 * This is a cheap hack until the IDR code can be fixed to
-	 * return proper error values.
-	 */
-	if (rv < 0)
-		return _idr_rc_to_errno(rv);
-	*id = rv;
-	return 0;
-}
-EXPORT_SYMBOL(idr_get_new);
-
 static void idr_remove_warning(int id)
 {
 	printk(KERN_WARNING
@@ -857,25 +827,6 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
 EXPORT_SYMBOL(ida_get_new_above);
 
 /**
- * ida_get_new - allocate new ID
- * @ida:	idr handle
- * @p_id:	pointer to the allocated handle
- *
- * Allocate new ID.  It should be called with any required locks.
- *
- * If memory is required, it will return %-EAGAIN, you should unlock
- * and go back to the idr_pre_get() call.  If the idr is full, it will
- * return %-ENOSPC.
- *
- * @p_id returns a value in the range %0 ... %0x7fffffff.
- */
-int ida_get_new(struct ida *ida, int *p_id)
-{
-	return ida_get_new_above(ida, 0, p_id);
-}
-EXPORT_SYMBOL(ida_get_new);
-
-/**
  * ida_remove - remove the given ID
  * @ida:	ida handle
  * @id:		ID to free
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 18/77] idr: remove _idr_rc_to_errno() hack
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (16 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 17/77] idr: relocate idr_for_each_entry() and reorganize id[r|a]_get_new() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 19/77] idr: refactor idr_get_new_above() Tejun Heo
                   ` (59 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo

idr uses -1, IDR_NEED_TO_GROW and IDR_NOMORE_SPACE to communicate
exception conditions internally.  The return value is later translated
to errno values using _idr_rc_to_errno().

This is confusing.  Drop the custom ones and consistently use -EAGAIN
for "tree needs to grow", -ENOMEM for "need more memory" and -ENOSPC
for "ran out of ID space".

Due to the weird memory preloading mechanism, [ra]_get_new*() return
-EAGAIN on memory shortage, so we need to substitute -ENOMEM w/
-EAGAIN on those interface functions.  They'll eventually be cleaned
up and the translations will go away.

This patch doesn't introduce any functional changes.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 include/linux/idr.h |  6 ------
 lib/idr.c           | 35 +++++++++++++++++++++++------------
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index 7c0700c..92e84f7 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -70,12 +70,6 @@ struct idr {
 }
 #define DEFINE_IDR(name)	struct idr name = IDR_INIT(name)
 
-/* Actions to be taken after a call to _idr_sub_alloc */
-#define IDR_NEED_TO_GROW -2
-#define IDR_NOMORE_SPACE -3
-
-#define _idr_rc_to_errno(rc) ((rc) == -1 ? -EAGAIN : -ENOSPC)
-
 /**
  * DOC: idr sync
  * idr synchronization (stolen from radix-tree.h)
diff --git a/lib/idr.c b/lib/idr.c
index 282841b..bde6eec 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -133,6 +133,21 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
 }
 EXPORT_SYMBOL(idr_pre_get);
 
+/**
+ * sub_alloc - try to allocate an id without growing the tree depth
+ * @idp: idr handle
+ * @starting_id: id to start search at
+ * @id: pointer to the allocated handle
+ * @pa: idr_layer[MAX_IDR_LEVEL] used as backtrack buffer
+ *
+ * Allocate an id in range [@starting_id, INT_MAX] from @idp without
+ * growing its depth.  Returns
+ *
+ *  the allocated id >= 0 if successful,
+ *  -EAGAIN if the tree needs to grow for allocation to succeed,
+ *  -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)
 {
 	int n, m, sh;
@@ -161,7 +176,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
 			/* if already at the top layer, we need to grow */
 			if (id >= 1 << (idp->layers * IDR_BITS)) {
 				*starting_id = id;
-				return IDR_NEED_TO_GROW;
+				return -EAGAIN;
 			}
 			p = pa[l];
 			BUG_ON(!p);
@@ -180,7 +195,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
 			id = ((id >> sh) ^ n ^ m) << sh;
 		}
 		if ((id >= MAX_IDR_BIT) || (id < 0))
-			return IDR_NOMORE_SPACE;
+			return -ENOSPC;
 		if (l == 0)
 			break;
 		/*
@@ -189,7 +204,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
 		if (!p->ary[m]) {
 			new = get_from_free_list(idp);
 			if (!new)
-				return -1;
+				return -ENOMEM;
 			new->layer = l-1;
 			rcu_assign_pointer(p->ary[m], new);
 			p->count++;
@@ -215,7 +230,7 @@ build_up:
 	layers = idp->layers;
 	if (unlikely(!p)) {
 		if (!(p = get_from_free_list(idp)))
-			return -1;
+			return -ENOMEM;
 		p->layer = 0;
 		layers = 1;
 	}
@@ -246,7 +261,7 @@ build_up:
 				__move_to_free_list(idp, new);
 			}
 			spin_unlock_irqrestore(&idp->lock, flags);
-			return -1;
+			return -ENOMEM;
 		}
 		new->ary[0] = p;
 		new->count = 1;
@@ -258,7 +273,7 @@ build_up:
 	rcu_assign_pointer(idp->top, p);
 	idp->layers = layers;
 	v = sub_alloc(idp, &id, pa);
-	if (v == IDR_NEED_TO_GROW)
+	if (v == -EAGAIN)
 		goto build_up;
 	return(v);
 }
@@ -306,12 +321,8 @@ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
 	int rv;
 
 	rv = idr_get_new_above_int(idp, ptr, starting_id);
-	/*
-	 * This is a cheap hack until the IDR code can be fixed to
-	 * return proper error values.
-	 */
 	if (rv < 0)
-		return _idr_rc_to_errno(rv);
+		return rv == -ENOMEM ? -EAGAIN : rv;
 	*id = rv;
 	return 0;
 }
@@ -766,7 +777,7 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
 	/* get vacant slot */
 	t = idr_get_empty_slot(&ida->idr, idr_id, pa);
 	if (t < 0)
-		return _idr_rc_to_errno(t);
+		return t == -ENOMEM ? -EAGAIN : t;
 
 	if (t * IDA_BITMAP_BITS >= MAX_IDR_BIT)
 		return -ENOSPC;
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 19/77] idr: refactor idr_get_new_above()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (17 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 18/77] idr: remove _idr_rc_to_errno() hack Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 20/77] idr: implement idr_preload[_end]() and idr_alloc() Tejun Heo
                   ` (58 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo

Move slot filling to idr_fill_slot() from idr_get_new_above_int() and
make idr_get_new_above() directly call it.  idr_get_new_above_int() is
no longer needed and removed.

This will be used to implement a new ID allocation interface.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 lib/idr.c | 30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/lib/idr.c b/lib/idr.c
index bde6eec..b13aae5 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -278,24 +278,15 @@ build_up:
 	return(v);
 }
 
-static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
+/*
+ * @id and @pa are from a successful allocation from idr_get_empty_slot().
+ * Install the user pointer @ptr and mark the slot full.
+ */
+static void idr_fill_slot(void *ptr, int id, struct idr_layer **pa)
 {
-	struct idr_layer *pa[MAX_IDR_LEVEL];
-	int id;
-
-	id = idr_get_empty_slot(idp, starting_id, pa);
-	if (id >= 0) {
-		/*
-		 * Successfully found an empty slot.  Install the user
-		 * pointer and mark the slot full.
-		 */
-		rcu_assign_pointer(pa[0]->ary[id & IDR_MASK],
-				(struct idr_layer *)ptr);
-		pa[0]->count++;
-		idr_mark_full(pa, id);
-	}
-
-	return id;
+	rcu_assign_pointer(pa[0]->ary[id & IDR_MASK], (struct idr_layer *)ptr);
+	pa[0]->count++;
+	idr_mark_full(pa, id);
 }
 
 /**
@@ -318,11 +309,14 @@ static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
  */
 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_new_above_int(idp, ptr, starting_id);
+	rv = idr_get_empty_slot(idp, starting_id, pa);
 	if (rv < 0)
 		return rv == -ENOMEM ? -EAGAIN : rv;
+
+	idr_fill_slot(ptr, rv, pa);
 	*id = rv;
 	return 0;
 }
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 20/77] idr: implement idr_preload[_end]() and idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (18 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 19/77] idr: refactor idr_get_new_above() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-07 19:53   ` [PATCH v3 " Tejun Heo
  2013-02-06 19:39 ` [PATCH 21/77] block: fix synchronization and limit check in blk_alloc_devt() Tejun Heo
                   ` (57 subsequent siblings)
  77 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Rusty Russell

The current idr interface is very cumbersome.

* For all allocations, two function calls - idr_pre_get() and
  idr_get_new*() - should be made.

* idr_pre_get() doesn't guarantee that the following idr_get_new*()
  will not fail from memory shortage.  If idr_get_new*() returns
  -EAGAIN, the caller is expected to retry pre_get and allocation.

* idr_get_new*() can't enforce upper limit.  Upper limit can only be
  enforced by allocating and then freeing if above limit.

* idr_layer buffer is unnecessarily per-idr.  Each idr ends up keeping
  around MAX_IDR_FREE idr_layers.  The memory consumed per idr is
  under two pages but it makes it difficult to make idr_layer larger.

This patch implements the following new set of allocation functions.

* idr_preload[_end]() - Similar to radix preload but doesn't fail.
  The first idr_alloc() inside preload section can be treated as if it
  were called with @gfp_mask used for idr_preload().

* idr_alloc() - Allocate an ID w/ lower and upper limits.  Takes
  @gfp_flags and can be used w/o preloading.  When used inside
  preloaded section, the allocation mask of preloading can be assumed.

If idr_alloc() can be called from a context which allows sufficiently
relaxed @gfp_mask, it can be used by itself.  If, for example,
idr_alloc() is called inside spinlock protected region, preloading can
be used like the following.

	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;

which is much simpler and less error-prone than idr_pre_get and
idr_get_new*() loop.

The new interface uses per-pcu idr_layer buffer and thus the number of
idr's in the system doesn't affect the amount of memory used for
preloading.

idr_layer_alloc() is introduced to handle idr_layer allocations for
both old and new ID allocation paths.  This is a bit hairy now but the
new interface is expected to replace the old and the internal
implementation eventually will become simpler.

v2: Improve idr_preload() comment a bit so that it's clear that
    preemption is disabled while preloaded.  Make idr_layer_alloc()
    try kmem_cache first and then fall back to per-cpu buffer;
    otherwise, non-preloading idr_alloc()s empty per-cpu buffers
    makeing preloaders fill them, which, while not incorrect, still is
    a bit unfair.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
---
 include/linux/idr.h |  14 +++++
 lib/idr.c           | 171 +++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 177 insertions(+), 8 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index 92e84f7..8d3ffe1 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -94,15 +94,29 @@ 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/lib/idr.c b/lib/idr.c
index b13aae5..5115705 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -35,8 +35,12 @@
 #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)
@@ -54,6 +58,50 @@ 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;
@@ -139,6 +187,8 @@ 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
@@ -148,7 +198,8 @@ 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)
+static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa,
+		     gfp_t gfp_mask, struct idr *layer_idr)
 {
 	int n, m, sh;
 	struct idr_layer *p, *new;
@@ -202,7 +253,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 = get_from_free_list(idp);
+			new = idr_layer_alloc(gfp_mask, layer_idr);
 			if (!new)
 				return -ENOMEM;
 			new->layer = l-1;
@@ -218,7 +269,8 @@ 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)
+			      struct idr_layer **pa, gfp_t gfp_mask,
+			      struct idr *layer_idr)
 {
 	struct idr_layer *p, *new;
 	int layers, v, id;
@@ -229,7 +281,7 @@ build_up:
 	p = idp->top;
 	layers = idp->layers;
 	if (unlikely(!p)) {
-		if (!(p = get_from_free_list(idp)))
+		if (!(p = idr_layer_alloc(gfp_mask, layer_idr)))
 			return -ENOMEM;
 		p->layer = 0;
 		layers = 1;
@@ -248,7 +300,7 @@ build_up:
 			p->layer++;
 			continue;
 		}
-		if (!(new = get_from_free_list(idp))) {
+		if (!(new = idr_layer_alloc(gfp_mask, layer_idr))) {
 			/*
 			 * The allocation failed.  If we built part of
 			 * the structure tear it down.
@@ -272,7 +324,7 @@ build_up:
 	}
 	rcu_assign_pointer(idp->top, p);
 	idp->layers = layers;
-	v = sub_alloc(idp, &id, pa);
+	v = sub_alloc(idp, &id, pa, gfp_mask, layer_idr);
 	if (v == -EAGAIN)
 		goto build_up;
 	return(v);
@@ -312,7 +364,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);
+	rv = idr_get_empty_slot(idp, starting_id, pa, 0, idp);
 	if (rv < 0)
 		return rv == -ENOMEM ? -EAGAIN : rv;
 
@@ -322,6 +374,109 @@ 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
@@ -769,7 +924,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);
+	t = idr_get_empty_slot(&ida->idr, idr_id, pa, 0, &ida->idr);
 	if (t < 0)
 		return t == -ENOMEM ? -EAGAIN : t;
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 21/77] block: fix synchronization and limit check in blk_alloc_devt()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (19 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 20/77] idr: implement idr_preload[_end]() and idr_alloc() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 22:24   ` Andrew Morton
  2013-02-06 19:39 ` [PATCH 22/77] block: convert to idr_alloc() Tejun Heo
                   ` (56 subsequent siblings)
  77 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, stable

idr allocation in blk_alloc_devt() wasn't synchronized against lookup
and removal, and its limit check was off by one - 1 << MINORBITS is
the number of minors allowed, not the maximum allowed minor.

Add locking and rename MAX_EXT_DEVT to NR_EXT_DEVT and fix limit
checking.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Jens Axboe <axboe@kernel.dk>
Cc: stable@vger.kernel.org
---
 block/genhd.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index 2eb64a3..b1f34d0 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -26,7 +26,7 @@ static DEFINE_MUTEX(block_class_lock);
 struct kobject *block_depr;
 
 /* for extended dynamic devt allocation, currently only one major is used */
-#define MAX_EXT_DEVT		(1 << MINORBITS)
+#define NR_EXT_DEVT		(1 << MINORBITS)
 
 /* For extended devt allocation.  ext_devt_mutex prevents look up
  * results from going away underneath its user.
@@ -423,17 +423,18 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
 	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;
 
-	if (idx > MAX_EXT_DEVT) {
-		idr_remove(&ext_devt_idr, idx);
-		return -EBUSY;
-	}
-
 	*devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
 	return 0;
 }
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 22/77] block: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (20 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 21/77] block: fix synchronization and limit check in blk_alloc_devt() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 23/77] block/loop: " Tejun Heo
                   ` (55 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo

Convert to the much saner new idr interface.  Both bsg and genhd
protect idr w/ mutex making preloading unnecessary.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Jens Axboe <axboe@kernel.dk>
---
 block/bsg.c   | 26 +++++++++-----------------
 block/genhd.c | 21 ++++++---------------
 2 files changed, 15 insertions(+), 32 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index ff64ae3..3ca92eb 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -997,7 +997,7 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
 {
 	struct bsg_class_device *bcd;
 	dev_t dev;
-	int ret, minor;
+	int ret;
 	struct device *class_dev = NULL;
 	const char *devname;
 
@@ -1017,23 +1017,16 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
 
 	mutex_lock(&bsg_mutex);
 
-	ret = idr_pre_get(&bsg_minor_idr, GFP_KERNEL);
-	if (!ret) {
-		ret = -ENOMEM;
-		goto unlock;
-	}
-
-	ret = idr_get_new(&bsg_minor_idr, bcd, &minor);
-	if (ret < 0)
+	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;
+		}
 		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->minor = ret;
 	bcd->queue = q;
 	bcd->parent = get_device(parent);
 	bcd->release = release;
@@ -1059,8 +1052,7 @@ unregister_class_dev:
 	device_unregister(class_dev);
 put_dev:
 	put_device(parent);
-remove_idr:
-	idr_remove(&bsg_minor_idr, minor);
+	idr_remove(&bsg_minor_idr, bcd->minor);
 unlock:
 	mutex_unlock(&bsg_mutex);
 	return ret;
diff --git a/block/genhd.c b/block/genhd.c
index b1f34d0..bd509e3 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, rc;
+	int idx;
 
 	/* in consecutive minor range? */
 	if (part->partno < disk->minors) {
@@ -420,20 +420,11 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
 	}
 
 	/* allocate ext devt */
-	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;
+	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;
 
 	*devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
 	return 0;
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 23/77] block/loop: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (21 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 22/77] block: convert to idr_alloc() Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-07 18:25   ` [PATCH 22.5/77] block/loop: fix error return value in loop_add() Tejun Heo
  2013-02-07 18:26   ` [PATCH v2 23/77] block/loop: convert to idr_alloc() Tejun Heo
  2013-02-06 19:39 ` [PATCH 24/77] atm/nicstar: " Tejun Heo
                   ` (54 subsequent siblings)
  77 siblings, 2 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo

Convert to the much saner new idr interface.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Jens Axboe <axboe@kernel.dk>
---
 drivers/block/loop.c | 23 +++++------------------
 1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 3b9c32b..dafbfdb 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1624,30 +1624,17 @@ static int loop_add(struct loop_device **l, int i)
 	if (!lo)
 		goto out;
 
-	if (!idr_pre_get(&loop_index_idr, GFP_KERNEL))
-		goto out_free_dev;
-
+	/* allocate id, if @id >= 0, we're requesting that specific id */
 	if (i >= 0) {
-		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 = idr_alloc(&loop_index_idr, lo, i, i + 1, GFP_KERNEL);
+		if (err == -ENOSPC)
 			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 = -EINVAL;
+		err = idr_alloc(&loop_index_idr, lo, 0, 0, GFP_KERNEL);
 	}
 	if (err < 0)
 		goto out_free_dev;
+	i = err;
 
 	lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
 	if (!lo->lo_queue)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 24/77] atm/nicstar: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (22 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 23/77] block/loop: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 25/77] drbd: " Tejun Heo
                   ` (53 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, netdev

Convert to the much saner new idr interface.  The existing code looks
buggy to me - ID 0 is treated as no-ID but allocation specifies 0 as
lower limit and there's no error handling after partial success.  This
conversion keeps the bugs unchanged.

Only compile tested.

v2: id1 and id2 are now directly used for -errno return and thus
    should be signed.  Make them int instead of u32.  This was spotted
    by kbuild test robot.

v3: Further simplify as suggested by Chas Williams.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Chas Williams <chas@cmf.nrl.navy.mil>
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Cc: netdev@vger.kernel.org
---
 drivers/atm/nicstar.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 628787e..6587dc2 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -949,11 +949,10 @@ 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;
-	u32 id1 = 0, id2 = 0;
+	int id1, id2;
 	u32 addr1, addr2;
 	u32 stat;
 	unsigned long flags;
-	int err;
 
 	/* *BARF* */
 	handle2 = NULL;
@@ -1026,23 +1025,12 @@ static void push_rxbufs(ns_dev * card, struct sk_buff *skb)
 				card->lbfqc += 2;
 		}
 
-		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);
+		id1 = idr_alloc(&card->idr, handle1, 0, 0, GFP_ATOMIC);
+		if (id1 < 0)
+			goto out;
 
-		if (err)
+		id2 = idr_alloc(&card->idr, handle2, 0, 0, GFP_ATOMIC);
+		if (id2 < 0)
 			goto out;
 
 		spin_lock_irqsave(&card->res_lock, flags);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 25/77] drbd: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (23 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 24/77] atm/nicstar: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 26/77] dca: " Tejun Heo
                   ` (52 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, drbd-dev, drbd-user

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: drbd-dev@lists.linbit.com
Cc: drbd-user@lists.linbit.com
---
 drivers/block/drbd/drbd_main.c | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 8c13eeb..e98da67 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2660,25 +2660,24 @@ enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor,
 	mdev->read_requests = RB_ROOT;
 	mdev->write_requests = RB_ROOT;
 
-	if (!idr_pre_get(&minors, GFP_KERNEL))
-		goto out_no_minor_idr;
-	if (idr_get_new_above(&minors, mdev, minor, &minor_got))
+	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");
+		}
 		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;
 	}
 
-	if (!idr_pre_get(&tconn->volumes, GFP_KERNEL))
-		goto out_idr_remove_minor;
-	if (idr_get_new_above(&tconn->volumes, mdev, vnr, &vnr_got))
+	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");
+		}
 		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 */
 
@@ -2689,8 +2688,6 @@ 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();
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 26/77] dca: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (24 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 25/77] drbd: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:39 ` [PATCH 27/77] dmaengine: " Tejun Heo
                   ` (51 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Paul Gortmaker, Maciej Sosnowski,
	Shannon Nelson

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Maciej Sosnowski <maciej.sosnowski@intel.com>
Cc: Shannon Nelson <shannon.nelson@intel.com>
---
 drivers/dca/dca-sysfs.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
index 591b659..126cf29 100644
--- a/drivers/dca/dca-sysfs.c
+++ b/drivers/dca/dca-sysfs.c
@@ -53,22 +53,19 @@ 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 err = 0;
+	int ret;
 
-idr_try_again:
-	if (!idr_pre_get(&dca_idr, GFP_KERNEL))
-		return -ENOMEM;
+	idr_preload(GFP_KERNEL);
 	spin_lock(&dca_idr_lock);
-	err = idr_get_new(&dca_idr, dca, &dca->id);
+
+	ret = idr_alloc(&dca_idr, dca, 0, 0, GFP_NOWAIT);
+	if (ret >= 0)
+		dca->id = ret;
+
 	spin_unlock(&dca_idr_lock);
-	switch (err) {
-	case 0:
-		break;
-	case -EAGAIN:
-		goto idr_try_again;
-	default:
-		return err;
-	}
+	idr_preload_end();
+	if (ret < 0)
+		return ret;
 
 	cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id);
 	if (IS_ERR(cd)) {
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 27/77] dmaengine: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (25 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 26/77] dca: " Tejun Heo
@ 2013-02-06 19:39 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 28/77] firewire: add minor number range check to fw_device_init() Tejun Heo
                   ` (50 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:39 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Dan Williams

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Dan Williams <djbw@fb.com>
---
 drivers/dma/dmaengine.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 242b8c0..b2728d6 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -686,18 +686,14 @@ 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_get_new(&dma_idr, NULL, &device->dev_id);
-	mutex_unlock(&dma_list_mutex);
-	if (rc == -EAGAIN)
-		goto idr_retry;
-	else if (rc != 0)
-		return rc;
 
-	return 0;
+	rc = idr_alloc(&dma_idr, NULL, 0, 0, GFP_KERNEL);
+	if (rc >= 0)
+		device->dev_id = rc;
+
+	mutex_unlock(&dma_list_mutex);
+	return rc < 0 ? rc : 0;
 }
 
 /**
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 28/77] firewire: add minor number range check to fw_device_init()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (26 preceding siblings ...)
  2013-02-06 19:39 ` [PATCH 27/77] dmaengine: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 29/77] firewire: convert to idr_alloc() Tejun Heo
                   ` (49 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, stable

fw_device_init() didn't check whether the allocated minor number isn't
too large.  Fail if it goes overflows MINORBITS.

Signed-off-by: Tejun Heo <tj@kernel.org>
Suggested-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Acked-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Cc: stable@vger.kernel.org
---
 drivers/firewire/core-device.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index 3873d53..af3e8aa 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -1020,6 +1020,10 @@ static void fw_device_init(struct work_struct *work)
 	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)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 29/77] firewire: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (27 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 28/77] firewire: add minor number range check to fw_device_init() Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 30/77] gpio: " Tejun Heo
                   ` (48 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, linux1394-devel

Convert to the much saner new idr interface.

Only compile tested.

v2: Stefan pointed out that add_client_resource() may be called from
    non-process context.  Preload iff @gfp_mask contains __GFP_WAIT.
    Also updated to include minor upper limit check.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Cc: linux1394-devel@lists.sourceforge.net
---
 drivers/firewire/core-cdev.c   | 19 ++++++++++---------
 drivers/firewire/core-device.c |  8 +-------
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 68c3138..27ac423 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -487,27 +487,28 @@ 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;
 
- retry:
-	if (idr_pre_get(&client->resource_idr, gfp_mask) == 0)
-		return -ENOMEM;
-
+	if (preload)
+		idr_preload(gfp_mask);
 	spin_lock_irqsave(&client->lock, flags);
+
 	if (client->in_shutdown)
 		ret = -ECANCELED;
 	else
-		ret = idr_get_new(&client->resource_idr, resource,
-				  &resource->handle);
+		ret = idr_alloc(&client->resource_idr, resource, 0, 0,
+				GFP_NOWAIT);
 	if (ret >= 0) {
+		resource->handle = ret;
 		client_get(client);
 		schedule_if_iso_resource(resource);
 	}
-	spin_unlock_irqrestore(&client->lock, flags);
 
-	if (ret == -EAGAIN)
-		goto retry;
+	spin_unlock_irqrestore(&client->lock, flags);
+	if (preload)
+		idr_preload_end();
 
 	return ret < 0 ? ret : 0;
 }
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index af3e8aa..b946330 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -1017,13 +1017,7 @@ static void fw_device_init(struct work_struct *work)
 
 	fw_device_get(device);
 	down_write(&fw_device_rwsem);
-	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;
-	}
+	ret = idr_alloc(&fw_device_idr, device, 0, 1 << MINORBITS, GFP_KERNEL);
 	up_write(&fw_device_rwsem);
 
 	if (ret < 0)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 30/77] gpio: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (28 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 29/77] firewire: convert to idr_alloc() Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 31/77] drm: " Tejun Heo
                   ` (47 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Grant Likely

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
 drivers/gpio/gpiolib.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e27877a..d5accb0 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -357,15 +357,10 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
 			goto err_out;
 		}
 
-		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)
+		ret = idr_alloc(&dirent_idr, value_sd, 1, 0, GFP_KERNEL);
+		if (ret < 0)
 			goto free_sd;
+		id = ret;
 
 		desc->flags &= GPIO_FLAGS_MASK;
 		desc->flags |= (unsigned long)id << ID_SHIFT;
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 31/77] drm: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (29 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 30/77] gpio: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 32/77] drm/exynos: " Tejun Heo
                   ` (46 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, David Airlie, dri-devel

Convert to the much saner new idr interface.

Only compile tested.

* drm_ctxbitmap_next() error handling in drm_addctx() seems broken.
  drm_ctxbitmap_next() return -errno on failure not -1.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: David Airlie <airlied@linux.ie>
Cc: dri-devel@lists.freedesktop.org
---
 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 ++-----------------
 4 files changed, 22 insertions(+), 68 deletions(-)

diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 75f62c5..725968d 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -74,24 +74,13 @@ 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_get_new_above(&dev->ctx_idr, NULL,
-				DRM_RESERVED_CONTEXTS, &new_id);
+	ret = idr_alloc(&dev->ctx_idr, NULL, DRM_RESERVED_CONTEXTS, 0,
+			GFP_KERNEL);
 	mutex_unlock(&dev->struct_mutex);
-	if (ret == -EAGAIN)
-		goto again;
-	else if (ret)
-		return ret;
-
-	return new_id;
+	return ret;
 }
 
 /**
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 775102d..838c9b6 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -252,32 +252,21 @@ 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_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
-
-	if (!ret) {
+	ret = idr_alloc(&dev->mode_config.crtc_idr, obj, 1, 0, GFP_KERNEL);
+	if (ret >= 0) {
 		/*
 		 * Set up the object linking under the protection of the idr
 		 * lock so that other users can't see inconsistent state.
 		 */
-		obj->id = new_id;
+		obj->id = ret;
 		obj->type = obj_type;
 	}
 	mutex_unlock(&dev->mode_config.idr_mutex);
 
-	if (ret == -EAGAIN)
-		goto again;
-
-	return ret;
+	return ret < 0 ? ret : 0;
 }
 
 /**
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index e775859..6577514 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -270,21 +270,19 @@ drm_gem_handle_create(struct drm_file *file_priv,
 	int ret;
 
 	/*
-	 * Get the user-visible handle using idr.
+	 * Get the user-visible handle using idr.  Preload and perform
+	 * allocation under our spinlock.
 	 */
-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 */
+	idr_preload(GFP_KERNEL);
 	spin_lock(&file_priv->table_lock);
-	ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep);
+
+	ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
+
 	spin_unlock(&file_priv->table_lock);
-	if (ret == -EAGAIN)
-		goto again;
-	else if (ret)
+	idr_preload_end();
+	if (ret < 0)
 		return ret;
+	*handlep = ret;
 
 	drm_gem_object_handle_reference(obj);
 
@@ -451,22 +449,15 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
 	if (obj == NULL)
 		return -ENOENT;
 
-again:
-	if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
+	idr_preload(GFP_KERNEL);
 	spin_lock(&dev->object_name_lock);
 	if (!obj->name) {
-		ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
-					&obj->name);
+		ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_NOWAIT);
+		obj->name = ret;
 		args->name = (uint64_t) obj->name;
 		spin_unlock(&dev->object_name_lock);
 
-		if (ret == -EAGAIN)
-			goto again;
-		else if (ret)
+		if (ret < 0)
 			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 200e104..7d30802 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -109,7 +109,6 @@ 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;
 
@@ -121,25 +120,11 @@ 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_get_new_above(&drm_minors_idr, NULL,
-				base, &new_id);
+	ret = idr_alloc(&drm_minors_idr, NULL, base, limit, GFP_KERNEL);
 	mutex_unlock(&dev->struct_mutex);
-	if (ret == -EAGAIN)
-		goto again;
-	else if (ret)
-		return ret;
 
-	if (new_id >= limit) {
-		idr_remove(&drm_minors_idr, new_id);
-		return -EINVAL;
-	}
-	return new_id;
+	return ret == -ENOSPC ? -EINVAL : ret;
 }
 
 struct drm_master *drm_master_create(struct drm_minor *minor)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 32/77] drm/exynos: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (30 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 31/77] drm: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 33/77] drm/i915: " Tejun Heo
                   ` (45 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, David Airlie, Kukjin Kim, dri-devel

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: David Airlie <airlied@linux.ie>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: dri-devel@lists.freedesktop.org
---
 drivers/gpu/drm/exynos/exynos_drm_ipp.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 90398df..1adce07 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -137,21 +137,15 @@ 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_get_new_above(id_idr, obj, 1, (int *)idp);
+	ret = idr_alloc(id_idr, obj, 1, 0, GFP_KERNEL);
 	mutex_unlock(lock);
-	if (ret == -EAGAIN)
-		goto again;
+	if (ret < 0)
+		return ret;
 
-	return ret;
+	*idp = ret;
+	return 0;
 }
 
 static void *ipp_find_obj(struct idr *id_idr, struct mutex *lock, u32 id)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 33/77] drm/i915: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (31 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 32/77] drm/exynos: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 34/77] drm/sis: " Tejun Heo
                   ` (44 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, David Airlie, dri-devel

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: David Airlie <airlied@linux.ie>
Cc: dri-devel@lists.freedesktop.org
---
 drivers/gpu/drm/i915/i915_gem_context.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index a3f06bc..27e586a 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, id;
+	int ret;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (ctx == NULL)
@@ -169,22 +169,11 @@ create_hw_context(struct drm_device *dev,
 
 	ctx->file_priv = file_priv;
 
-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)
+	ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0,
+			GFP_KERNEL);
+	if (ret < 0)
 		goto err_out;
+	ctx->id = ret;
 
 	return ctx;
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 34/77] drm/sis: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (32 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 33/77] drm/i915: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 35/77] drm/via: " Tejun Heo
                   ` (43 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, David Airlie, dri-devel

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: David Airlie <airlied@linux.ie>
Cc: dri-devel@lists.freedesktop.org
---
 drivers/gpu/drm/sis/sis_mm.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
index 2b2f78c..9a43d98 100644
--- a/drivers/gpu/drm/sis/sis_mm.c
+++ b/drivers/gpu/drm/sis/sis_mm.c
@@ -128,17 +128,10 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
 	if (retval)
 		goto fail_alloc;
 
-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)
+	retval = idr_alloc(&dev_priv->object_idr, item, 1, 0, GFP_KERNEL);
+	if (retval < 0)
 		goto fail_idr;
+	user_key = retval;
 
 	list_add(&item->owner_list, &file_priv->obj_list);
 	mutex_unlock(&dev->struct_mutex);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 35/77] drm/via: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (33 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 34/77] drm/sis: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 36/77] drm/vmwgfx: " Tejun Heo
                   ` (42 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, David Airlie, dri-devel

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: David Airlie <airlied@linux.ie>
Cc: dri-devel@lists.freedesktop.org
---
 drivers/gpu/drm/via/via_mm.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index 0d55432..0ab93ff 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -148,17 +148,10 @@ int via_mem_alloc(struct drm_device *dev, void *data,
 	if (retval)
 		goto fail_alloc;
 
-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)
+	retval = idr_alloc(&dev_priv->object_idr, item, 1, 0, GFP_KERNEL);
+	if (retval < 0)
 		goto fail_idr;
+	user_key = retval;
 
 	list_add(&item->owner_list, &file_priv->obj_list);
 	mutex_unlock(&dev->struct_mutex);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 36/77] drm/vmwgfx: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (34 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 35/77] drm/via: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 37/77] i2c: " Tejun Heo
                   ` (41 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, David Airlie, dri-devel

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: David Airlie <airlied@linux.ie>
Cc: dri-devel@lists.freedesktop.org
---
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index e01a17b..c9d0676 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -177,17 +177,16 @@ int vmw_resource_alloc_id(struct vmw_resource *res)
 
 	BUG_ON(res->id != -1);
 
-	do {
-		if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
-			return -ENOMEM;
-
-		write_lock(&dev_priv->resource_lock);
-		ret = idr_get_new_above(idr, res, 1, &res->id);
-		write_unlock(&dev_priv->resource_lock);
+	idr_preload(GFP_KERNEL);
+	write_lock(&dev_priv->resource_lock);
 
-	} while (ret == -EAGAIN);
+	ret = idr_alloc(idr, res, 1, 0, GFP_NOWAIT);
+	if (ret >= 0)
+		res->id = ret;
 
-	return ret;
+	write_unlock(&dev_priv->resource_lock);
+	idr_preload_end();
+	return ret < 0 ? ret : 0;
 }
 
 /**
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 37/77] i2c: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (35 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 36/77] drm/vmwgfx: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-07 15:28   ` Mark Brown
  2013-02-06 19:40 ` [PATCH 38/77] IB/core: convert to idr_alloc() Tejun Heo
                   ` (40 subsequent siblings)
  77 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Jean Delvare, linux-i2c

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: linux-i2c@vger.kernel.org
---
 drivers/i2c/i2c-core.c | 45 ++++++++++-----------------------------------
 1 file changed, 10 insertions(+), 35 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 66a30f7..795c916 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -935,25 +935,16 @@ out_list:
  */
 int i2c_add_adapter(struct i2c_adapter *adapter)
 {
-	int	id, res = 0;
-
-retry:
-	if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
-		return -ENOMEM;
+	int res;
 
 	mutex_lock(&core_lock);
-	/* "above" here means "above or equal to", sigh */
-	res = idr_get_new_above(&i2c_adapter_idr, adapter,
-				__i2c_first_dynamic_bus_num, &id);
+	res = idr_alloc(&i2c_adapter_idr, adapter,
+			__i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
 	mutex_unlock(&core_lock);
-
-	if (res < 0) {
-		if (res == -EAGAIN)
-			goto retry;
+	if (res < 0)
 		return res;
-	}
 
-	adapter->nr = id;
+	adapter->nr = res;
 	return i2c_register_adapter(adapter);
 }
 EXPORT_SYMBOL(i2c_add_adapter);
@@ -984,33 +975,17 @@ 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);
-	/* "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);
-	}
+	id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,
+		       GFP_KERNEL);
 	mutex_unlock(&core_lock);
-	if (status == -EAGAIN)
-		goto retry;
-
-	if (status == 0)
-		status = i2c_register_adapter(adap);
-	return status;
+	if (id < 0)
+		return id == -ENOSPC ? -EBUSY : id;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 38/77] IB/core: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (36 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 37/77] i2c: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 39/77] IB/amso1100: " Tejun Heo
                   ` (39 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Roland Dreier, Sean Hefty,
	Hal Rosenstock, linux-rdma

Convert to the much saner new idr interface.

Only compile tested.

v2: Mike triggered WARN_ON() in idr_preload() because send_mad(),
    which may be used from non-process context, was calling
    idr_preload() unconditionally.  Preload iff @gfp_mask has
    __GFP_WAIT.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Sean Hefty <sean.hefty@intel.com>
Reported-by: "Marciniszyn, Mike" <mike.marciniszyn@intel.com>
Cc: Roland Dreier <roland@kernel.org>
Cc: Sean Hefty <sean.hefty@intel.com>
Cc: Hal Rosenstock <hal.rosenstock@gmail.com>
Cc: linux-rdma@vger.kernel.org
---
 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 ++++++++---------
 6 files changed, 48 insertions(+), 81 deletions(-)

diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 394fea2..98281fe 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -382,20 +382,21 @@ 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 ret, id;
+	int id;
 	static int next_id;
 
-	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) );
+	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();
 
 	cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand;
-	return ret;
+	return id < 0 ? id : 0;
 }
 
 static void cm_free_id(__be32 local_id)
@@ -3844,7 +3845,6 @@ 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 d789eea..c32eeaa 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -2143,33 +2143,23 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
 			  unsigned short snum)
 {
 	struct rdma_bind_list *bind_list;
-	int port, ret;
+	int ret;
 
 	bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL);
 	if (!bind_list)
 		return -ENOMEM;
 
-	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;
-	}
+	ret = idr_alloc(ps, bind_list, snum, snum + 1, GFP_KERNEL);
+	if (ret < 0)
+		goto err;
 
 	bind_list->ps = ps;
-	bind_list->port = (unsigned short) port;
+	bind_list->port = (unsigned short)ret;
 	cma_bind_port(bind_list, id_priv);
 	return 0;
-err2:
-	idr_remove(ps, port);
-err1:
+err:
 	kfree(bind_list);
-	return ret;
+	return ret == -ENOSPC ? -EADDRNOTAVAIL : 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 a8905ab..934f45e 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -611,19 +611,21 @@ 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;
 
-retry:
-	if (!idr_pre_get(&query_idr, gfp_mask))
-		return -ENOMEM;
+	if (preload)
+		idr_preload(gfp_mask);
 	spin_lock_irqsave(&idr_lock, flags);
-	ret = idr_get_new(&query_idr, query, &id);
+
+	id = idr_alloc(&query_idr, query, 0, 0, GFP_NOWAIT);
+
 	spin_unlock_irqrestore(&idr_lock, flags);
-	if (ret == -EAGAIN)
-		goto retry;
-	if (ret)
-		return ret;
+	if (preload)
+		idr_preload_end();
+	if (id < 0)
+		return id;
 
 	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 49b15ac..f2f6393 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -176,7 +176,6 @@ 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)
@@ -187,17 +186,10 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
 	ctx->file = file;
 	INIT_LIST_HEAD(&ctx->events);
 
-	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)
+	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)
 		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 2709ff5..5ca44cd 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -145,7 +145,6 @@ 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)
@@ -156,17 +155,10 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
 	INIT_LIST_HEAD(&ctx->mc_list);
 	ctx->file = file;
 
-	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)
+	mutex_lock(&mut);
+	ctx->id = idr_alloc(&ctx_idr, ctx, 0, 0, GFP_KERNEL);
+	mutex_unlock(&mut);
+	if (ctx->id < 0)
 		goto error;
 
 	list_add_tail(&ctx->list, &file->ctx_list);
@@ -180,23 +172,15 @@ 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;
 
-	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)
+	mutex_lock(&mut);
+	mc->id = idr_alloc(&multicast_idr, mc, 0, 0, GFP_KERNEL);
+	mutex_unlock(&mut);
+	if (mc->id < 0)
 		goto error;
 
 	mc->ctx = ctx;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 0cb0007..83bc309 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -124,18 +124,17 @@ static int idr_add_uobj(struct idr *idr, struct ib_uobject *uobj)
 {
 	int ret;
 
-retry:
-	if (!idr_pre_get(idr, GFP_KERNEL))
-		return -ENOMEM;
-
+	idr_preload(GFP_KERNEL);
 	spin_lock(&ib_uverbs_idr_lock);
-	ret = idr_get_new(idr, uobj, &uobj->id);
-	spin_unlock(&ib_uverbs_idr_lock);
 
-	if (ret == -EAGAIN)
-		goto retry;
+	ret = idr_alloc(idr, uobj, 0, 0, GFP_NOWAIT);
+	if (ret >= 0)
+		uobj->id = ret;
 
-	return ret;
+	spin_unlock(&ib_uverbs_idr_lock);
+	idr_preload_end();
+
+	return ret < 0 ? ret : 0;
 }
 
 void idr_remove_uobj(struct idr *idr, struct ib_uobject *uobj)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 39/77] IB/amso1100: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (37 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 38/77] IB/core: convert to idr_alloc() Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 40/77] IB/cxgb3: " Tejun Heo
                   ` (38 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Tom Tucker, linux-rdma

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Cc: Tom Tucker <tom@opengridcomputing.com>
Cc: linux-rdma@vger.kernel.org
---
 drivers/infiniband/hw/amso1100/c2_qp.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c
index 28cd5cb..0ab826b 100644
--- a/drivers/infiniband/hw/amso1100/c2_qp.c
+++ b/drivers/infiniband/hw/amso1100/c2_qp.c
@@ -382,14 +382,17 @@ static int c2_alloc_qpn(struct c2_dev *c2dev, struct c2_qp *qp)
 {
 	int ret;
 
-        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;
+	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;
 }
 
 static void c2_free_qpn(struct c2_dev *c2dev, int qpn)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 40/77] IB/cxgb3: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (38 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 39/77] IB/amso1100: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 41/77] IB/cxgb4: " Tejun Heo
                   ` (37 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, linux-rdma

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Cc: linux-rdma@vger.kernel.org
---
 drivers/infiniband/hw/cxgb3/iwch.h | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h
index a1c4457..8378622 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.h
+++ b/drivers/infiniband/hw/cxgb3/iwch.h
@@ -153,19 +153,17 @@ static inline int insert_handle(struct iwch_dev *rhp, struct idr *idr,
 				void *handle, u32 id)
 {
 	int ret;
-	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;
+
+	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;
 }
 
 static inline void remove_handle(struct iwch_dev *rhp, struct idr *idr, u32 id)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 41/77] IB/cxgb4: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (39 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 40/77] IB/cxgb3: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 42/77] IB/ehca: " Tejun Heo
                   ` (36 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, linux-rdma

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Cc: linux-rdma@vger.kernel.org
---
 drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 9c1644f..7f862da 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -260,20 +260,21 @@ static inline int _insert_handle(struct c4iw_dev *rhp, struct idr *idr,
 				 void *handle, u32 id, int lock)
 {
 	int ret;
-	int newid;
 
-	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;
+	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;
 }
 
 static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 42/77] IB/ehca: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (40 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 41/77] IB/cxgb4: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 43/77] IB/ipath: " Tejun Heo
                   ` (35 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Hoang-Nam Nguyen, Christoph Raisch, linux-rdma

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Cc: Christoph Raisch <raisch@de.ibm.com>
Cc: linux-rdma@vger.kernel.org
---
 drivers/infiniband/hw/ehca/ehca_cq.c | 27 +++++++--------------------
 drivers/infiniband/hw/ehca/ehca_qp.c | 34 +++++++++++++++-------------------
 2 files changed, 22 insertions(+), 39 deletions(-)

diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 8f52901..212150c 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, ret, i;
+	int ipz_rc, i;
 	unsigned long flags;
 
 	if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
@@ -163,32 +163,19 @@ 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;
 
-	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);
+	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();
 
-	if (ret) {
+	if (my_cq->token < 0) {
 		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 1493939..00d6861 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -636,30 +636,26 @@ static struct ehca_qp *internal_create_qp(
 		my_qp->send_cq =
 			container_of(init_attr->send_cq, struct ehca_cq, ib_cq);
 
-	do {
-		if (!idr_pre_get(&ehca_qp_idr, GFP_KERNEL)) {
-			ret = -ENOMEM;
-			ehca_err(pd->device, "Can't reserve idr resources.");
-			goto create_qp_exit0;
-		}
+	idr_preload(GFP_KERNEL);
+	write_lock_irqsave(&ehca_qp_idr_lock, flags);
 
-		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);
+	ret = idr_alloc(&ehca_qp_idr, my_qp, 0, 0x2000000, GFP_NOWAIT);
+	if (ret >= 0)
+		my_qp->token = ret;
 
-	if (ret) {
-		ret = -ENOMEM;
-		ehca_err(pd->device, "Can't allocate new idr entry.");
+	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 {
+			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;
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 43/77] IB/ipath: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (41 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 42/77] IB/ehca: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 44/77] IB/mlx4: " Tejun Heo
                   ` (34 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Mike Marciniszyn, linux-rdma

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Mike Marciniszyn <infinipath@intel.com>
Cc: linux-rdma@vger.kernel.org
---
 drivers/infiniband/hw/ipath/ipath_driver.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 7b371f5..fcdaeea 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -194,11 +194,6 @@ 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);
@@ -206,9 +201,10 @@ 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_get_new(&unit_table, dd, &dd->ipath_unit);
+	ret = idr_alloc(&unit_table, dd, 0, 0, GFP_KERNEL);
 	if (ret < 0) {
 		printk(KERN_ERR IPATH_DRV_NAME
 		       ": Could not allocate unit ID: error %d\n", -ret);
@@ -216,6 +212,7 @@ 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);
@@ -224,7 +221,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;
 }
@@ -2503,11 +2500,6 @@ 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) {
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 44/77] IB/mlx4: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (42 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 43/77] IB/ipath: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 45/77] IB/ocrdma: " Tejun Heo
                   ` (33 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Jack Morgenstein, Or Gerlitz,
	Roland Dreier, linux-rdma

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Jack Morgenstein <jackm@dev.mellanox.co.il>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Roland Dreier <roland@purestorage.com>
Cc: linux-rdma@vger.kernel.org
---
 drivers/infiniband/hw/mlx4/cm.c | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c
index dbc99d4..80e59ed 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, id;
+	int ret;
 	static int next_id;
 	struct id_map_entry *ent;
 	struct mlx4_ib_sriov *sriov = &to_mdev(ibdev)->sriov;
@@ -220,25 +220,23 @@ 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);
 
-	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);
-		}
+	idr_preload(GFP_KERNEL);
+	spin_lock(&to_mdev(ibdev)->sriov.id_map_lock);
 
-		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);
+	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);
 		list_add_tail(&ent->list, &sriov->cm_list);
-		spin_unlock(&sriov->id_map_lock);
-		return ent;
 	}
+
+	spin_unlock(&sriov->id_map_lock);
+	idr_preload_end();
+
+	if (ret >= 0)
+		return ent;
+
 	/*error flow*/
 	kfree(ent);
 	mlx4_ib_warn(ibdev, "No more space in the idr (err:0x%x)\n", ret);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 45/77] IB/ocrdma: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (43 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 44/77] IB/mlx4: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 46/77] IB/qib: " Tejun Heo
                   ` (32 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Roland Dreier, linux-rdma

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Roland Dreier <roland@purestorage.com>
Cc: linux-rdma@vger.kernel.org
---
 drivers/infiniband/hw/ocrdma/ocrdma_main.c | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
index c4e0131..48928c8 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
@@ -51,18 +51,6 @@ 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];
@@ -416,7 +404,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 = ocrdma_get_instance();
+	dev->id = idr_alloc(&ocrdma_dev_id, NULL, 0, 0, GFP_KERNEL);
 	if (dev->id < 0)
 		goto idr_err;
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 46/77] IB/qib: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (44 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 45/77] IB/ocrdma: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 47/77] dm: " Tejun Heo
                   ` (31 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Mike Marciniszyn, linux-rdma

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Mike Marciniszyn <infinipath@intel.com>
Cc: linux-rdma@vger.kernel.org
---
 drivers/infiniband/hw/qib/qib_init.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c
index ddf066d..50e33aa 100644
--- a/drivers/infiniband/hw/qib/qib_init.c
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -1060,22 +1060,23 @@ 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_get_new(&qib_unit_table, dd, &dd->unit);
-	if (ret >= 0)
+
+	ret = idr_alloc(&qib_unit_table, dd, 0, 0, GFP_NOWAIT);
+	if (ret >= 0) {
+		dd->unit = ret;
 		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,
@@ -1180,11 +1181,6 @@ 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) {
@@ -1199,7 +1195,6 @@ 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();
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 47/77] dm: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (45 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 46/77] IB/qib: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 48/77] memstick: " Tejun Heo
                   ` (30 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Alasdair Kergon, dm-devel

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alasdair Kergon <agk@redhat.com>
Cc: dm-devel@redhat.com
---
 drivers/md/dm.c | 54 +++++++++++++++---------------------------------------
 1 file changed, 15 insertions(+), 39 deletions(-)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index c644eb6..ac74b81 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1801,62 +1801,38 @@ static void free_minor(int minor)
  */
 static int specific_minor(int minor)
 {
-	int r, m;
+	int r;
 
 	if (minor >= (1 << MINORBITS))
 		return -EINVAL;
 
-	r = idr_pre_get(&_minor_idr, GFP_KERNEL);
-	if (!r)
-		return -ENOMEM;
-
+	idr_preload(GFP_KERNEL);
 	spin_lock(&_minor_lock);
 
-	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;
+	r = idr_alloc(&_minor_idr, MINOR_ALLOCED, minor, minor + 1, GFP_NOWAIT);
 
-	if (m != minor) {
-		idr_remove(&_minor_idr, m);
-		r = -EBUSY;
-		goto out;
-	}
-
-out:
 	spin_unlock(&_minor_lock);
-	return r;
+	idr_preload_end();
+	if (r < 0)
+		return r == -ENOSPC ? -EBUSY : r;
+	return 0;
 }
 
 static int next_free_minor(int *minor)
 {
-	int r, m;
-
-	r = idr_pre_get(&_minor_idr, GFP_KERNEL);
-	if (!r)
-		return -ENOMEM;
+	int r;
 
+	idr_preload(GFP_KERNEL);
 	spin_lock(&_minor_lock);
 
-	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;
+	r = idr_alloc(&_minor_idr, MINOR_ALLOCED, 0, 1 << MINORBITS, GFP_NOWAIT);
 
-out:
 	spin_unlock(&_minor_lock);
-	return r;
+	idr_preload_end();
+	if (r < 0)
+		return r;
+	*minor = r;
+	return 0;
 }
 
 static const struct block_device_operations dm_blk_dops;
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 48/77] memstick: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (46 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 47/77] dm: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 49/77] mfd: " Tejun Heo
                   ` (29 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Alex Dubov

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alex Dubov <oakad@yahoo.com>
---
 drivers/memstick/core/memstick.c    | 21 ++++++++++-----------
 drivers/memstick/core/mspro_block.c | 17 +++--------------
 2 files changed, 13 insertions(+), 25 deletions(-)

diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index 56ff19c..ffcb10a 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -512,18 +512,17 @@ int memstick_add_host(struct memstick_host *host)
 {
 	int rc;
 
-	while (1) {
-		if (!idr_pre_get(&memstick_host_idr, GFP_KERNEL))
-			return -ENOMEM;
+	idr_preload(GFP_KERNEL);
+	spin_lock(&memstick_host_lock);
 
-		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;
-	}
+	rc = idr_alloc(&memstick_host_idr, host, 0, 0, GFP_NOWAIT);
+	if (rc >= 0)
+		host->id = rc;
+
+	spin_unlock(&memstick_host_lock);
+	idr_preload_end();
+	if (rc < 0)
+		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 9729b92..f12b78d 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -1213,21 +1213,10 @@ 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);
-	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);
+	disk_id = idr_alloc(&mspro_block_disk_idr, card, 0, 256, GFP_KERNEL);
 	mutex_unlock(&mspro_block_disk_lock);
-
-	if (rc)
-		return rc;
-
-	if ((disk_id << MSPRO_BLOCK_PART_SHIFT) > 255) {
-		rc = -ENOSPC;
-		goto out_release_id;
-	}
+	if (disk_id < 0)
+		return disk_id;
 
 	msb->disk = alloc_disk(1 << MSPRO_BLOCK_PART_SHIFT);
 	if (!msb->disk) {
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 49/77] mfd: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (47 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 48/77] memstick: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 50/77] misc/c2port: " Tejun Heo
                   ` (28 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Samuel Ortiz

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
 drivers/mfd/rtsx_pcr.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 9016932..81d8b14 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -1056,15 +1056,14 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
 	}
 	handle->pcr = pcr;
 
-	if (!idr_pre_get(&rtsx_pci_idr, GFP_KERNEL)) {
-		ret = -ENOMEM;
-		goto free_handle;
-	}
-
+	idr_preload(GFP_KERNEL);
 	spin_lock(&rtsx_pci_lock);
-	ret = idr_get_new(&rtsx_pci_idr, pcr, &pcr->id);
+	ret = idr_alloc(&rtsx_pci_idr, pcr, 0, 0, GFP_NOWAIT);
+	if (ret >= 0)
+		pcr->id = ret;
 	spin_unlock(&rtsx_pci_lock);
-	if (ret)
+	idr_preload_end();
+	if (ret < 0)
 		goto free_handle;
 
 	pcr->pci = pcidev;
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 50/77] misc/c2port: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (48 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 49/77] mfd: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 51/77] misc/tifm_core: " Tejun Heo
                   ` (27 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Arnd Bergmann, Rodolfo Giometti

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Rodolfo Giometti <giometti@linux.it>
---
 drivers/misc/c2port/core.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c
index f428d86..f32550a 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 id, ret;
+	int ret;
 
 	if (unlikely(!ops) || unlikely(!ops->access) || \
 		unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
@@ -897,22 +897,18 @@ struct c2port_device *c2port_device_register(char *name,
 	if (unlikely(!c2dev))
 		return ERR_PTR(-ENOMEM);
 
-	ret = idr_pre_get(&c2port_idr, GFP_KERNEL);
-	if (!ret) {
-		ret = -ENOMEM;
-		goto error_idr_get_new;
-	}
-
+	idr_preload(GFP_KERNEL);
 	spin_lock_irq(&c2port_idr_lock);
-	ret = idr_get_new(&c2port_idr, c2dev, &id);
+	ret = idr_alloc(&c2port_idr, c2dev, 0, 0, GFP_NOWAIT);
 	spin_unlock_irq(&c2port_idr_lock);
+	idr_preload_end();
 
 	if (ret < 0)
-		goto error_idr_get_new;
-	c2dev->id = id;
+		goto error_idr_alloc;
+	c2dev->id = ret;
 
 	c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
-					"c2port%d", id);
+				   "c2port%d", c2dev->id);
 	if (unlikely(IS_ERR(c2dev->dev))) {
 		ret = PTR_ERR(c2dev->dev);
 		goto error_device_create;
@@ -946,10 +942,10 @@ error_device_create_bin_file:
 
 error_device_create:
 	spin_lock_irq(&c2port_idr_lock);
-	idr_remove(&c2port_idr, id);
+	idr_remove(&c2port_idr, c2dev->id);
 	spin_unlock_irq(&c2port_idr_lock);
 
-error_idr_get_new:
+error_idr_alloc:
 	kfree(c2dev);
 
 	return ERR_PTR(ret);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 51/77] misc/tifm_core: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (49 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 50/77] misc/c2port: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 52/77] mmc: " Tejun Heo
                   ` (26 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Arnd Bergmann, Alex Dubov

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alex Dubov <oakad@yahoo.com>
---
 drivers/misc/tifm_core.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index 0bd5349..0ab7c92 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -196,13 +196,14 @@ int tifm_add_adapter(struct tifm_adapter *fm)
 {
 	int rc;
 
-	if (!idr_pre_get(&tifm_adapter_idr, GFP_KERNEL))
-		return -ENOMEM;
-
+	idr_preload(GFP_KERNEL);
 	spin_lock(&tifm_adapter_lock);
-	rc = idr_get_new(&tifm_adapter_idr, fm, &fm->id);
+	rc = idr_alloc(&tifm_adapter_idr, fm, 0, 0, GFP_NOWAIT);
+	if (rc >= 0)
+		fm->id = rc;
 	spin_unlock(&tifm_adapter_lock);
-	if (rc)
+	idr_preload_end();
+	if (rc < 0)
 		return rc;
 
 	dev_set_name(&fm->dev, "tifm%u", fm->id);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 52/77] mmc: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (50 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 51/77] misc/tifm_core: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 53/77] mtd: " Tejun Heo
                   ` (25 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Chris Ball, linux-mmc

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Chris Ball <cjb@laptop.org>
Cc: linux-mmc@vger.kernel.org
---
 drivers/mmc/core/host.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index ee2e16b..1117de7 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -306,19 +306,20 @@ 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_get_new(&mmc_host_idr, host, &host->index);
+	err = idr_alloc(&mmc_host_idr, host, 0, 0, GFP_NOWAIT);
+	if (err >= 0)
+		host->index = err;
 	spin_unlock(&mmc_host_lock);
-	if (err)
+	idr_preload_end();
+	if (err < 0)
 		goto free;
 
 	dev_set_name(&host->class_dev, "mmc%d", host->index);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 53/77] mtd: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (51 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 52/77] mmc: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 54/77] macvtap: " Tejun Heo
                   ` (24 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, David Woodhouse, linux-mtd

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: linux-mtd@lists.infradead.org
---
 drivers/mtd/mtdcore.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index ec794a7..61d5f56 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -349,13 +349,8 @@ int add_mtd_device(struct mtd_info *mtd)
 	BUG_ON(mtd->writesize == 0);
 	mutex_lock(&mtd_table_mutex);
 
-	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)
+	i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
+	if (i < 0)
 		goto fail_locked;
 
 	mtd->index = i;
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 54/77] macvtap: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (52 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 53/77] mtd: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 55/77] ppp: " Tejun Heo
                   ` (23 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Jason Wang, Michael S. Tsirkin

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
---
 drivers/net/macvtap.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index b181dfb..1814cfe 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -279,28 +279,17 @@ 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);
-	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 {
+	retval = idr_alloc(&minor_idr, vlan, 1, MACVTAP_NUM_DEVS, GFP_KERNEL);
+	if (retval >= 0) {
+		vlan->minor = retval;
+	} else if (retval == -ENOSPC) {
 		printk(KERN_ERR "too many macvtap devices\n");
 		retval = -EINVAL;
-		idr_remove(&minor_idr, id);
 	}
-exit:
 	mutex_unlock(&minor_lock);
-	return retval;
+	return retval < 0 ? retval : 0;
 }
 
 static void macvtap_free_minor(struct macvlan_dev *vlan)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 55/77] ppp: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (53 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 54/77] macvtap: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 56/77] power: " Tejun Heo
                   ` (22 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Paul Mackerras, linux-ppp

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linux-ppp@vger.kernel.org
---
 drivers/net/ppp/ppp_generic.c | 33 ++++-----------------------------
 1 file changed, 4 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 0b2706a..7efdb91 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -2946,46 +2946,21 @@ 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 = __unit_alloc(p, ptr, n);
-	if (unit < 0)
-		return unit;
-	else if (unit != n) {
-		idr_remove(p, unit);
-		return -EINVAL;
-	}
-
+	unit = idr_alloc(p, ptr, n, n + 1, GFP_KERNEL);
+	if (unit == -ENOSPC)
+		unit = -EINVAL;
 	return unit;
 }
 
 /* get new free unit number and associate pointer with it */
 static int unit_get(struct idr *p, void *ptr)
 {
-	return __unit_alloc(p, ptr, 0);
+	return idr_alloc(p, ptr, 0, 0, GFP_KERNEL);
 }
 
 /* put unit number back to a pool */
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 56/77] power: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (54 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 55/77] ppp: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 57/77] pps: " Tejun Heo
                   ` (21 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, David Woodhouse

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Anton Vorontsov <cbou@mail.ru>
Cc: David Woodhouse <dwmw2@infradead.org>
---
 drivers/power/bq2415x_charger.c | 11 +++--------
 drivers/power/bq27x00_battery.c |  9 +++------
 drivers/power/ds2782_battery.c  |  9 ++-------
 3 files changed, 8 insertions(+), 21 deletions(-)

diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
index ca70365..3f00568 100644
--- a/drivers/power/bq2415x_charger.c
+++ b/drivers/power/bq2415x_charger.c
@@ -1504,16 +1504,11 @@ 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);
-	ret = idr_get_new(&bq2415x_id, client, &num);
+	num = idr_alloc(&bq2415x_id, client, 0, 0, GFP_KERNEL);
 	mutex_unlock(&bq2415x_id_mutex);
-
-	if (ret < 0)
-		return ret;
+	if (num < 0)
+		return num;
 
 	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 8ccf5d7..26037ca 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -791,14 +791,11 @@ 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);
-	retval = idr_get_new(&battery_id, client, &num);
+	num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL);
 	mutex_unlock(&battery_mutex);
-	if (retval < 0)
-		return retval;
+	if (num < 0)
+		return num;
 
 	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 e7301b3..c09e772 100644
--- a/drivers/power/ds2782_battery.c
+++ b/drivers/power/ds2782_battery.c
@@ -395,17 +395,12 @@ 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_get_new(&battery_id, client, &num);
+	ret = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL);
 	mutex_unlock(&battery_lock);
 	if (ret < 0)
 		goto fail_id;
+	num = ret;
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info) {
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 57/77] pps: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (55 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 56/77] power: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 58/77] remoteproc: " Tejun Heo
                   ` (20 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Rodolfo Giometti

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Rodolfo Giometti <giometti@enneenne.com>
---
 drivers/pps/kapi.c |  2 +-
 drivers/pps/pps.c  | 36 ++++++++++++++----------------------
 2 files changed, 15 insertions(+), 23 deletions(-)

diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index f197e8e..cdad4d9 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_get_new()
+	/* These initializations must be done before calling idr_alloc()
 	 * 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 2420d5a..de8e663 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -290,29 +290,21 @@ int pps_register_cdev(struct pps_device *pps)
 	dev_t devt;
 
 	mutex_lock(&pps_idr_lock);
-	/* Get new ID for the new PPS source */
-	if (idr_pre_get(&pps_idr, GFP_KERNEL) == 0) {
-		mutex_unlock(&pps_idr_lock);
-		return -ENOMEM;
-	}
-
-	/* Now really allocate the PPS source.
-	 * After idr_get_new() calling the new source will be freely available
-	 * into the kernel.
+	/*
+	 * Get new ID for the new PPS source.  After idr_alloc() 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;
+	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;
 	}
+	pps->id = err;
+	mutex_unlock(&pps_idr_lock);
 
 	devt = MKDEV(MAJOR(pps_devt), pps->id);
 
@@ -345,8 +337,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;
 }
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 58/77] remoteproc: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (56 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 57/77] pps: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 59/77] rpmsg: " Tejun Heo
                   ` (19 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Ohad Ben-Cohen

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/remoteproc/remoteproc_core.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 634d367..29387df 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -199,11 +199,6 @@ 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
@@ -221,12 +216,13 @@ 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_get_new(&rproc->notifyids, rvring, &notifyid);
+	ret = idr_alloc(&rproc->notifyids, rvring, 0, 0, GFP_KERNEL);
 	if (ret) {
-		dev_err(dev, "idr_get_new failed: %d\n", ret);
+		dev_err(dev, "idr_alloc 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);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 59/77] rpmsg: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (57 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 58/77] remoteproc: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 60/77] scsi/bfa: " Tejun Heo
                   ` (18 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Ohad Ben-Cohen

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/rpmsg/virtio_rpmsg_bus.c | 30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index aaa6840..a59684b 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -213,13 +213,10 @@ 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 err, tmpaddr, request;
+	int id_min, id_max, id;
 	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");
@@ -234,31 +231,28 @@ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp,
 	ept->priv = priv;
 
 	/* do we need to allocate a local address ? */
-	request = addr == RPMSG_ADDR_ANY ? RPMSG_RESERVED_ADDRESSES : addr;
+	if (addr == RPMSG_ADDR_ANY) {
+		id_min = RPMSG_RESERVED_ADDRESSES;
+		id_max = 0;
+	} else {
+		id_min = addr;
+		id_max = addr + 1;
+	}
 
 	mutex_lock(&vrp->endpoints_lock);
 
 	/* bind the endpoint to an rpmsg address (and allocate one if needed) */
-	err = idr_get_new_above(&vrp->endpoints, ept, request, &tmpaddr);
-	if (err) {
-		dev_err(dev, "idr_get_new_above failed: %d\n", err);
+	id = idr_alloc(&vrp->endpoints, ept, id_min, id_max, GFP_KERNEL);
+	if (id < 0) {
+		dev_err(dev, "idr_alloc failed: %d\n", id);
 		goto free_ept;
 	}
-
-	/* 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;
+	ept->addr = id;
 
 	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);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 60/77] scsi/bfa: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (58 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 59/77] rpmsg: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 61/77] scsi: " Tejun Heo
                   ` (17 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Krishna C Gudipati, linux-scsi

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Krishna C Gudipati <kgudipat@brocade.com>
Cc: linux-scsi@vger.kernel.org
---
 drivers/scsi/bfa/bfad_im.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 8f92732..5864f98 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -523,20 +523,13 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
 	int error = 1;
 
 	mutex_lock(&bfad_mutex);
-	if (!idr_pre_get(&bfad_im_port_index, GFP_KERNEL)) {
+	error = idr_alloc(&bfad_im_port_index, im_port, 0, 0, GFP_KERNEL);
+	if (error < 0) {
 		mutex_unlock(&bfad_mutex);
-		printk(KERN_WARNING "idr_pre_get failure\n");
+		printk(KERN_WARNING "idr_alloc failure\n");
 		goto out;
 	}
-
-	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;
-	}
-
+	im_port->idr_id = error;
 	mutex_unlock(&bfad_mutex);
 
 	im_port->shost = bfad_scsi_host_alloc(im_port, bfad);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 61/77] scsi: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (59 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 60/77] scsi/bfa: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 62/77] target/iscsi: " Tejun Heo
                   ` (16 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, James E.J. Bottomley, linux-scsi

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: linux-scsi@vger.kernel.org
---
 drivers/scsi/ch.c | 21 +++++++++------------
 drivers/scsi/sg.c | 43 +++++++++++++++++--------------------------
 drivers/scsi/st.c | 27 ++++++++-------------------
 3 files changed, 34 insertions(+), 57 deletions(-)

diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index a15474e..2a32374 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 minor, ret = -ENOMEM;
+	int ret;
 	scsi_changer *ch;
 
 	if (sd->type != TYPE_MEDIUM_CHANGER)
@@ -905,22 +905,19 @@ static int ch_probe(struct device *dev)
 	if (NULL == ch)
 		return -ENOMEM;
 
-	if (!idr_pre_get(&ch_index_idr, GFP_KERNEL))
-		goto free_ch;
-
+	idr_preload(GFP_KERNEL);
 	spin_lock(&ch_index_lock);
-	ret = idr_get_new(&ch_index_idr, ch, &minor);
+	ret = idr_alloc(&ch_index_idr, ch, 0, CH_MAX_DEVS + 1, GFP_NOWAIT);
 	spin_unlock(&ch_index_lock);
+	idr_preload_end();
 
-	if (ret)
+	if (ret < 0) {
+		if (ret == -ENOSPC)
+			ret = -ENODEV;
 		goto free_ch;
-
-	if (minor > CH_MAX_DEVS) {
-		ret = -ENODEV;
-		goto remove_idr;
 	}
 
-	ch->minor = minor;
+	ch->minor = ret;
 	sprintf(ch->name,"ch%d",ch->minor);
 
 	class_dev = device_create(ch_sysfs_class, dev,
@@ -944,7 +941,7 @@ static int ch_probe(struct device *dev)
 
 	return 0;
 remove_idr:
-	idr_remove(&ch_index_idr, minor);
+	idr_remove(&ch_index_idr, ch->minor);
 free_ch:
 	kfree(ch);
 	return ret;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index afa5bfc..df5e961 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1392,24 +1392,23 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
 		return ERR_PTR(-ENOMEM);
 	}
 
-	if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) {
-		printk(KERN_WARNING "idr expansion Sg_device failure\n");
-		error = -ENOMEM;
-		goto out;
-	}
-
+	idr_preload(GFP_KERNEL);
 	write_lock_irqsave(&sg_index_lock, iflags);
 
-	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;
+	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;
 	}
-
-	if (unlikely(k >= SG_MAX_DEVS))
-		goto overflow;
+	k = error;
 
 	SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k));
 	sprintf(disk->disk_name, "sg%d", k);
@@ -1421,25 +1420,17 @@ 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 98156a9..7c6edca 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, dev_num, error;
+	int i, error;
 	char *stp;
 
 	if (SDp->type != TYPE_TAPE)
@@ -4178,27 +4178,17 @@ static int st_probe(struct device *dev)
 	    tpnt->blksize_changed = 0;
 	mutex_init(&tpnt->lock);
 
-	if (!idr_pre_get(&st_index_idr, GFP_KERNEL)) {
-		pr_warn("st: idr expansion failed\n");
-		error = -ENOMEM;
-		goto out_put_disk;
-	}
-
+	idr_preload(GFP_KERNEL);
 	spin_lock(&st_index_lock);
-	error = idr_get_new(&st_index_idr, tpnt, &dev_num);
+	error = idr_alloc(&st_index_idr, tpnt, 0, ST_MAX_TAPES + 1, GFP_NOWAIT);
 	spin_unlock(&st_index_lock);
-	if (error) {
+	idr_preload_end();
+	if (error < 0) {
 		pr_warn("st: idr allocation failed: %d\n", error);
 		goto out_put_disk;
 	}
-
-	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);
+	tpnt->index = error;
+	sprintf(disk->disk_name, "st%d", tpnt->index);
 
 	dev_set_drvdata(dev, tpnt);
 
@@ -4218,9 +4208,8 @@ 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, dev_num);
+	idr_remove(&st_index_idr, tpnt->index);
 	spin_unlock(&st_index_lock);
 out_put_disk:
 	put_disk(disk);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 62/77] target/iscsi: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (60 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 61/77] scsi: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 63/77] scsi/lpfc: " Tejun Heo
                   ` (15 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Nicholas A. Bellinger, linux-scsi, target-devel

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Nicholas A. Bellinger <nab@linux-iscsi.org>
Cc: linux-scsi@vger.kernel.org
Cc: target-devel@vger.kernel.org
---
 drivers/target/iscsi/iscsi_target.c       | 15 ++++++++-------
 drivers/target/iscsi/iscsi_target_login.c | 15 ++++++---------
 2 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 339f97f..f1fdf4f 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -144,23 +144,24 @@ 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_get_new(&tiqn_idr, NULL, &tiqn->tiqn_index);
+
+	ret = idr_alloc(&tiqn_idr, NULL, 0, 0, GFP_NOWAIT);
 	if (ret < 0) {
-		pr_err("idr_get_new() failed for tiqn->tiqn_index\n");
+		pr_err("idr_alloc() 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 fdb632f..2535d4d 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -247,19 +247,16 @@ static int iscsi_login_zero_tsih_s1(
 	spin_lock_init(&sess->session_usage_lock);
 	spin_lock_init(&sess->ttt_lock);
 
-	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;
-	}
+	idr_preload(GFP_KERNEL);
 	spin_lock_bh(&sess_idr_lock);
-	ret = idr_get_new(&sess_idr, NULL, &sess->session_index);
+	ret = idr_alloc(&sess_idr, NULL, 0, 0, GFP_NOWAIT);
+	if (ret >= 0)
+		sess->session_index = ret;
 	spin_unlock_bh(&sess_idr_lock);
+	idr_preload_end();
 
 	if (ret < 0) {
-		pr_err("idr_get_new() for sess_idr failed\n");
+		pr_err("idr_alloc() for sess_idr failed\n");
 		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 				ISCSI_LOGIN_STATUS_NO_RESOURCES);
 		kfree(sess);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 63/77] scsi/lpfc: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (61 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 62/77] target/iscsi: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-11 22:47   ` James Smart
  2013-02-06 19:40 ` [PATCH 64/77] thermal: " Tejun Heo
                   ` (14 subsequent siblings)
  77 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, James Smart, linux-scsi

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: James Smart <james.smart@emulex.com>
Cc: linux-scsi@vger.kernel.org
---
 drivers/scsi/lpfc/lpfc_init.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 26ca2ef..314b4f6 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -3165,14 +3165,10 @@ destroy_port(struct lpfc_vport *vport)
 int
 lpfc_get_instance(void)
 {
-	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;
+	int ret;
+
+	ret = idr_alloc(&lpfc_hba_index, NULL, 0, 0, GFP_KERNEL);
+	return ret < 0 ? -1 : ret;
 }
 
 /**
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 64/77] thermal: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (62 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 63/77] scsi/lpfc: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 65/77] uio: " Tejun Heo
                   ` (13 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Zhang Rui, linux-pm

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Zhang Rui <rui.zhang@intel.com>
Cc: linux-pm@vger.kernel.org
---
 drivers/thermal/cpu_cooling.c | 17 +++++------------
 drivers/thermal/thermal_sys.c | 17 +++++------------
 2 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 836828e..c33fa53 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -73,21 +73,14 @@ static struct cpufreq_cooling_device *notify_device;
  */
 static int get_idr(struct idr *idr, int *id)
 {
-	int err;
-again:
-	if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
-		return -ENOMEM;
+	int ret;
 
 	mutex_lock(&cooling_cpufreq_lock);
-	err = idr_get_new(idr, NULL, id);
+	ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
 	mutex_unlock(&cooling_cpufreq_lock);
-
-	if (unlikely(err == -EAGAIN))
-		goto again;
-	else if (unlikely(err))
-		return err;
-
-	*id = *id & MAX_IDR_MASK;
+	if (unlikely(ret < 0))
+		return ret;
+	*id = ret;
 	return 0;
 }
 
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 0a1bf6b..0767193 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -131,23 +131,16 @@ EXPORT_SYMBOL_GPL(thermal_unregister_governor);
 
 static int get_idr(struct idr *idr, struct mutex *lock, int *id)
 {
-	int err;
-
-again:
-	if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
-		return -ENOMEM;
+	int ret;
 
 	if (lock)
 		mutex_lock(lock);
-	err = idr_get_new(idr, NULL, id);
+	ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
 	if (lock)
 		mutex_unlock(lock);
-	if (unlikely(err == -EAGAIN))
-		goto again;
-	else if (unlikely(err))
-		return err;
-
-	*id = *id & MAX_IDR_MASK;
+	if (unlikely(ret < 0))
+		return ret;
+	*id = ret;
 	return 0;
 }
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 65/77] uio: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (63 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 64/77] thermal: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 66/77] vfio: " Tejun Heo
                   ` (12 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Hans J. Koch

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Hans J. Koch" <hjk@hansjkoch.de>
---
 drivers/uio/uio.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 5110f36..c8b9262 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -369,26 +369,15 @@ 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);
-	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 {
+	retval = idr_alloc(&uio_idr, idev, 0, UIO_MAX_DEVICES, GFP_KERNEL);
+	if (retval >= 0) {
+		idev->minor = retval;
+	} else if (retval == -ENOSPC) {
 		dev_err(idev->dev, "too many uio devices\n");
 		retval = -EINVAL;
-		idr_remove(&uio_idr, id);
 	}
-exit:
 	mutex_unlock(&minor_lock);
 	return retval;
 }
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 66/77] vfio: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (64 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 65/77] uio: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 67/77] dlm: " Tejun Heo
                   ` (11 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, kvm

Convert to the much saner new idr interface.

Only compile tested.

v2: Restore accidentally dropped "index 0" comment as suggested by
    Alex.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Cc: kvm@vger.kernel.org
---
 drivers/vfio/vfio.c | 17 +----------------
 1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 12c264d..7f61abf 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -139,23 +139,8 @@ 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 */
-	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;
+	return idr_alloc(&vfio.group_idr, group, 1, MINORMASK + 1, GFP_KERNEL);
 }
 
 static void vfio_free_group_minor(int minor)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 67/77] dlm: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (65 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 66/77] vfio: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-03-11 19:29   ` David Teigland
  2013-02-06 19:40 ` [PATCH 68/77] inotify: convert to idr_alloc() Tejun Heo
                   ` (10 subsequent siblings)
  77 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo

Convert to the much saner new idr interface.  Error return values from
recover_idr_add() mix -1 and -errno.  The conversion doesn't change
that but it looks iffy.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 fs/dlm/lock.c    | 18 ++++++------------
 fs/dlm/recover.c | 27 +++++++++++++--------------
 2 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index f750165..1b11466 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, id;
+	int rv;
 
 	lkb = dlm_allocate_lkb(ls);
 	if (!lkb)
@@ -1199,19 +1199,13 @@ 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);
 
- retry:
-	rv = idr_pre_get(&ls->ls_lkbidr, GFP_NOFS);
-	if (!rv)
-		return -ENOMEM;
-
+	idr_preload(GFP_NOFS);
 	spin_lock(&ls->ls_lkbidr_spin);
-	rv = idr_get_new_above(&ls->ls_lkbidr, lkb, 1, &id);
-	if (!rv)
-		lkb->lkb_id = id;
+	rv = idr_alloc(&ls->ls_lkbidr, lkb, 1, 0, GFP_NOWAIT);
+	if (rv >= 0)
+		lkb->lkb_id = rv;
 	spin_unlock(&ls->ls_lkbidr_spin);
-
-	if (rv == -EAGAIN)
-		goto retry;
+	idr_preload_end();
 
 	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 236d108..a6bc63f 100644
--- a/fs/dlm/recover.c
+++ b/fs/dlm/recover.c
@@ -305,27 +305,26 @@ 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, id;
-
-	rv = idr_pre_get(&ls->ls_recover_idr, GFP_NOFS);
-	if (!rv)
-		return -ENOMEM;
+	int rv;
 
+	idr_preload(GFP_NOFS);
 	spin_lock(&ls->ls_recover_idr_lock);
 	if (r->res_id) {
-		spin_unlock(&ls->ls_recover_idr_lock);
-		return -1;
-	}
-	rv = idr_get_new_above(&ls->ls_recover_idr, r, 1, &id);
-	if (rv) {
-		spin_unlock(&ls->ls_recover_idr_lock);
-		return rv;
+		rv = -1;
+		goto out_unlock;
 	}
-	r->res_id = id;
+	rv = idr_alloc(&ls->ls_recover_idr, r, 1, 0, GFP_NOWAIT);
+	if (rv < 0)
+		goto out_unlock;
+
+	r->res_id = rv;
 	ls->ls_recover_list_count++;
 	dlm_hold_rsb(r);
+	rv = 0;
+out_unlock:
 	spin_unlock(&ls->ls_recover_idr_lock);
-	return 0;
+	idr_preload_end();
+	return rv;
 }
 
 static void recover_idr_del(struct dlm_rsb *r)
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 68/77] inotify: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (66 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 67/77] dlm: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 69/77] ocfs2: " Tejun Heo
                   ` (9 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, John McCutchan, Robert Love, Eric Paris

Convert to the much saner new idr interface.

Note that the adhoc cyclic id allocation is buggy.  If wraparound
happens, the previous code with idr_get_new_above() may segfault and
the converted code will trigger WARN and return -EINVAL.  Even if it's
fixed to wrap to zero, the code will be prone to unnecessary -ENOSPC
failures after the first wraparound.  We probably need to implement
proper cyclic support in idr.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: John McCutchan <john@johnmccutchan.com>
Cc: Robert Love <rlove@rlove.org>
Cc: Eric Paris <eparis@parisplace.org>
---
 fs/notify/inotify/inotify_user.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 228a2c2..8f8099c 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -364,22 +364,20 @@ static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock,
 {
 	int ret;
 
-	do {
-		if (unlikely(!idr_pre_get(idr, GFP_KERNEL)))
-			return -ENOMEM;
+	idr_preload(GFP_KERNEL);
+	spin_lock(idr_lock);
 
-		spin_lock(idr_lock);
-		ret = idr_get_new_above(idr, i_mark, *last_wd + 1,
-					&i_mark->wd);
+	ret = idr_alloc(idr, i_mark, *last_wd + 1, 0, GFP_NOWAIT);
+	if (ret >= 0) {
 		/* we added the mark to the idr, take a reference */
-		if (!ret) {
-			*last_wd = i_mark->wd;
-			fsnotify_get_mark(&i_mark->fsn_mark);
-		}
-		spin_unlock(idr_lock);
-	} while (ret == -EAGAIN);
+		i_mark->wd = ret;
+		*last_wd = i_mark->wd;
+		fsnotify_get_mark(&i_mark->fsn_mark);
+	}
 
-	return ret;
+	spin_unlock(idr_lock);
+	idr_preload_end();
+	return ret < 0 ? ret : 0;
 }
 
 static struct inotify_inode_mark *inotify_idr_find_locked(struct fsnotify_group *group,
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 69/77] ocfs2: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (67 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 68/77] inotify: convert to idr_alloc() Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 70/77] ipc: " Tejun Heo
                   ` (8 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Mark Fasheh, Joel Becker

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
---
 fs/ocfs2/cluster/tcp.c | 32 +++++++++++++-------------------
 1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index a1d83c5..33b8924 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -304,28 +304,22 @@ 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 = 0;
-
-	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);
+	int ret;
 
-	if (ret == 0)  {
-		init_waitqueue_head(&nsw->ns_wq);
-		nsw->ns_sys_status = O2NET_ERR_NONE;
-		nsw->ns_status = 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);
 	}
+	spin_unlock(&nn->nn_lock);
+	if (ret < 0)
+		return ret;
 
-	return ret;
+	init_waitqueue_head(&nsw->ns_wq);
+	nsw->ns_sys_status = O2NET_ERR_NONE;
+	nsw->ns_status = 0;
+	return 0;
 }
 
 static void o2net_complete_nsw_locked(struct o2net_node *nn,
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 70/77] ipc: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (68 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 69/77] ocfs2: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-07 19:43   ` [PATCH v2 " Tejun Heo
  2013-02-06 19:40 ` [PATCH 71/77] cgroup: " Tejun Heo
                   ` (7 subsequent siblings)
  77 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Stanislav Kinsbursky, Eric W. Biederman,
	James Morris

Convert to the much saner new idr interface.

The new interface doesn't directly translate to the way idr_pre_get()
was used around ipc_addid() as preloading disables preemption.  From
my cursory reading, it seems like we should be able to do all
allocation from ipc_addid(), so I moved it there.  Can you please
check whether this would be okay?  If this is wrong and ipc_addid()
should be allowed to be called from non-sleepable context, I'd suggest
allocating id itself in the outer functions and later install the
pointer using idr_replace().

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Stanislav Kinsbursky <skinsbursky@parallels.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: James Morris <jmorris@namei.org>
---
 ipc/util.c | 30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/ipc/util.c b/ipc/util.c
index 74e1d9c..91ce0bc 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, err;
+	int id;
 	int next_id = ids->next_id;
 
 	if (size > IPCMNI)
@@ -261,17 +261,21 @@ 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);
 
-	err = idr_get_new_above(&ids->ipcs_idr, new,
-				(next_id < 0) ? 0 : ipcid_to_idx(next_id), &id);
-	if (err) {
+	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) {
 		spin_unlock(&new->lock);
 		rcu_read_unlock();
-		return err;
+		return id;
 	}
 
 	ids->in_use++;
@@ -307,19 +311,10 @@ 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;
 }
 
@@ -375,9 +370,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
 {
 	struct kern_ipc_perm *ipcp;
 	int flg = params->flg;
-	int err;
-retry:
-	err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
+	int err = 0;
 
 	/*
 	 * Take the lock as a writer since we are potentially going to add
@@ -413,9 +406,6 @@ retry:
 	}
 	up_write(&ids->rw_mutex);
 
-	if (err == -EAGAIN)
-		goto retry;
-
 	return err;
 }
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 71/77] cgroup: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (69 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 70/77] ipc: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 72/77] events: " Tejun Heo
                   ` (6 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, containers, cgroups

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Cc: containers@lists.linux-foundation.org
Cc: cgroups@vger.kernel.org
---
 kernel/cgroup.c | 27 ++++++++-------------------
 1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 525c508..29f9e11 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -5284,7 +5284,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 myid, error, size;
+	int ret, size;
 
 	BUG_ON(!ss->use_id);
 
@@ -5292,35 +5292,24 @@ static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
 	newid = kzalloc(size, GFP_KERNEL);
 	if (!newid)
 		return ERR_PTR(-ENOMEM);
-	/* get id */
-	if (unlikely(!idr_pre_get(&ss->idr, GFP_KERNEL))) {
-		error = -ENOMEM;
-		goto err_out;
-	}
+
+	idr_preload(GFP_KERNEL);
 	spin_lock(&ss->id_lock);
 	/* Don't use 0. allocates an ID of 1-65535 */
-	error = idr_get_new_above(&ss->idr, newid, 1, &myid);
+	ret = idr_alloc(&ss->idr, newid, 1, CSS_ID_MAX + 1, GFP_NOWAIT);
 	spin_unlock(&ss->id_lock);
+	idr_preload_end();
 
 	/* Returns error when there are no free spaces for new ID.*/
-	if (error) {
-		error = -ENOSPC;
+	if (ret < 0)
 		goto err_out;
-	}
-	if (myid > CSS_ID_MAX)
-		goto remove_idr;
 
-	newid->id = myid;
+	newid->id = ret;
 	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(error);
+	return ERR_PTR(ret);
 
 }
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 72/77] events: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (70 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 71/77] cgroup: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 73/77] posix-timers: " Tejun Heo
                   ` (5 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Peter Zijlstra, Paul Mackerras,
	Ingo Molnar, Arnaldo Carvalho de Melo

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
---
 kernel/events/core.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 7b6646a..43ba037 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5965,13 +5965,9 @@ int perf_pmu_register(struct pmu *pmu, char *name, int type)
 	pmu->name = name;
 
 	if (type < 0) {
-		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;
+		type = idr_alloc(&pmu_idr, pmu, PERF_TYPE_MAX, 0, GFP_KERNEL);
+		if (type < 0) {
+			ret = type;
 			goto free_pdc;
 		}
 	}
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 73/77] posix-timers: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (71 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 72/77] events: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 74/77] net/9p: " Tejun Heo
                   ` (4 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Thomas Gleixner

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/posix-timers.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 69185ae..e897f66 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -552,24 +552,22 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
 		return -EAGAIN;
 
 	spin_lock_init(&new_timer->it_lock);
- retry:
-	if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) {
-		error = -EAGAIN;
-		goto out;
-	}
+
+	idr_preload(GFP_KERNEL);
 	spin_lock_irq(&idr_lock);
-	error = idr_get_new(&posix_timers_id, new_timer, &new_timer_id);
+	error = idr_alloc(&posix_timers_id, new_timer, 0, 0, GFP_NOWAIT);
 	spin_unlock_irq(&idr_lock);
-	if (error) {
-		if (error == -EAGAIN)
-			goto retry;
+	idr_preload_end();
+	if (error < 0) {
 		/*
 		 * Weird looking, but we return EAGAIN if the IDR is
 		 * full (proper POSIX return value for this)
 		 */
-		error = -EAGAIN;
+		if (error == -ENOSPC)
+			error = -EAGAIN;
 		goto out;
 	}
+	new_timer_id = error;
 
 	it_id_set = IT_ID_SET;
 	new_timer->it_id = (timer_t) new_timer_id;
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 74/77] net/9p: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (72 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 73/77] posix-timers: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 75/77] mac80211: " Tejun Heo
                   ` (3 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Eric Van Hensbergen, Ron Minnich,
	Latchesar Ionkov, v9fs-developer

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ron Minnich <rminnich@sandia.gov>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Cc: v9fs-developer@lists.sourceforge.net
---
 net/9p/util.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/net/9p/util.c b/net/9p/util.c
index 6ceeeb3..59f278e 100644
--- a/net/9p/util.c
+++ b/net/9p/util.c
@@ -87,23 +87,18 @@ EXPORT_SYMBOL(p9_idpool_destroy);
 
 int p9_idpool_get(struct p9_idpool *p)
 {
-	int i = 0;
-	int error;
+	int i;
 	unsigned long flags;
 
-retry:
-	if (idr_pre_get(&p->pool, GFP_NOFS) == 0)
-		return -1;
-
+	idr_preload(GFP_NOFS);
 	spin_lock_irqsave(&p->lock, flags);
 
 	/* no need to store exactly p, we just need something non-null */
-	error = idr_get_new(&p->pool, p, &i);
-	spin_unlock_irqrestore(&p->lock, flags);
+	i = idr_alloc(&p->pool, p, 0, 0, GFP_NOWAIT);
 
-	if (error == -EAGAIN)
-		goto retry;
-	else if (error)
+	spin_unlock_irqrestore(&p->lock, flags);
+	idr_preload_end();
+	if (i < 0)
 		return -1;
 
 	p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 75/77] mac80211: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (73 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 74/77] net/9p: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 19:40 ` [PATCH 76/77] sctp: " Tejun Heo
                   ` (2 subsequent siblings)
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, linux-wireless

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-wireless@vger.kernel.org
---
 net/mac80211/main.c |  2 --
 net/mac80211/tx.c   | 18 ++++--------------
 2 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 2bdd454..632f2a7 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -647,8 +647,6 @@ 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 a2cb6a3..5a62468 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1999,24 +1999,14 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 		skb = skb_clone(skb, GFP_ATOMIC);
 		if (skb) {
 			unsigned long flags;
-			int id, r;
+			int id;
 
 			spin_lock_irqsave(&local->ack_status_lock, flags);
-			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;
-			}
+			id = idr_alloc(&local->ack_status_frames, orig_skb,
+				       1, 0x10000, GFP_ATOMIC);
 			spin_unlock_irqrestore(&local->ack_status_lock, flags);
 
-			if (!r) {
+			if (id >= 0) {
 				info_id = id;
 				info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
 			} else if (skb_shared(skb)) {
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 76/77] sctp: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (74 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 75/77] mac80211: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-06 20:07   ` Vlad Yasevich
  2013-02-07 14:49   ` Neil Horman
  2013-02-06 19:40 ` [PATCH 77/77] nfs4client: " Tejun Heo
  2013-02-08  4:04 ` [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Dave Airlie
  77 siblings, 2 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm
  Cc: linux-kernel, Tejun Heo, Vlad Yasevich, Sridhar Samudrala, linux-sctp

Convert to the much saner new idr interface.

Only compile tested.

v2: Don't preload if @gfp doesn't contain __GFP_WAIT as the function
    may be being called from non-process ocntext.  Also, add a comment
    explaining @idr_low never becomes zero.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Sridhar Samudrala <sri@us.ibm.com>
Cc: linux-sctp@vger.kernel.org
---
 net/sctp/associola.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index b45ed1f..0c9a791 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1592,32 +1592,31 @@ 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)
 {
-	int assoc_id;
-	int error = 0;
+	bool preload = gfp & __GFP_WAIT;
+	int ret;
 
 	/* If the id is already assigned, keep it. */
 	if (asoc->assoc_id)
-		return error;
-retry:
-	if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
-		return -ENOMEM;
+		return 0;
 
+	if (preload)
+		idr_preload(gfp);
 	spin_lock_bh(&sctp_assocs_id_lock);
-	error = idr_get_new_above(&sctp_assocs_id, (void *)asoc,
-				    idr_low, &assoc_id);
-	if (!error) {
-		idr_low = assoc_id + 1;
+	/* 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;
 		if (idr_low == INT_MAX)
 			idr_low = 1;
 	}
 	spin_unlock_bh(&sctp_assocs_id_lock);
-	if (error == -EAGAIN)
-		goto retry;
-	else if (error)
-		return error;
+	if (preload)
+		idr_preload_end();
+	if (ret < 0)
+		return ret;
 
-	asoc->assoc_id = (sctp_assoc_t) assoc_id;
-	return error;
+	asoc->assoc_id = (sctp_assoc_t)ret;
+	return 0;
 }
 
 /* Free the ASCONF queue */
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 77/77] nfs4client: convert to idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (75 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 76/77] sctp: " Tejun Heo
@ 2013-02-06 19:40 ` Tejun Heo
  2013-02-08  4:04 ` [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Dave Airlie
  77 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 19:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Tejun Heo, Trond Myklebust, linux-nfs

Convert to the much saner new idr interface.

Only compile tested.

Signed-off-by: Tejun Heo <tj@kernel.org>

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: linux-nfs@vger.kernel.org
---
 fs/nfs/nfs4client.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 2e9779b..47d1008 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -29,15 +29,14 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
 
 	if (clp->rpc_ops->version != 4 || minorversion != 0)
 		return ret;
-retry:
-	if (!idr_pre_get(&nn->cb_ident_idr, GFP_KERNEL))
-		return -ENOMEM;
+	idr_preload(GFP_KERNEL);
 	spin_lock(&nn->nfs_client_lock);
-	ret = idr_get_new(&nn->cb_ident_idr, clp, &clp->cl_cb_ident);
+	ret = idr_alloc(&nn->cb_ident_idr, clp, 0, 0, GFP_NOWAIT);
+	if (ret >= 0)
+		clp->cl_cb_ident = ret;
 	spin_unlock(&nn->nfs_client_lock);
-	if (ret == -EAGAIN)
-		goto retry;
-	return ret;
+	idr_preload_end();
+	return ret < 0 ? ret : 0;
 }
 
 #ifdef CONFIG_NFS_V4_1
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* Re: [PATCH 76/77] sctp: convert to idr_alloc()
  2013-02-06 19:40 ` [PATCH 76/77] sctp: " Tejun Heo
@ 2013-02-06 20:07   ` Vlad Yasevich
  2013-02-07 14:49   ` Neil Horman
  1 sibling, 0 replies; 106+ messages in thread
From: Vlad Yasevich @ 2013-02-06 20:07 UTC (permalink / raw)
  To: Tejun Heo; +Cc: akpm, linux-kernel, Sridhar Samudrala, linux-sctp

On 02/06/2013 02:40 PM, Tejun Heo wrote:
> Convert to the much saner new idr interface.
>
> Only compile tested.
>
> v2: Don't preload if @gfp doesn't contain __GFP_WAIT as the function
>      may be being called from non-process ocntext.  Also, add a comment
>      explaining @idr_low never becomes zero.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Acked-by: Neil Horman <nhorman@tuxdriver.com>
> Cc: Vlad Yasevich <vyasevich@gmail.com>

Acked-by: Vlad Yasevich <vyasevich@gmail.com>

-vlad

> Cc: Sridhar Samudrala <sri@us.ibm.com>
> Cc: linux-sctp@vger.kernel.org
> ---
>   net/sctp/associola.c | 31 +++++++++++++++----------------
>   1 file changed, 15 insertions(+), 16 deletions(-)
>
> diff --git a/net/sctp/associola.c b/net/sctp/associola.c
> index b45ed1f..0c9a791 100644
> --- a/net/sctp/associola.c
> +++ b/net/sctp/associola.c
> @@ -1592,32 +1592,31 @@ 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)
>   {
> -	int assoc_id;
> -	int error = 0;
> +	bool preload = gfp & __GFP_WAIT;
> +	int ret;
>
>   	/* If the id is already assigned, keep it. */
>   	if (asoc->assoc_id)
> -		return error;
> -retry:
> -	if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
> -		return -ENOMEM;
> +		return 0;
>
> +	if (preload)
> +		idr_preload(gfp);
>   	spin_lock_bh(&sctp_assocs_id_lock);
> -	error = idr_get_new_above(&sctp_assocs_id, (void *)asoc,
> -				    idr_low, &assoc_id);
> -	if (!error) {
> -		idr_low = assoc_id + 1;
> +	/* 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;
>   		if (idr_low == INT_MAX)
>   			idr_low = 1;
>   	}
>   	spin_unlock_bh(&sctp_assocs_id_lock);
> -	if (error == -EAGAIN)
> -		goto retry;
> -	else if (error)
> -		return error;
> +	if (preload)
> +		idr_preload_end();
> +	if (ret < 0)
> +		return ret;
>
> -	asoc->assoc_id = (sctp_assoc_t) assoc_id;
> -	return error;
> +	asoc->assoc_id = (sctp_assoc_t)ret;
> +	return 0;
>   }
>
>   /* Free the ASCONF queue */
>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 21/77] block: fix synchronization and limit check in blk_alloc_devt()
  2013-02-06 19:39 ` [PATCH 21/77] block: fix synchronization and limit check in blk_alloc_devt() Tejun Heo
@ 2013-02-06 22:24   ` Andrew Morton
  2013-02-06 22:27     ` Tejun Heo
  0 siblings, 1 reply; 106+ messages in thread
From: Andrew Morton @ 2013-02-06 22:24 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel, stable, Tomas Henzl

On Wed,  6 Feb 2013 11:39:53 -0800
Tejun Heo <tj@kernel.org> wrote:

> idr allocation in blk_alloc_devt() wasn't synchronized against lookup
> and removal, and its limit check was off by one - 1 << MINORBITS is
> the number of minors allowed, not the maximum allowed minor.
> 
> Add locking and rename MAX_EXT_DEVT to NR_EXT_DEVT and fix limit
> checking.
> 
> ...
>
> --- a/block/genhd.c
> +++ b/block/genhd.c
> @@ -26,7 +26,7 @@ static DEFINE_MUTEX(block_class_lock);
>  struct kobject *block_depr;
>  
>  /* for extended dynamic devt allocation, currently only one major is used */
> -#define MAX_EXT_DEVT		(1 << MINORBITS)
> +#define NR_EXT_DEVT		(1 << MINORBITS)
>  
>  /* For extended devt allocation.  ext_devt_mutex prevents look up
>   * results from going away underneath its user.
> @@ -423,17 +423,18 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
>  	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;
>  
> -	if (idx > MAX_EXT_DEVT) {
> -		idr_remove(&ext_devt_idr, idx);
> -		return -EBUSY;
> -	}
> -
>  	*devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
>  	return 0;
>  }

This gets all tangled up with
http://ozlabs.org/~akpm/mmotm/broken-out/block-fix-ext_devt_idr-handling.patch,
which appears to solve the same issue.

What to do?


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 21/77] block: fix synchronization and limit check in blk_alloc_devt()
  2013-02-06 22:24   ` Andrew Morton
@ 2013-02-06 22:27     ` Tejun Heo
  2013-02-06 22:32       ` Andrew Morton
  0 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 22:27 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, stable, Tomas Henzl

Hello, Andrew.

On Wed, Feb 06, 2013 at 02:24:22PM -0800, Andrew Morton wrote:
> This gets all tangled up with
> http://ozlabs.org/~akpm/mmotm/broken-out/block-fix-ext_devt_idr-handling.patch,
> which appears to solve the same issue.
> 
> What to do?

Can you please drop 21 and 22?  Everything else shouldn't be affected
and we can sort these out later.  The actual deprecation patch is held
off for now anyway.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 21/77] block: fix synchronization and limit check in blk_alloc_devt()
  2013-02-06 22:27     ` Tejun Heo
@ 2013-02-06 22:32       ` Andrew Morton
  2013-02-06 22:33         ` Tejun Heo
  0 siblings, 1 reply; 106+ messages in thread
From: Andrew Morton @ 2013-02-06 22:32 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel, stable, Tomas Henzl

On Wed, 6 Feb 2013 14:27:55 -0800
Tejun Heo <tj@kernel.org> wrote:

> Hello, Andrew.
> 
> On Wed, Feb 06, 2013 at 02:24:22PM -0800, Andrew Morton wrote:
> > This gets all tangled up with
> > http://ozlabs.org/~akpm/mmotm/broken-out/block-fix-ext_devt_idr-handling.patch,
> > which appears to solve the same issue.
> > 
> > What to do?
> 
> Can you please drop 21 and 22?  Everything else shouldn't be affected
> and we can sort these out later.  The actual deprecation patch is held
> off for now anyway.

hm, I could.  Instead I merged your patch on top of Tomas's and marked
Tomas's patch for -stable as well.  Sound OK?


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 21/77] block: fix synchronization and limit check in blk_alloc_devt()
  2013-02-06 22:32       ` Andrew Morton
@ 2013-02-06 22:33         ` Tejun Heo
  0 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-06 22:33 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, stable, Tomas Henzl

Hello,

On Wed, Feb 6, 2013 at 2:32 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
>> Can you please drop 21 and 22?  Everything else shouldn't be affected
>> and we can sort these out later.  The actual deprecation patch is held
>> off for now anyway.
>
> hm, I could.  Instead I merged your patch on top of Tomas's and marked
> Tomas's patch for -stable as well.  Sound OK?

Sure, less work for me. :)

-- 
tejun

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 14/77] cgroup: don't use idr_remove_all()
  2013-02-06 19:39 ` [PATCH 14/77] cgroup: " Tejun Heo
@ 2013-02-07  1:29   ` Li Zefan
  0 siblings, 0 replies; 106+ messages in thread
From: Li Zefan @ 2013-02-07  1:29 UTC (permalink / raw)
  To: Tejun Heo; +Cc: akpm, linux-kernel, containers, cgroups

On 2013/2/7 3:39, Tejun Heo wrote:
> idr_destroy() can destroy idr by itself and idr_remove_all() is being
> deprecated.  Drop its usage.
> 
> Signed-off-by: Tejun Heo <tj@kernel.org>

Acked-by: Li Zefan <lizefan@huawei.com>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 76/77] sctp: convert to idr_alloc()
  2013-02-06 19:40 ` [PATCH 76/77] sctp: " Tejun Heo
  2013-02-06 20:07   ` Vlad Yasevich
@ 2013-02-07 14:49   ` Neil Horman
  1 sibling, 0 replies; 106+ messages in thread
From: Neil Horman @ 2013-02-07 14:49 UTC (permalink / raw)
  To: Tejun Heo
  Cc: akpm, linux-kernel, Vlad Yasevich, Sridhar Samudrala, linux-sctp

On Wed, Feb 06, 2013 at 11:40:48AM -0800, Tejun Heo wrote:
> Convert to the much saner new idr interface.
> 
> Only compile tested.
> 
> v2: Don't preload if @gfp doesn't contain __GFP_WAIT as the function
>     may be being called from non-process ocntext.  Also, add a comment
>     explaining @idr_low never becomes zero.
> 
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Acked-by: Neil Horman <nhorman@tuxdriver.com>
> Cc: Vlad Yasevich <vyasevich@gmail.com>
> Cc: Sridhar Samudrala <sri@us.ibm.com>
> Cc: linux-sctp@vger.kernel.org
> ---
>  net/sctp/associola.c | 31 +++++++++++++++----------------
>  1 file changed, 15 insertions(+), 16 deletions(-)
> 
> diff --git a/net/sctp/associola.c b/net/sctp/associola.c
> index b45ed1f..0c9a791 100644
> --- a/net/sctp/associola.c
> +++ b/net/sctp/associola.c
> @@ -1592,32 +1592,31 @@ 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)
>  {
> -	int assoc_id;
> -	int error = 0;
> +	bool preload = gfp & __GFP_WAIT;
> +	int ret;
>  
>  	/* If the id is already assigned, keep it. */
>  	if (asoc->assoc_id)
> -		return error;
> -retry:
> -	if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
> -		return -ENOMEM;
> +		return 0;
>  
> +	if (preload)
> +		idr_preload(gfp);
>  	spin_lock_bh(&sctp_assocs_id_lock);
> -	error = idr_get_new_above(&sctp_assocs_id, (void *)asoc,
> -				    idr_low, &assoc_id);
> -	if (!error) {
> -		idr_low = assoc_id + 1;
> +	/* 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;
>  		if (idr_low == INT_MAX)
>  			idr_low = 1;
>  	}
>  	spin_unlock_bh(&sctp_assocs_id_lock);
> -	if (error == -EAGAIN)
> -		goto retry;
> -	else if (error)
> -		return error;
> +	if (preload)
> +		idr_preload_end();
> +	if (ret < 0)
> +		return ret;
>  
> -	asoc->assoc_id = (sctp_assoc_t) assoc_id;
> -	return error;
> +	asoc->assoc_id = (sctp_assoc_t)ret;
> +	return 0;
>  }
>  
>  /* Free the ASCONF queue */
> -- 
> 1.8.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
Acked-by: Neil Horman <nhorman@tuxdriver.com>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 37/77] i2c: convert to idr_alloc()
  2013-02-06 19:40 ` [PATCH 37/77] i2c: " Tejun Heo
@ 2013-02-07 15:28   ` Mark Brown
  2013-02-07 16:32     ` Tejun Heo
  0 siblings, 1 reply; 106+ messages in thread
From: Mark Brown @ 2013-02-07 15:28 UTC (permalink / raw)
  To: Tejun Heo; +Cc: akpm, linux-kernel, Jean Delvare, linux-i2c

On Wed, Feb 06, 2013 at 11:40:09AM -0800, Tejun Heo wrote:
> Convert to the much saner new idr interface.
> 
> Only compile tested.

This broke I2C for me in -next today, I saw a spinlock bad magic error
calling pm_runtime_enable().  

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 37/77] i2c: convert to idr_alloc()
  2013-02-07 15:28   ` Mark Brown
@ 2013-02-07 16:32     ` Tejun Heo
  2013-02-07 16:39       ` Mark Brown
  0 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-07 16:32 UTC (permalink / raw)
  To: Mark Brown; +Cc: akpm, linux-kernel, Jean Delvare, linux-i2c

Hello,

On Thu, Feb 07, 2013 at 03:28:31PM +0000, Mark Brown wrote:
> On Wed, Feb 06, 2013 at 11:40:09AM -0800, Tejun Heo wrote:
> > Convert to the much saner new idr interface.
> > 
> > Only compile tested.
> 
> This broke I2C for me in -next today, I saw a spinlock bad magic error
> calling pm_runtime_enable().  

Hmmm... weird, can't see where the difference in behavior would come
from.  The only material difference would be if id < 0 && id != -1 in
i2c_add_numbered_adapter(), which now would trigger WARN_ON_ONCE()
inside idr_alloc() instead of silently returning -EINVAL.

Can you please elaborate the failure?  I can't see how the idr
conversion would lead to spinlock bad magic error.  Does reverting
this patch make the problem go away?

Thanks.

--
tejun

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 37/77] i2c: convert to idr_alloc()
  2013-02-07 16:32     ` Tejun Heo
@ 2013-02-07 16:39       ` Mark Brown
  2013-02-07 16:55         ` [PATCH v2] " Tejun Heo
  0 siblings, 1 reply; 106+ messages in thread
From: Mark Brown @ 2013-02-07 16:39 UTC (permalink / raw)
  To: Tejun Heo; +Cc: akpm, linux-kernel, Jean Delvare, linux-i2c

[-- Attachment #1: Type: text/plain, Size: 1072 bytes --]

On Thu, Feb 07, 2013 at 08:32:47AM -0800, Tejun Heo wrote:
> On Thu, Feb 07, 2013 at 03:28:31PM +0000, Mark Brown wrote:
> > On Wed, Feb 06, 2013 at 11:40:09AM -0800, Tejun Heo wrote:
> > > Convert to the much saner new idr interface.

> > > Only compile tested.

> > This broke I2C for me in -next today, I saw a spinlock bad magic error
> > calling pm_runtime_enable().  

> Hmmm... weird, can't see where the difference in behavior would come
> from.  The only material difference would be if id < 0 && id != -1 in
> i2c_add_numbered_adapter(), which now would trigger WARN_ON_ONCE()
> inside idr_alloc() instead of silently returning -EINVAL.

> Can you please elaborate the failure?  I can't see how the idr
> conversion would lead to spinlock bad magic error.  Does reverting
> this patch make the problem go away?

Yes, reverting the patch made the issue vanish.  I've no more
diagnostics I'm afraid, just a 10s timeout then bad magic - it looks
like memory corruption.  I'll try to find time to dig in more but not
sure when that'll happen.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH v2] i2c: convert to idr_alloc()
  2013-02-07 16:39       ` Mark Brown
@ 2013-02-07 16:55         ` Tejun Heo
  2013-02-07 18:52           ` Mark Brown
                             ` (2 more replies)
  0 siblings, 3 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-07 16:55 UTC (permalink / raw)
  To: Mark Brown; +Cc: akpm, linux-kernel, Jean Delvare, linux-i2c

Convert to the much saner new idr interface.

Only compile tested.

v2: The original conversion accidentally dropped a call to
    i2c_register_adapter() in i2c_add_numbered_adapter() leaving @adap
    uninitialized and unregistered.  Reported by Mark Brown.  Fix it.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: linux-i2c@vger.kernel.org
---
Heh, this is embarrassing.  I got too focused on the id allocation
itself and missed moving i2c_register_adapter() call.

I think this should fix the problem you're seeing.  Can you please
test this?

Thank you.

 drivers/i2c/i2c-core.c |   43 ++++++++++---------------------------------
 1 file changed, 10 insertions(+), 33 deletions(-)

--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -935,25 +935,16 @@ out_list:
  */
 int i2c_add_adapter(struct i2c_adapter *adapter)
 {
-	int	id, res = 0;
-
-retry:
-	if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
-		return -ENOMEM;
+	int res;
 
 	mutex_lock(&core_lock);
-	/* "above" here means "above or equal to", sigh */
-	res = idr_get_new_above(&i2c_adapter_idr, adapter,
-				__i2c_first_dynamic_bus_num, &id);
+	res = idr_alloc(&i2c_adapter_idr, adapter,
+			__i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
 	mutex_unlock(&core_lock);
-
-	if (res < 0) {
-		if (res == -EAGAIN)
-			goto retry;
+	if (res < 0)
 		return res;
-	}
 
-	adapter->nr = id;
+	adapter->nr = res;
 	return i2c_register_adapter(adapter);
 }
 EXPORT_SYMBOL(i2c_add_adapter);
@@ -984,33 +975,19 @@ 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);
-	/* "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);
-	}
+	id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,
+		       GFP_KERNEL);
 	mutex_unlock(&core_lock);
-	if (status == -EAGAIN)
-		goto retry;
-
-	if (status == 0)
-		status = i2c_register_adapter(adap);
-	return status;
+	if (id < 0)
+		return id == -ENOSPC ? -EBUSY : id;
+	return i2c_register_adapter(adap);
 }
 EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 22.5/77] block/loop: fix error return value in loop_add()
  2013-02-06 19:39 ` [PATCH 23/77] block/loop: " Tejun Heo
@ 2013-02-07 18:25   ` Tejun Heo
  2013-02-07 18:26   ` [PATCH v2 23/77] block/loop: convert to idr_alloc() Tejun Heo
  1 sibling, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-07 18:25 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

If queue or disk allocation fails, loop_add() returns @err, which is
cleared to zero by idr allocation by that point.  Reset @err to
-ENOMEM before the allocations so that we return -ENOMEM instead of 0
on alloc failure.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: stable@vger.kernel.org
---
Hey, guys.

I was going through the conversions one more time and noticed this
existing bug.  We're returning 0 on alloc failure.  It seems the worst
which can come out of this is userland misled to believe a loop device
has been created when in fact it failed.  This can be routed
separately but it probably is easier to route with other changes.

Thanks!

 drivers/block/loop.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1649,6 +1649,7 @@ static int loop_add(struct loop_device *
 	if (err < 0)
 		goto out_free_dev;
 
+	err = -ENOMEM;
 	lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
 	if (!lo->lo_queue)
 		goto out_free_dev;

^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH v2 23/77] block/loop: convert to idr_alloc()
  2013-02-06 19:39 ` [PATCH 23/77] block/loop: " Tejun Heo
  2013-02-07 18:25   ` [PATCH 22.5/77] block/loop: fix error return value in loop_add() Tejun Heo
@ 2013-02-07 18:26   ` Tejun Heo
  1 sibling, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-07 18:26 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

Subject: block/loop: convert to idr_alloc()

Convert to the much saner new idr interface.

v2: loop_add() treats -1 @i as request for any free ID while any other
    negative trigger -EINVAL.  The v1 conversion treated any negative
    number as valid request for any free ID.  While this doesn't make
    any difference for in-kernel users, loop_add() is almost directly
    visible to userland via LOOP_CTL_ADD and this behavior change is
    userland-visible.  Restore -EINVAL on < -1.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Jens Axboe <axboe@kernel.dk>
---
Another mistake I noticed while auditing the conversions again.  I
don't think this would actually affect anybody but no reason to change
the behavior.

Thanks.

 drivers/block/loop.c |   21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1624,30 +1624,19 @@ static int loop_add(struct loop_device *
 	if (!lo)
 		goto out;
 
-	if (!idr_pre_get(&loop_index_idr, GFP_KERNEL))
-		goto out_free_dev;
-
+	/* allocate id, if @id >= 0, we're requesting that specific id */
 	if (i >= 0) {
-		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 = idr_alloc(&loop_index_idr, lo, i, i + 1, GFP_KERNEL);
+		if (err == -ENOSPC)
 			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;
+		err = idr_alloc(&loop_index_idr, lo, 0, 0, GFP_KERNEL);
 	} else {
 		err = -EINVAL;
 	}
 	if (err < 0)
 		goto out_free_dev;
+	i = err;
 
 	err = -ENOMEM;
 	lo->lo_queue = blk_alloc_queue(GFP_KERNEL);

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2] i2c: convert to idr_alloc()
  2013-02-07 16:55         ` [PATCH v2] " Tejun Heo
@ 2013-02-07 18:52           ` Mark Brown
  2013-02-08 12:10           ` Mark Brown
  2013-02-10 11:47           ` Wolfram Sang
  2 siblings, 0 replies; 106+ messages in thread
From: Mark Brown @ 2013-02-07 18:52 UTC (permalink / raw)
  To: Tejun Heo; +Cc: akpm, linux-kernel, Jean Delvare, linux-i2c

[-- Attachment #1: Type: text/plain, Size: 325 bytes --]

On Thu, Feb 07, 2013 at 08:55:47AM -0800, Tejun Heo wrote:

> Heh, this is embarrassing.  I got too focused on the id allocation
> itself and missed moving i2c_register_adapter() call.

> I think this should fix the problem you're seeing.  Can you please
> test this?

Oops :) I'll test this tomorrow, out of time for today.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH v2 70/77] ipc: convert to idr_alloc()
  2013-02-06 19:40 ` [PATCH 70/77] ipc: " Tejun Heo
@ 2013-02-07 19:43   ` Tejun Heo
  0 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-07 19:43 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Stanislav Kinsbursky, Eric W. Biederman, James Morris

Convert to the much saner new idr interface.

The new interface doesn't directly translate to the way idr_pre_get()
was used around ipc_addid() as preloading disables preemption.  From
my cursory reading, it seems like we should be able to do all
allocation from ipc_addid(), so I moved it there.  Can you please
check whether this would be okay?  If this is wrong and ipc_addid()
should be allowed to be called from non-sleepable context, I'd suggest
allocating id itself in the outer functions and later install the
pointer using idr_replace().

Only compile tested.

v2: The v1 conversion of ipcget_public() was incorrect.  As
    idr_pre_get() returns 0 for -ENOMEM failure, @err should have been
    initialized to 1 not 0.  As the function doesn't do preloading
    itself anymore, there's no point in the error handling path.
    Simply remove the -ENOMEM path.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Sedat Dilek <sedat.dilek@gmail.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Stanislav Kinsbursky <skinsbursky@parallels.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: James Morris <jmorris@namei.org>
---
 ipc/util.c |   30 +++++++++---------------------
 1 file changed, 9 insertions(+), 21 deletions(-)

--- a/ipc/util.c
+++ b/ipc/util.c
@@ -252,7 +252,7 @@ int ipc_addid(struct ipc_ids* ids, struc
 {
 	kuid_t euid;
 	kgid_t egid;
-	int id, err;
+	int id;
 	int next_id = ids->next_id;
 
 	if (size > IPCMNI)
@@ -261,17 +261,21 @@ int ipc_addid(struct ipc_ids* ids, struc
 	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);
 
-	err = idr_get_new_above(&ids->ipcs_idr, new,
-				(next_id < 0) ? 0 : ipcid_to_idx(next_id), &id);
-	if (err) {
+	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) {
 		spin_unlock(&new->lock);
 		rcu_read_unlock();
-		return err;
+		return id;
 	}
 
 	ids->in_use++;
@@ -307,19 +311,10 @@ static int ipcget_new(struct ipc_namespa
 		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;
 }
 
@@ -376,8 +371,6 @@ static int ipcget_public(struct ipc_name
 	struct kern_ipc_perm *ipcp;
 	int flg = params->flg;
 	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
@@ -389,8 +382,6 @@ retry:
 		/* key not used */
 		if (!(flg & IPC_CREAT))
 			err = -ENOENT;
-		else if (!err)
-			err = -ENOMEM;
 		else
 			err = ops->getnew(ns, params);
 	} else {
@@ -413,9 +404,6 @@ retry:
 	}
 	up_write(&ids->rw_mutex);
 
-	if (err == -EAGAIN)
-		goto retry;
-
 	return err;
 }
 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH v3 20/77] idr: implement idr_preload[_end]() and idr_alloc()
  2013-02-06 19:39 ` [PATCH 20/77] idr: implement idr_preload[_end]() and idr_alloc() Tejun Heo
@ 2013-02-07 19:53   ` Tejun Heo
  0 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-07 19:53 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Rusty Russell

The current idr interface is very cumbersome.

* For all allocations, two function calls - idr_pre_get() and
  idr_get_new*() - should be made.

* idr_pre_get() doesn't guarantee that the following idr_get_new*()
  will not fail from memory shortage.  If idr_get_new*() returns
  -EAGAIN, the caller is expected to retry pre_get and allocation.

* idr_get_new*() can't enforce upper limit.  Upper limit can only be
  enforced by allocating and then freeing if above limit.

* idr_layer buffer is unnecessarily per-idr.  Each idr ends up keeping
  around MAX_IDR_FREE idr_layers.  The memory consumed per idr is
  under two pages but it makes it difficult to make idr_layer larger.

This patch implements the following new set of allocation functions.

* idr_preload[_end]() - Similar to radix preload but doesn't fail.
  The first idr_alloc() inside preload section can be treated as if it
  were called with @gfp_mask used for idr_preload().

* idr_alloc() - Allocate an ID w/ lower and upper limits.  Takes
  @gfp_flags and can be used w/o preloading.  When used inside
  preloaded section, the allocation mask of preloading can be assumed.

If idr_alloc() can be called from a context which allows sufficiently
relaxed @gfp_mask, it can be used by itself.  If, for example,
idr_alloc() is called inside spinlock protected region, preloading can
be used like the following.

	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;

which is much simpler and less error-prone than idr_pre_get and
idr_get_new*() loop.

The new interface uses per-pcu idr_layer buffer and thus the number of
idr's in the system doesn't affect the amount of memory used for
preloading.

idr_layer_alloc() is introduced to handle idr_layer allocations for
both old and new ID allocation paths.  This is a bit hairy now but the
new interface is expected to replace the old and the internal
implementation eventually will become simpler.

v2: Improve idr_preload() comment a bit so that it's clear that
    preemption is disabled while preloaded.  Make idr_layer_alloc()
    try kmem_cache first and then fall back to per-cpu buffer;
    otherwise, non-preloading idr_alloc()s empty per-cpu buffers
    makeing preloaders fill them, which, while not incorrect, still is
    a bit unfair.

v3: In idr_alloc() treat @end <= 0 as indicating max.  This is
    necessary to always allow using @start + N as @end for a positive
    integer N.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
---
Another smallish update to allow negative @end so that people can
specify [@id, @id + 1) range without worrying about the latter
overflowing.

Thanks.

 include/linux/idr.h |   14 ++++
 lib/idr.c           |  174 +++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 180 insertions(+), 8 deletions(-)

--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -94,15 +94,29 @@ 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
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -35,8 +35,12 @@
 #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)
@@ -54,6 +58,50 @@ static struct idr_layer *get_from_free_l
 	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;
@@ -139,6 +187,8 @@ 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
@@ -148,7 +198,8 @@ 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)
+static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa,
+		     gfp_t gfp_mask, struct idr *layer_idr)
 {
 	int n, m, sh;
 	struct idr_layer *p, *new;
@@ -202,7 +253,7 @@ static int sub_alloc(struct idr *idp, in
 		 * Create the layer below if it is missing.
 		 */
 		if (!p->ary[m]) {
-			new = get_from_free_list(idp);
+			new = idr_layer_alloc(gfp_mask, layer_idr);
 			if (!new)
 				return -ENOMEM;
 			new->layer = l-1;
@@ -218,7 +269,8 @@ static int sub_alloc(struct idr *idp, in
 }
 
 static int idr_get_empty_slot(struct idr *idp, int starting_id,
-			      struct idr_layer **pa)
+			      struct idr_layer **pa, gfp_t gfp_mask,
+			      struct idr *layer_idr)
 {
 	struct idr_layer *p, *new;
 	int layers, v, id;
@@ -229,7 +281,7 @@ build_up:
 	p = idp->top;
 	layers = idp->layers;
 	if (unlikely(!p)) {
-		if (!(p = get_from_free_list(idp)))
+		if (!(p = idr_layer_alloc(gfp_mask, layer_idr)))
 			return -ENOMEM;
 		p->layer = 0;
 		layers = 1;
@@ -248,7 +300,7 @@ build_up:
 			p->layer++;
 			continue;
 		}
-		if (!(new = get_from_free_list(idp))) {
+		if (!(new = idr_layer_alloc(gfp_mask, layer_idr))) {
 			/*
 			 * The allocation failed.  If we built part of
 			 * the structure tear it down.
@@ -272,7 +324,7 @@ build_up:
 	}
 	rcu_assign_pointer(idp->top, p);
 	idp->layers = layers;
-	v = sub_alloc(idp, &id, pa);
+	v = sub_alloc(idp, &id, pa, gfp_mask, layer_idr);
 	if (v == -EAGAIN)
 		goto build_up;
 	return(v);
@@ -312,7 +364,7 @@ int idr_get_new_above(struct idr *idp, v
 	struct idr_layer *pa[MAX_IDR_LEVEL];
 	int rv;
 
-	rv = idr_get_empty_slot(idp, starting_id, pa);
+	rv = idr_get_empty_slot(idp, starting_id, pa, 0, idp);
 	if (rv < 0)
 		return rv == -ENOMEM ? -EAGAIN : rv;
 
@@ -322,6 +374,112 @@ int idr_get_new_above(struct idr *idp, v
 }
 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.
+ *
+ * Note that @end is treated as max when <= 0.  This is to always allow
+ * using @start + N as @end as long as N is inside integer range.
+ *
+ * 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 > 0 ? 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))
+		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
@@ -769,7 +927,7 @@ int ida_get_new_above(struct ida *ida, i
 
  restart:
 	/* get vacant slot */
-	t = idr_get_empty_slot(&ida->idr, idr_id, pa);
+	t = idr_get_empty_slot(&ida->idr, idr_id, pa, 0, &ida->idr);
 	if (t < 0)
 		return t == -ENOMEM ? -EAGAIN : t;
 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc()
  2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
                   ` (76 preceding siblings ...)
  2013-02-06 19:40 ` [PATCH 77/77] nfs4client: " Tejun Heo
@ 2013-02-08  4:04 ` Dave Airlie
  77 siblings, 0 replies; 106+ messages in thread
From: Dave Airlie @ 2013-02-08  4:04 UTC (permalink / raw)
  To: Tejun Heo; +Cc: akpm, linux-kernel

On Thu, Feb 7, 2013 at 5:39 AM, Tejun Heo <tj@kernel.org> wrote:
> (If you're reading this patchset for the first time, this patchset is
>  an effort to improve idr interface.  This posting is mostly for
>  collecting and routing the patches towards -mm.  Please follow the
>  link at the end for details on each patchset.)
>
> Hello, Andrew.
>
> This patchset is combination of the following three on top of
> linux-next as of 20130204 (the one before idr_removal_all() got
> included).

just FYI, all the drm bits are

Acked-by: Dave Airlie <airlied@redhat.com>

Don't worry about attaching that to the patches though :-)

Dave.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2] i2c: convert to idr_alloc()
  2013-02-07 16:55         ` [PATCH v2] " Tejun Heo
  2013-02-07 18:52           ` Mark Brown
@ 2013-02-08 12:10           ` Mark Brown
  2013-02-10 11:47           ` Wolfram Sang
  2 siblings, 0 replies; 106+ messages in thread
From: Mark Brown @ 2013-02-08 12:10 UTC (permalink / raw)
  To: Tejun Heo; +Cc: akpm, linux-kernel, Jean Delvare, linux-i2c

[-- Attachment #1: Type: text/plain, Size: 210 bytes --]

On Thu, Feb 07, 2013 at 08:55:47AM -0800, Tejun Heo wrote:
> Convert to the much saner new idr interface.
> 
> Only compile tested.

Tested-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

Thanks!

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2] i2c: convert to idr_alloc()
  2013-02-07 16:55         ` [PATCH v2] " Tejun Heo
  2013-02-07 18:52           ` Mark Brown
  2013-02-08 12:10           ` Mark Brown
@ 2013-02-10 11:47           ` Wolfram Sang
  2013-02-12 17:34             ` [PATCH -mm] i2c: style cleanups after idr_alloc() conversion Tejun Heo
  2 siblings, 1 reply; 106+ messages in thread
From: Wolfram Sang @ 2013-02-10 11:47 UTC (permalink / raw)
  To: Tejun Heo; +Cc: Mark Brown, akpm, linux-kernel, Jean Delvare, linux-i2c

Hi,

thanks for doing this cleanup series. Looks very worthwhile!

> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -935,25 +935,16 @@ out_list:
>   */
>  int i2c_add_adapter(struct i2c_adapter *adapter)
>  {
> -	int	id, res = 0;
> -
> -retry:
> -	if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
> -		return -ENOMEM;
> +	int res;

I'd vote for using 'id' as the variable name here. Feels more logical to
me and you are using 'id' in the other block, too.

> @@ -984,33 +975,19 @@ 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);
> -	/* "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);
> -	}
> +	id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,
> +		       GFP_KERNEL);
>  	mutex_unlock(&core_lock);
> -	if (status == -EAGAIN)
> -		goto retry;
> -
> -	if (status == 0)
> -		status = i2c_register_adapter(adap);
> -	return status;
> +	if (id < 0)
> +		return id == -ENOSPC ? -EBUSY : id;
> +	return i2c_register_adapter(adap);

Add an empty line before the return statement?

Thanks,

   Wolfram


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 63/77] scsi/lpfc: convert to idr_alloc()
  2013-02-06 19:40 ` [PATCH 63/77] scsi/lpfc: " Tejun Heo
@ 2013-02-11 22:47   ` James Smart
  0 siblings, 0 replies; 106+ messages in thread
From: James Smart @ 2013-02-11 22:47 UTC (permalink / raw)
  To: Tejun Heo; +Cc: akpm, linux-kernel, linux-scsi

Acked-by: James Smart <james.smart@emulex.com>

-- james s


On 2/6/2013 2:40 PM, Tejun Heo wrote:
> Convert to the much saner new idr interface.
>
> Only compile tested.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Cc: James Smart <james.smart@emulex.com>
> Cc: linux-scsi@vger.kernel.org
> ---
>   drivers/scsi/lpfc/lpfc_init.c | 12 ++++--------
>   1 file changed, 4 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
> index 26ca2ef..314b4f6 100644
> --- a/drivers/scsi/lpfc/lpfc_init.c
> +++ b/drivers/scsi/lpfc/lpfc_init.c
> @@ -3165,14 +3165,10 @@ destroy_port(struct lpfc_vport *vport)
>   int
>   lpfc_get_instance(void)
>   {
> -	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;
> +	int ret;
> +
> +	ret = idr_alloc(&lpfc_hba_index, NULL, 0, 0, GFP_KERNEL);
> +	return ret < 0 ? -1 : ret;
>   }
>   
>   /**


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH -mm] i2c: style cleanups after idr_alloc() conversion
  2013-02-10 11:47           ` Wolfram Sang
@ 2013-02-12 17:34             ` Tejun Heo
  2013-02-12 17:36               ` Tejun Heo
  2013-02-13 20:42               ` Wolfram Sang
  0 siblings, 2 replies; 106+ messages in thread
From: Tejun Heo @ 2013-02-12 17:34 UTC (permalink / raw)
  To: Wolfram Sang, akpm; +Cc: Mark Brown, linux-kernel, Jean Delvare, linux-i2c

Style cleanups suggested by Wolfram.

* s/res/id/ in i2c_add_numbered_adapter() so that it matches
  i2c_add_adapter().

* Add a blank line before return in i2c_add_numbered_adapter().

This patch is purely cosmetic.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Wolfram Sang <w.sang@pengutronix.de>
---
 drivers/i2c/i2c-core.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -935,16 +935,17 @@ out_list:
  */
 int i2c_add_adapter(struct i2c_adapter *adapter)
 {
-	int res;
+	int id;
 
 	mutex_lock(&core_lock);
-	res = idr_alloc(&i2c_adapter_idr, adapter,
-			__i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
+	id = idr_alloc(&i2c_adapter_idr, adapter,
+		       __i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
 	mutex_unlock(&core_lock);
-	if (res < 0)
-		return res;
+	if (id < 0)
+		return id;
+
+	adapter->nr = id;
 
-	adapter->nr = res;
 	return i2c_register_adapter(adapter);
 }
 EXPORT_SYMBOL(i2c_add_adapter);

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH -mm] i2c: style cleanups after idr_alloc() conversion
  2013-02-12 17:34             ` [PATCH -mm] i2c: style cleanups after idr_alloc() conversion Tejun Heo
@ 2013-02-12 17:36               ` Tejun Heo
  2013-02-12 18:00                 ` Jean Delvare
  2013-02-13 20:42               ` Wolfram Sang
  1 sibling, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-02-12 17:36 UTC (permalink / raw)
  To: Wolfram Sang, akpm; +Cc: Mark Brown, linux-kernel, Jean Delvare, linux-i2c

On Tue, Feb 12, 2013 at 09:34:14AM -0800, Tejun Heo wrote:
> Style cleanups suggested by Wolfram.
> 
> * s/res/id/ in i2c_add_numbered_adapter() so that it matches
>   i2c_add_adapter().
> 
> * Add a blank line before return in i2c_add_numbered_adapter().
> 
> This patch is purely cosmetic.
> 
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Cc: Wolfram Sang <w.sang@pengutronix.de>

JFYI, got a permanent delivery failure for w.sang@pengutronix.de.
Does anyone in i2c circle know other contact points?  If so, please
ping him about it.

Thanks!

-- 
tejun

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH -mm] i2c: style cleanups after idr_alloc() conversion
  2013-02-12 17:36               ` Tejun Heo
@ 2013-02-12 18:00                 ` Jean Delvare
  0 siblings, 0 replies; 106+ messages in thread
From: Jean Delvare @ 2013-02-12 18:00 UTC (permalink / raw)
  To: Tejun Heo; +Cc: Wolfram Sang, akpm, Mark Brown, linux-kernel, linux-i2c

On Tue, 12 Feb 2013 09:36:48 -0800, Tejun Heo wrote:
> On Tue, Feb 12, 2013 at 09:34:14AM -0800, Tejun Heo wrote:
> > Style cleanups suggested by Wolfram.
> > 
> > * s/res/id/ in i2c_add_numbered_adapter() so that it matches
> >   i2c_add_adapter().
> > 
> > * Add a blank line before return in i2c_add_numbered_adapter().
> > 
> > This patch is purely cosmetic.
> > 
> > Signed-off-by: Tejun Heo <tj@kernel.org>
> > Cc: Wolfram Sang <w.sang@pengutronix.de>
> 
> JFYI, got a permanent delivery failure for w.sang@pengutronix.de.
> Does anyone in i2c circle know other contact points?  If so, please
> ping him about it.

See the updated Cc list :)

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH -mm] i2c: style cleanups after idr_alloc() conversion
  2013-02-12 17:34             ` [PATCH -mm] i2c: style cleanups after idr_alloc() conversion Tejun Heo
  2013-02-12 17:36               ` Tejun Heo
@ 2013-02-13 20:42               ` Wolfram Sang
  1 sibling, 0 replies; 106+ messages in thread
From: Wolfram Sang @ 2013-02-13 20:42 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Wolfram Sang, akpm, Mark Brown, linux-kernel, Jean Delvare, linux-i2c

On Tue, Feb 12, 2013 at 09:34:14AM -0800, Tejun Heo wrote:
> Style cleanups suggested by Wolfram.
> 
> * s/res/id/ in i2c_add_numbered_adapter() so that it matches
>   i2c_add_adapter().
> 
> * Add a blank line before return in i2c_add_numbered_adapter().
> 
> This patch is purely cosmetic.
> 
> Signed-off-by: Tejun Heo <tj@kernel.org>

Acked-by: Wolfram Sang <wolfram@the-dreams.de>

Would be nice to fold this patch into the previous one, if possible.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 67/77] dlm: convert to idr_alloc()
  2013-02-06 19:40 ` [PATCH 67/77] dlm: " Tejun Heo
@ 2013-03-11 19:29   ` David Teigland
  2013-03-11 20:28     ` Tejun Heo
  0 siblings, 1 reply; 106+ messages in thread
From: David Teigland @ 2013-03-11 19:29 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel

On Wed, Feb 06, 2013 at 11:40:39AM -0800, Tejun Heo wrote:
>  static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
>  {
>  	struct dlm_lkb *lkb;
> -	int rv, id;
> +	int rv;
>  
>  	lkb = dlm_allocate_lkb(ls);
>  	if (!lkb)
> @@ -1199,19 +1199,13 @@ 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);
>  
> - retry:
> -	rv = idr_pre_get(&ls->ls_lkbidr, GFP_NOFS);
> -	if (!rv)
> -		return -ENOMEM;
> -
> +	idr_preload(GFP_NOFS);
>  	spin_lock(&ls->ls_lkbidr_spin);
> -	rv = idr_get_new_above(&ls->ls_lkbidr, lkb, 1, &id);
> -	if (!rv)
> -		lkb->lkb_id = id;
> +	rv = idr_alloc(&ls->ls_lkbidr, lkb, 1, 0, GFP_NOWAIT);

Hi Tejun,
I'm seeing a number of new failure/warning messages within this idr_alloc.
I've not seen idr_alloc itself return an error yet.  Is this an expected
failure where the warnings should be suppressed?
Dave

kworker/u:3: page allocation failure: order:1, mode:0x200000
Pid: 181, comm: kworker/u:3 Not tainted 3.9.0-rc2+ #1
Call Trace:
 [<ffffffff810c870b>] warn_alloc_failed+0xeb/0x150
 [<ffffffff8105f91e>] ? __wake_up+0x4e/0x70
 [<ffffffff810ca626>] __alloc_pages_nodemask+0x666/0x930
 [<ffffffff810ca626>] ? __alloc_pages_nodemask+0x666/0x930
 [<ffffffff811031ff>] kmem_getpages+0x5f/0x1b0
 [<ffffffff81103e33>] fallback_alloc+0x173/0x250
 [<ffffffff81103be3>] ____cache_alloc_node+0x93/0x170
 [<ffffffff811035f8>] ? cache_alloc_refill+0x2a8/0x310
 [<ffffffff81104e59>] kmem_cache_alloc+0xd9/0x130
 [<ffffffff811da11c>] idr_layer_alloc+0x2c/0x80
 [<ffffffff811dac8c>] idr_get_empty_slot+0x2ec/0x390
 [<ffffffff811db0ad>] idr_alloc+0x4d/0xc0
 [<ffffffffa031ded2>] create_lkb+0x122/0x180 [dlm]
 [<ffffffffa03232a4>] receive_request+0x34/0x440 [dlm]
 [<ffffffffa0331f07>] ? dlm_wait_requestqueue+0x37/0x60 [dlm]
 [<ffffffffa0326aac>] _receive_message+0x67c/0x1050 [dlm]
 [<ffffffff81425f39>] ? mutex_unlock+0x9/0x10
 [<ffffffffa0327605>] dlm_receive_buffer+0x185/0x200 [dlm]
 [<ffffffffa032ab7f>] dlm_process_incoming_buffer+0xef/0x210 [dlm]
 [<ffffffffa032c5cc>] receive_from_sock+0x1ac/0x430 [dlm]
 [<ffffffffa032aee9>] process_recv_sockets+0x29/0x40 [dlm]
 [<ffffffff8104e0d7>] process_one_work+0x1c7/0x460
 [<ffffffff8104e071>] ? process_one_work+0x161/0x460
 [<ffffffff8105124d>] worker_thread+0x11d/0x3e0
 [<ffffffff81051130>] ? manage_workers+0x340/0x340
 [<ffffffff81056606>] kthread+0xe6/0xf0
 [<ffffffff81056520>] ? __init_kthread_worker+0x70/0x70
 [<ffffffff8142feec>] ret_from_fork+0x7c/0xb0
 [<ffffffff81056520>] ? __init_kthread_worker+0x70/0x70
Mem-Info:
Node 0 DMA per-cpu:
CPU    0: hi:    0, btch:   1 usd:   0
CPU    1: hi:    0, btch:   1 usd:   0
CPU    2: hi:    0, btch:   1 usd:   0
CPU    3: hi:    0, btch:   1 usd:   0
Node 0 DMA32 per-cpu:
CPU    0: hi:  186, btch:  31 usd: 163
CPU    1: hi:  186, btch:  31 usd: 161
CPU    2: hi:  186, btch:  31 usd: 183
CPU    3: hi:  186, btch:  31 usd:  53
Node 1 DMA32 per-cpu:
CPU    0: hi:  186, btch:  31 usd:   0
CPU    1: hi:  186, btch:  31 usd:   0
CPU    2: hi:  186, btch:  31 usd: 191
CPU    3: hi:  186, btch:  31 usd: 166
Node 1 Normal per-cpu:
CPU    0: hi:  186, btch:  31 usd:   0
CPU    1: hi:  186, btch:  31 usd:  32
CPU    2: hi:  186, btch:  31 usd: 162
CPU    3: hi:  186, btch:  31 usd: 222
active_anon:4222 inactive_anon:8075 isolated_anon:0
 active_file:511976 inactive_file:334346 isolated_file:0
 unevictable:7742 dirty:0 writeback:0 unstable:0
 free:6682 slab_reclaimable:68508 slab_unreclaimable:62477
 mapped:8263 shmem:7537 pagetables:913 bounce:0
 free_cma:0
Node 0 DMA free:7912kB min:28kB low:32kB high:40kB active_anon:0kB inactive_anon:0kB active_file:7376kB inactive_file:256kB unevictable:24kB isolated(anon):0kB isolated(file):0kB present:15972kB managed:15884kB mlocked:24kB dirty:0kB writeback:0kB mapped:24kB shmem:24kB slab_reclaimable:296kB slab_unreclaimable:20kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 1971 1971 1971
Node 0 DMA32 free:7560kB min:4016kB low:5020kB high:6024kB active_anon:7868kB inactive_anon:22228kB active_file:1034116kB inactive_file:727656kB unevictable:1720kB isolated(anon):0kB isolated(file):0kB present:2080768kB managed:2019104kB mlocked:1720kB dirty:0kB writeback:0kB mapped:18188kB shmem:15648kB slab_reclaimable:101792kB slab_unreclaimable:110520kB kernel_stack:792kB pagetables:1632kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 0 0
Node 1 DMA32 free:7928kB min:1952kB low:2440kB high:2928kB active_anon:44kB inactive_anon:888kB active_file:482644kB inactive_file:366988kB unevictable:26080kB isolated(anon):0kB isolated(file):0kB present:1047680kB managed:982144kB mlocked:26080kB dirty:0kB writeback:0kB mapped:4524kB shmem:4500kB slab_reclaimable:71140kB slab_unreclaimable:24332kB kernel_stack:24kB pagetables:96kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:27 all_unreclaimable? no
lowmem_reserve[]: 0 0 995 995
Node 1 Normal free:3328kB min:2024kB low:2528kB high:3036kB active_anon:8976kB inactive_anon:9184kB active_file:523768kB inactive_file:242484kB unevictable:3144kB isolated(anon):0kB isolated(file):0kB present:1048576kB managed:1018896kB mlocked:3144kB dirty:0kB writeback:0kB mapped:10316kB shmem:9976kB slab_reclaimable:100804kB slab_unreclaimable:115036kB kernel_stack:352kB pagetables:1924kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:71 all_unreclaimable? no
lowmem_reserve[]: 0 0 0 0
Node 0 DMA: 2*4kB (U) 4*8kB (UEM) 4*16kB (UEM) 2*32kB (U) 3*64kB (UE) 1*128kB (E) 1*256kB (U) 2*512kB (EM) 2*1024kB (UE) 2*2048kB (ER) 0*4096kB = 7912kB
Node 0 DMA32: 1228*4kB (UEM) 25*8kB (UEM) 19*16kB (M) 17*32kB (M) 7*64kB (M) 1*128kB (M) 0*256kB 0*512kB 1*1024kB (R) 0*2048kB 0*4096kB = 7560kB
Node 1 DMA32: 1571*4kB (UEMR) 25*8kB (EMR) 9*16kB (MR) 5*32kB (MR) 2*64kB (M) 0*128kB 2*256kB (M) 1*512kB (M) 0*1024kB 0*2048kB 0*4096kB = 7940kB
Node 1 Normal: 537*4kB (UEMR) 46*8kB (UEMR) 19*16kB (MR) 8*32kB (MR) 0*64kB 0*128kB 1*256kB (R) 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3332kB
854648 total pagecache pages
0 pages in swap cache
Swap cache stats: add 0, delete 0, find 0/0
Free swap  = 6160380kB
Total swap = 6160380kB
1048575 pages RAM
35415 pages reserved
884260 pages shared
916445 pages non-shared
SLAB: Unable to allocate memory on node 1 (gfp=0x0)
  cache: idr_layer_cache, object size: 2112, order: 1
  node 0: slabs: 91/91, objs: 273/273, free: 0
  node 1: slabs: 200/200, objs: 600/600, free: 0


> +	if (rv >= 0)
> +		lkb->lkb_id = rv;
>  	spin_unlock(&ls->ls_lkbidr_spin);
> -
> -	if (rv == -EAGAIN)
> -		goto retry;
> +	idr_preload_end();
>  
>  	if (rv < 0) {
>  		log_error(ls, "create_lkb idr error %d", rv);

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 67/77] dlm: convert to idr_alloc()
  2013-03-11 19:29   ` David Teigland
@ 2013-03-11 20:28     ` Tejun Heo
  2013-03-12 15:17       ` David Teigland
  0 siblings, 1 reply; 106+ messages in thread
From: Tejun Heo @ 2013-03-11 20:28 UTC (permalink / raw)
  To: David Teigland; +Cc: linux-kernel

Hello, David.

On Mon, Mar 11, 2013 at 03:29:55PM -0400, David Teigland wrote:
> On Wed, Feb 06, 2013 at 11:40:39AM -0800, Tejun Heo wrote:
> >  static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
> >  {
> >  	struct dlm_lkb *lkb;
> > -	int rv, id;
> > +	int rv;
> >  
> >  	lkb = dlm_allocate_lkb(ls);
> >  	if (!lkb)
> > @@ -1199,19 +1199,13 @@ 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);
> >  
> > - retry:
> > -	rv = idr_pre_get(&ls->ls_lkbidr, GFP_NOFS);
> > -	if (!rv)
> > -		return -ENOMEM;
> > -
> > +	idr_preload(GFP_NOFS);
> >  	spin_lock(&ls->ls_lkbidr_spin);
> > -	rv = idr_get_new_above(&ls->ls_lkbidr, lkb, 1, &id);
> > -	if (!rv)
> > -		lkb->lkb_id = id;
> > +	rv = idr_alloc(&ls->ls_lkbidr, lkb, 1, 0, GFP_NOWAIT);
> 
> Hi Tejun,
> I'm seeing a number of new failure/warning messages within this idr_alloc.
> I've not seen idr_alloc itself return an error yet.  Is this an expected
> failure where the warnings should be suppressed?

Ah, right, in preloaded section, the allocation is expected to fail
before falling back to the preload buffer and I forgot to add
__GFP_NOWARN to the first try.  Something like the following should
make it go away.  Can you please test it?

Thanks a lot!

diff --git a/lib/idr.c b/lib/idr.c
index 00739aa..e410e5d 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -106,8 +106,14 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
 	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);
+	/*
+	 * Try to allocate directly from kmem_cache.  We want to try this
+	 * before preload buffer; otherwise, non-preloading idr_alloc()
+	 * users will end up taking advantage of preloading ones.  As the
+	 * following is allowed to fail for preloaded cases, suppress
+	 * warning this time.
+	 */
+	new = kmem_cache_zalloc(idr_layer_cache, gfp_mask | __GFP_NOWARN);
 	if (new)
 		return new;
 
@@ -115,18 +121,24 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
 	 * 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;
+	if (!in_interrupt()) {
+		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();
+		if (new)
+			return new;
 	}
-	preempt_enable();
-	return new;
+
+	/*
+	 * Both failed.  Try kmem_cache again w/o adding __GFP_NOWARN so
+	 * that memory allocation failure warning is printed as intended.
+	 */
+	return kmem_cache_zalloc(idr_layer_cache, gfp_mask);
 }
 
 static void idr_layer_rcu_free(struct rcu_head *head)

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* Re: [PATCH 67/77] dlm: convert to idr_alloc()
  2013-03-11 20:28     ` Tejun Heo
@ 2013-03-12 15:17       ` David Teigland
  2013-03-12 21:22         ` [PATCH] idr: idr_alloc() shouldn't trigger lowmem warning when preloaded Tejun Heo
  0 siblings, 1 reply; 106+ messages in thread
From: David Teigland @ 2013-03-12 15:17 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel

On Mon, Mar 11, 2013 at 01:28:18PM -0700, Tejun Heo wrote:
> Ah, right, in preloaded section, the allocation is expected to fail
> before falling back to the preload buffer and I forgot to add
> __GFP_NOWARN to the first try.  Something like the following should
> make it go away.  Can you please test it?

Tested, and the warnings went away, thanks.
Dave

^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH] idr: idr_alloc() shouldn't trigger lowmem warning when preloaded
  2013-03-12 15:17       ` David Teigland
@ 2013-03-12 21:22         ` Tejun Heo
  0 siblings, 0 replies; 106+ messages in thread
From: Tejun Heo @ 2013-03-12 21:22 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, David Teigland

GFP_NOIO is often used for idr_alloc() inside preloaded section as the
allocation mask doesn't really matter.  If the idr tree needs to be
expanded, idr_alloc() first tries to allocate using the specified
allocation mask and if it fails falls back to the preloaded buffer.
This order prevent non-preloading idr_alloc() users from taking
advantage of preloading ones by using preload buffer without filling
it shifting the burden of allocation to the preload users.

Unfortunately, this allowed/expected-to-fail kmem_cache allocation
ends up generating spurious slab lowmem warning before succeeding the
request from the preload buffer.

This patch makes idr_layer_alloc() add __GFP_NOWARN to the first
kmem_cache attempt and try kmem_cache again w/o __GFP_NOWARN after
allocation from preload_buffer fails so that lowmem warning is
generated if not suppressed by the original @gfp_mask.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: David Teigland <teigland@redhat.com>
Tested-by: David Teigland <teigland@redhat.com>
---
Hello, Andrew.

I forgot about slab lowmem warning when swapping the positions of
kmem_cache alloc and preload buffer alloc and it's generating spurious
lowmem warnings.  Should probably be shipped to Linus soonish.

Thanks!

 lib/idr.c |   38 +++++++++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/lib/idr.c b/lib/idr.c
index 00739aa..e410e5d 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -106,8 +106,14 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
 	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);
+	/*
+	 * Try to allocate directly from kmem_cache.  We want to try this
+	 * before preload buffer; otherwise, non-preloading idr_alloc()
+	 * users will end up taking advantage of preloading ones.  As the
+	 * following is allowed to fail for preloaded cases, suppress
+	 * warning this time.
+	 */
+	new = kmem_cache_zalloc(idr_layer_cache, gfp_mask | __GFP_NOWARN);
 	if (new)
 		return new;
 
@@ -115,18 +121,24 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
 	 * 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;
+	if (!in_interrupt()) {
+		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();
+		if (new)
+			return new;
 	}
-	preempt_enable();
-	return new;
+
+	/*
+	 * Both failed.  Try kmem_cache again w/o adding __GFP_NOWARN so
+	 * that memory allocation failure warning is printed as intended.
+	 */
+	return kmem_cache_zalloc(idr_layer_cache, gfp_mask);
 }
 
 static void idr_layer_rcu_free(struct rcu_head *head)

^ permalink raw reply related	[flat|nested] 106+ messages in thread

end of thread, other threads:[~2013-03-12 21:22 UTC | newest]

Thread overview: 106+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-06 19:39 [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Tejun Heo
2013-02-06 19:39 ` [PATCH 01/77] idr: fix a subtle bug in idr_get_next() Tejun Heo
2013-02-06 19:39 ` [PATCH 02/77] idr: make idr_destroy() imply idr_remove_all() Tejun Heo
2013-02-06 19:39 ` [PATCH 03/77] atm/nicstar: don't use idr_remove_all() Tejun Heo
2013-02-06 19:39 ` [PATCH 04/77] block/loop: " Tejun Heo
2013-02-06 19:39 ` [PATCH 05/77] firewire: " Tejun Heo
2013-02-06 19:39 ` [PATCH 06/77] drm: " Tejun Heo
2013-02-06 19:39 ` [PATCH 07/77] dm: " Tejun Heo
2013-02-06 19:39 ` [PATCH 08/77] remoteproc: " Tejun Heo
2013-02-06 19:39 ` [PATCH 09/77] rpmsg: " Tejun Heo
2013-02-06 19:39 ` [PATCH 10/77] dlm: use idr_for_each_entry() in recover_idr_clear() error path Tejun Heo
2013-02-06 19:39 ` [PATCH 11/77] dlm: don't use idr_remove_all() Tejun Heo
2013-02-06 19:39 ` [PATCH 12/77] nfs: idr_destroy() no longer needs idr_remove_all() Tejun Heo
2013-02-06 19:39 ` [PATCH 13/77] inotify: don't use idr_remove_all() Tejun Heo
2013-02-06 19:39 ` [PATCH 14/77] cgroup: " Tejun Heo
2013-02-07  1:29   ` Li Zefan
2013-02-06 19:39 ` [PATCH 15/77] idr: deprecate idr_remove_all() Tejun Heo
2013-02-06 19:39 ` [PATCH 16/77] idr: cosmetic updates to struct / initializer definitions Tejun Heo
2013-02-06 19:39 ` [PATCH 17/77] idr: relocate idr_for_each_entry() and reorganize id[r|a]_get_new() Tejun Heo
2013-02-06 19:39 ` [PATCH 18/77] idr: remove _idr_rc_to_errno() hack Tejun Heo
2013-02-06 19:39 ` [PATCH 19/77] idr: refactor idr_get_new_above() Tejun Heo
2013-02-06 19:39 ` [PATCH 20/77] idr: implement idr_preload[_end]() and idr_alloc() Tejun Heo
2013-02-07 19:53   ` [PATCH v3 " Tejun Heo
2013-02-06 19:39 ` [PATCH 21/77] block: fix synchronization and limit check in blk_alloc_devt() Tejun Heo
2013-02-06 22:24   ` Andrew Morton
2013-02-06 22:27     ` Tejun Heo
2013-02-06 22:32       ` Andrew Morton
2013-02-06 22:33         ` Tejun Heo
2013-02-06 19:39 ` [PATCH 22/77] block: convert to idr_alloc() Tejun Heo
2013-02-06 19:39 ` [PATCH 23/77] block/loop: " Tejun Heo
2013-02-07 18:25   ` [PATCH 22.5/77] block/loop: fix error return value in loop_add() Tejun Heo
2013-02-07 18:26   ` [PATCH v2 23/77] block/loop: convert to idr_alloc() Tejun Heo
2013-02-06 19:39 ` [PATCH 24/77] atm/nicstar: " Tejun Heo
2013-02-06 19:39 ` [PATCH 25/77] drbd: " Tejun Heo
2013-02-06 19:39 ` [PATCH 26/77] dca: " Tejun Heo
2013-02-06 19:39 ` [PATCH 27/77] dmaengine: " Tejun Heo
2013-02-06 19:40 ` [PATCH 28/77] firewire: add minor number range check to fw_device_init() Tejun Heo
2013-02-06 19:40 ` [PATCH 29/77] firewire: convert to idr_alloc() Tejun Heo
2013-02-06 19:40 ` [PATCH 30/77] gpio: " Tejun Heo
2013-02-06 19:40 ` [PATCH 31/77] drm: " Tejun Heo
2013-02-06 19:40 ` [PATCH 32/77] drm/exynos: " Tejun Heo
2013-02-06 19:40 ` [PATCH 33/77] drm/i915: " Tejun Heo
2013-02-06 19:40 ` [PATCH 34/77] drm/sis: " Tejun Heo
2013-02-06 19:40 ` [PATCH 35/77] drm/via: " Tejun Heo
2013-02-06 19:40 ` [PATCH 36/77] drm/vmwgfx: " Tejun Heo
2013-02-06 19:40 ` [PATCH 37/77] i2c: " Tejun Heo
2013-02-07 15:28   ` Mark Brown
2013-02-07 16:32     ` Tejun Heo
2013-02-07 16:39       ` Mark Brown
2013-02-07 16:55         ` [PATCH v2] " Tejun Heo
2013-02-07 18:52           ` Mark Brown
2013-02-08 12:10           ` Mark Brown
2013-02-10 11:47           ` Wolfram Sang
2013-02-12 17:34             ` [PATCH -mm] i2c: style cleanups after idr_alloc() conversion Tejun Heo
2013-02-12 17:36               ` Tejun Heo
2013-02-12 18:00                 ` Jean Delvare
2013-02-13 20:42               ` Wolfram Sang
2013-02-06 19:40 ` [PATCH 38/77] IB/core: convert to idr_alloc() Tejun Heo
2013-02-06 19:40 ` [PATCH 39/77] IB/amso1100: " Tejun Heo
2013-02-06 19:40 ` [PATCH 40/77] IB/cxgb3: " Tejun Heo
2013-02-06 19:40 ` [PATCH 41/77] IB/cxgb4: " Tejun Heo
2013-02-06 19:40 ` [PATCH 42/77] IB/ehca: " Tejun Heo
2013-02-06 19:40 ` [PATCH 43/77] IB/ipath: " Tejun Heo
2013-02-06 19:40 ` [PATCH 44/77] IB/mlx4: " Tejun Heo
2013-02-06 19:40 ` [PATCH 45/77] IB/ocrdma: " Tejun Heo
2013-02-06 19:40 ` [PATCH 46/77] IB/qib: " Tejun Heo
2013-02-06 19:40 ` [PATCH 47/77] dm: " Tejun Heo
2013-02-06 19:40 ` [PATCH 48/77] memstick: " Tejun Heo
2013-02-06 19:40 ` [PATCH 49/77] mfd: " Tejun Heo
2013-02-06 19:40 ` [PATCH 50/77] misc/c2port: " Tejun Heo
2013-02-06 19:40 ` [PATCH 51/77] misc/tifm_core: " Tejun Heo
2013-02-06 19:40 ` [PATCH 52/77] mmc: " Tejun Heo
2013-02-06 19:40 ` [PATCH 53/77] mtd: " Tejun Heo
2013-02-06 19:40 ` [PATCH 54/77] macvtap: " Tejun Heo
2013-02-06 19:40 ` [PATCH 55/77] ppp: " Tejun Heo
2013-02-06 19:40 ` [PATCH 56/77] power: " Tejun Heo
2013-02-06 19:40 ` [PATCH 57/77] pps: " Tejun Heo
2013-02-06 19:40 ` [PATCH 58/77] remoteproc: " Tejun Heo
2013-02-06 19:40 ` [PATCH 59/77] rpmsg: " Tejun Heo
2013-02-06 19:40 ` [PATCH 60/77] scsi/bfa: " Tejun Heo
2013-02-06 19:40 ` [PATCH 61/77] scsi: " Tejun Heo
2013-02-06 19:40 ` [PATCH 62/77] target/iscsi: " Tejun Heo
2013-02-06 19:40 ` [PATCH 63/77] scsi/lpfc: " Tejun Heo
2013-02-11 22:47   ` James Smart
2013-02-06 19:40 ` [PATCH 64/77] thermal: " Tejun Heo
2013-02-06 19:40 ` [PATCH 65/77] uio: " Tejun Heo
2013-02-06 19:40 ` [PATCH 66/77] vfio: " Tejun Heo
2013-02-06 19:40 ` [PATCH 67/77] dlm: " Tejun Heo
2013-03-11 19:29   ` David Teigland
2013-03-11 20:28     ` Tejun Heo
2013-03-12 15:17       ` David Teigland
2013-03-12 21:22         ` [PATCH] idr: idr_alloc() shouldn't trigger lowmem warning when preloaded Tejun Heo
2013-02-06 19:40 ` [PATCH 68/77] inotify: convert to idr_alloc() Tejun Heo
2013-02-06 19:40 ` [PATCH 69/77] ocfs2: " Tejun Heo
2013-02-06 19:40 ` [PATCH 70/77] ipc: " Tejun Heo
2013-02-07 19:43   ` [PATCH v2 " Tejun Heo
2013-02-06 19:40 ` [PATCH 71/77] cgroup: " Tejun Heo
2013-02-06 19:40 ` [PATCH 72/77] events: " Tejun Heo
2013-02-06 19:40 ` [PATCH 73/77] posix-timers: " Tejun Heo
2013-02-06 19:40 ` [PATCH 74/77] net/9p: " Tejun Heo
2013-02-06 19:40 ` [PATCH 75/77] mac80211: " Tejun Heo
2013-02-06 19:40 ` [PATCH 76/77] sctp: " Tejun Heo
2013-02-06 20:07   ` Vlad Yasevich
2013-02-07 14:49   ` Neil Horman
2013-02-06 19:40 ` [PATCH 77/77] nfs4client: " Tejun Heo
2013-02-08  4:04 ` [PATCHSET] idr: deprecate idr_remova_all() and add idr_alloc() Dave Airlie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).