]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - lib/idr.c
dma-debug: add a schedule point in debug_dma_dump_mappings()
[mirror_ubuntu-bionic-kernel.git] / lib / idr.c
index 2593ce513a180a4f6de3515350592c9d4e4981d1..8dda36edf3149604b96ad7afa0540b331542d0ad 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -111,13 +111,27 @@ void *idr_get_next(struct idr *idr, int *nextid)
 {
        struct radix_tree_iter iter;
        void __rcu **slot;
-
-       slot = radix_tree_iter_find(&idr->idr_rt, &iter, *nextid);
+       void *entry = NULL;
+
+       radix_tree_for_each_slot(slot, &idr->idr_rt, &iter, *nextid) {
+               entry = rcu_dereference_raw(*slot);
+               if (!entry)
+                       continue;
+               if (!radix_tree_deref_retry(entry))
+                       break;
+               if (slot != (void *)&idr->idr_rt.rnode &&
+                               entry != (void *)RADIX_TREE_INTERNAL_NODE)
+                       break;
+               slot = radix_tree_iter_retry(&iter);
+       }
        if (!slot)
                return NULL;
 
+       if (WARN_ON_ONCE(iter.index > INT_MAX))
+               return NULL;
+
        *nextid = iter.index;
-       return rcu_dereference_raw(*slot);
+       return entry;
 }
 EXPORT_SYMBOL(idr_get_next);