idr: fix a subtle bug in idr_get_next()
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / lib / idr.c
index 648239079dd21329f0329ddaf12552677149d846..ca5aa000d6c31a15ad7ff837b0daa857eca49fe9 100644 (file)
--- 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;