|
@@ -495,6 +495,33 @@ int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(idr_alloc);
|
|
|
|
|
|
+/**
|
|
|
+ * idr_alloc_cyclic - allocate new idr entry in a cyclical fashion
|
|
|
+ * @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
|
|
|
+ *
|
|
|
+ * Essentially the same as idr_alloc, but prefers to allocate progressively
|
|
|
+ * higher ids if it can. If the "cur" counter wraps, then it will start again
|
|
|
+ * at the "start" end of the range and allocate one that has already been used.
|
|
|
+ */
|
|
|
+int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end,
|
|
|
+ gfp_t gfp_mask)
|
|
|
+{
|
|
|
+ int id;
|
|
|
+
|
|
|
+ id = idr_alloc(idr, ptr, max(start, idr->cur), end, gfp_mask);
|
|
|
+ if (id == -ENOSPC)
|
|
|
+ id = idr_alloc(idr, ptr, start, end, gfp_mask);
|
|
|
+
|
|
|
+ if (likely(id >= 0))
|
|
|
+ idr->cur = id + 1;
|
|
|
+ return id;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(idr_alloc_cyclic);
|
|
|
+
|
|
|
static void idr_remove_warning(int id)
|
|
|
{
|
|
|
printk(KERN_WARNING
|