Tejun Heo d5c7409f79 idr: implement idr_preload[_end]() and idr_alloc()
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.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-27 19:10:14 -08:00
..
2013-02-21 15:27:22 -08:00
2013-01-02 17:36:10 -08:00
2013-02-22 23:31:31 -05:00
2013-01-02 17:36:10 -08:00
2013-02-21 12:11:44 -08:00
2013-02-21 15:27:22 -08:00
2013-01-03 14:34:06 -08:00
2012-12-02 00:05:12 +00:00
2013-02-14 09:21:15 -05:00
2012-12-21 20:23:41 +00:00
2013-02-21 12:05:51 -08:00
2013-01-29 10:48:30 +01:00
2012-12-24 09:36:38 -07:00
2012-11-28 11:54:40 +01:00
2013-02-26 02:46:08 -05:00
2013-01-24 09:04:04 +01:00
2012-11-28 21:49:02 -05:00
2012-11-28 21:49:02 -05:00
2013-02-22 23:31:31 -05:00
2013-01-25 21:03:54 -08:00
2012-11-23 12:23:40 +01:00
2013-02-06 15:59:47 -05:00
2012-12-14 13:05:26 +10:30
2013-01-29 13:59:57 -05:00
2013-01-10 11:44:38 -06:00
2013-01-29 19:32:58 -08:00
2012-12-12 17:38:33 -08:00
2013-01-21 17:18:20 +10:30
2012-12-14 13:06:40 +10:30
2012-12-25 18:45:06 -05:00
2012-12-11 17:22:27 -08:00
2013-02-21 13:41:04 -08:00
2013-02-25 21:18:18 -08:00
2013-02-21 12:05:51 -08:00
2013-02-21 13:41:04 -08:00
2013-01-24 15:37:26 +01:00
2013-01-03 15:57:14 -08:00
2013-02-26 09:34:29 -08:00
2013-01-23 13:44:00 -05:00
2013-02-21 12:05:51 -08:00
2013-02-19 08:43:34 +01:00
2013-02-03 15:09:26 -05:00
2012-12-18 15:02:13 -08:00
2012-12-18 15:02:14 -08:00
2013-02-10 19:41:08 -05:00
2012-12-24 09:36:38 -07:00
2013-02-14 09:21:15 -05:00
2013-02-21 14:58:40 -08:00
2013-01-15 22:43:15 -08:00
2013-02-08 18:28:04 +01:00
2013-01-25 15:06:01 -08:00