All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, Rusty Russell <rusty@rustcorp.com.au>
Subject: [PATCH v3 20/77] idr: implement idr_preload[_end]() and idr_alloc()
Date: Thu, 7 Feb 2013 11:53:25 -0800	[thread overview]
Message-ID: <20130207195325.GS2875@htj.dyndns.org> (raw)
In-Reply-To: <1360179649-22465-21-git-send-email-tj@kernel.org>

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;
 

  reply	other threads:[~2013-02-07 19:53 UTC|newest]

Thread overview: 134+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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   ` 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   ` [Cluster-devel] " Tejun Heo
2013-02-06 19:39 ` [PATCH 11/77] dlm: don't use idr_remove_all() Tejun Heo
2013-02-06 19:39   ` [Cluster-devel] " 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
     [not found] ` <1360179649-22465-1-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-02-06 19:39   ` [PATCH 14/77] cgroup: " Tejun Heo
2013-02-06 19:39     ` Tejun Heo
     [not found]     ` <1360179649-22465-15-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-02-07  1:29       ` Li Zefan
2013-02-07  1:29     ` Li Zefan
2013-02-07  1:29       ` Li Zefan
2013-02-06 19:40   ` [PATCH 42/77] IB/ehca: convert to idr_alloc() Tejun Heo
2013-02-06 19:40     ` Tejun Heo
2013-02-06 19:40   ` [PATCH 71/77] cgroup: " Tejun Heo
2013-02-06 19:40     ` Tejun Heo
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   ` Tejun Heo [this message]
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   ` 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   ` Tejun Heo
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 36/77] drm/vmwgfx: " Tejun Heo
2013-02-06 19:40 ` [PATCH 37/77] i2c: " Tejun Heo
2013-02-06 19:40   ` Tejun Heo
2013-02-07 15:28   ` Mark Brown
2013-02-07 16:32     ` Tejun Heo
2013-02-07 16:32       ` Tejun Heo
2013-02-07 16:39       ` Mark Brown
2013-02-07 16:39         ` Mark Brown
2013-02-07 16:55         ` [PATCH v2] " Tejun Heo
2013-02-07 16:55           ` Tejun Heo
2013-02-07 18:52           ` Mark Brown
2013-02-08 12:10           ` Mark Brown
2013-02-08 12:10             ` Mark Brown
2013-02-10 11:47           ` Wolfram Sang
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:34               ` Tejun Heo
2013-02-12 17:36               ` Tejun Heo
2013-02-12 17:36                 ` Tejun Heo
2013-02-12 18:00                 ` Jean Delvare
2013-02-12 18:00                   ` Jean Delvare
2013-02-13 20:42               ` Wolfram Sang
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 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   ` 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   ` 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   ` 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-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 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 19:40   ` Tejun Heo
2013-02-06 20:07   ` Vlad Yasevich
2013-02-06 20:07     ` Vlad Yasevich
2013-02-07 14:49   ` Neil Horman
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130207195325.GS2875@htj.dyndns.org \
    --to=tj@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rusty@rustcorp.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.