aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/idr.h
diff options
context:
space:
mode:
authorCong Wang <xiyou.wangcong@gmail.com>2019-06-28 11:03:42 -0700
committerDavid S. Miller <davem@davemloft.net>2019-07-01 19:15:46 -0700
commitd39d714969cda5cbda291402c8c6b1fb1047f42e (patch)
tree6e8b7f868b4bd79fa2f07df468072dc22b0fdc54 /include/linux/idr.h
parentidr: fix overflow case for idr_for_each_entry_ul() (diff)
downloadlinux-dev-d39d714969cda5cbda291402c8c6b1fb1047f42e.tar.xz
linux-dev-d39d714969cda5cbda291402c8c6b1fb1047f42e.zip
idr: introduce idr_for_each_entry_continue_ul()
Similarly, other callers of idr_get_next_ul() suffer the same overflow bug as they don't handle it properly either. Introduce idr_for_each_entry_continue_ul() to help these callers iterate from a given ID. cls_flower needs more care here because it still has overflow when does arg->cookie++, we have to fold its nested loops into one and remove the arg->cookie++. Fixes: 01683a146999 ("net: sched: refactor flower walk to iterate over idr") Fixes: 12d6066c3b29 ("net/mlx5: Add flow counters idr") Reported-by: Li Shuang <shuali@redhat.com> Cc: Davide Caratti <dcaratti@redhat.com> Cc: Vlad Buslov <vladbu@mellanox.com> Cc: Chris Mi <chrism@mellanox.com> Cc: Matthew Wilcox <willy@infradead.org> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Tested-by: Davide Caratti <dcaratti@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/idr.h')
-rw-r--r--include/linux/idr.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/include/linux/idr.h b/include/linux/idr.h
index 68528a72d10d..4ec8986e5dfb 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -216,6 +216,20 @@ static inline void idr_preload_end(void)
entry; \
++id, (entry) = idr_get_next((idr), &(id)))
+/**
+ * idr_for_each_entry_continue_ul() - Continue iteration over an IDR's elements of a given type
+ * @idr: IDR handle.
+ * @entry: The type * to use as a cursor.
+ * @tmp: A temporary placeholder for ID.
+ * @id: Entry ID.
+ *
+ * Continue to iterate over entries, continuing after the current position.
+ */
+#define idr_for_each_entry_continue_ul(idr, entry, tmp, id) \
+ for (tmp = id; \
+ tmp <= id && ((entry) = idr_get_next_ul(idr, &(id))) != NULL; \
+ tmp = id, ++id)
+
/*
* IDA - ID Allocator, use when translation from id to pointer isn't necessary.
*/