Commit 5c7b25b90d36942c524d06522ebaf0510a75592a
Committed by
Mauro Carvalho Chehab
1 parent
3a9677063f
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
[media] media: Add support for circular graph traversal
The graph traversal API (media_entity_graph_walk_*) doesn't support cyclic graphs and will fail to correctly walk a graph when circular links exist. Support circular graph traversal by checking whether an entity has already been visited before pushing it to the stack. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@iki.fi> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Showing 2 changed files with 15 additions and 3 deletions Side-by-side Diff
drivers/media/media-entity.c
... | ... | @@ -20,6 +20,7 @@ |
20 | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | 21 | */ |
22 | 22 | |
23 | +#include <linux/bitmap.h> | |
23 | 24 | #include <linux/module.h> |
24 | 25 | #include <linux/slab.h> |
25 | 26 | #include <media/media-entity.h> |
... | ... | @@ -121,7 +122,6 @@ |
121 | 122 | return entity; |
122 | 123 | } |
123 | 124 | |
124 | -#define stack_peek(en) ((en)->stack[(en)->top - 1].entity) | |
125 | 125 | #define link_top(en) ((en)->stack[(en)->top].link) |
126 | 126 | #define stack_top(en) ((en)->stack[(en)->top].entity) |
127 | 127 | |
... | ... | @@ -140,6 +140,12 @@ |
140 | 140 | { |
141 | 141 | graph->top = 0; |
142 | 142 | graph->stack[graph->top].entity = NULL; |
143 | + bitmap_zero(graph->entities, MEDIA_ENTITY_ENUM_MAX_ID); | |
144 | + | |
145 | + if (WARN_ON(entity->id >= MEDIA_ENTITY_ENUM_MAX_ID)) | |
146 | + return; | |
147 | + | |
148 | + __set_bit(entity->id, graph->entities); | |
143 | 149 | stack_push(graph, entity); |
144 | 150 | } |
145 | 151 | EXPORT_SYMBOL_GPL(media_entity_graph_walk_start); |
146 | 152 | |
... | ... | @@ -180,9 +186,11 @@ |
180 | 186 | |
181 | 187 | /* Get the entity in the other end of the link . */ |
182 | 188 | next = media_entity_other(entity, link); |
189 | + if (WARN_ON(next->id >= MEDIA_ENTITY_ENUM_MAX_ID)) | |
190 | + return NULL; | |
183 | 191 | |
184 | - /* Was it the entity we came here from? */ | |
185 | - if (next == stack_peek(graph)) { | |
192 | + /* Has the entity already been visited? */ | |
193 | + if (__test_and_set_bit(next->id, graph->entities)) { | |
186 | 194 | link_top(graph)++; |
187 | 195 | continue; |
188 | 196 | } |
include/media/media-entity.h
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | #ifndef _MEDIA_ENTITY_H |
24 | 24 | #define _MEDIA_ENTITY_H |
25 | 25 | |
26 | +#include <linux/bitops.h> | |
26 | 27 | #include <linux/list.h> |
27 | 28 | #include <linux/media.h> |
28 | 29 | |
29 | 30 | |
... | ... | @@ -113,12 +114,15 @@ |
113 | 114 | } |
114 | 115 | |
115 | 116 | #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 |
117 | +#define MEDIA_ENTITY_ENUM_MAX_ID 64 | |
116 | 118 | |
117 | 119 | struct media_entity_graph { |
118 | 120 | struct { |
119 | 121 | struct media_entity *entity; |
120 | 122 | int link; |
121 | 123 | } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; |
124 | + | |
125 | + DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); | |
122 | 126 | int top; |
123 | 127 | }; |
124 | 128 |