media: entity: skip non-data link when removing reverse links
authorYunke Cao <yunkec@google.com>
Tue, 12 Apr 2022 06:23:13 +0000 (07:23 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Sun, 24 Apr 2022 06:56:44 +0000 (07:56 +0100)
The original implementation removes reverse links for any input link and
assumes the presense of sink/source.
It fails when the link is a not a data link.
media_entity_remove_links when there's an ancillary link can also fail.

We only need to remove reverse links for a data link.

Signed-off-by: Yunke Cao <yunkec@google.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/mc/mc-entity.c

index 8ab0913d8d8233575b26d137ceb307721eb9ad01..20f5a76bd78b6c40cb817cfd2700d4e973571e50 100644 (file)
@@ -579,26 +579,30 @@ static void __media_entity_remove_link(struct media_entity *entity,
        struct media_link *rlink, *tmp;
        struct media_entity *remote;
 
-       if (link->source->entity == entity)
-               remote = link->sink->entity;
-       else
-               remote = link->source->entity;
+       /* Remove the reverse links for a data link. */
+       if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == MEDIA_LNK_FL_DATA_LINK) {
+               if (link->source->entity == entity)
+                       remote = link->sink->entity;
+               else
+                       remote = link->source->entity;
 
-       list_for_each_entry_safe(rlink, tmp, &remote->links, list) {
-               if (rlink != link->reverse)
-                       continue;
+               list_for_each_entry_safe(rlink, tmp, &remote->links, list) {
+                       if (rlink != link->reverse)
+                               continue;
 
-               if (link->source->entity == entity)
-                       remote->num_backlinks--;
+                       if (link->source->entity == entity)
+                               remote->num_backlinks--;
 
-               /* Remove the remote link */
-               list_del(&rlink->list);
-               media_gobj_destroy(&rlink->graph_obj);
-               kfree(rlink);
+                       /* Remove the remote link */
+                       list_del(&rlink->list);
+                       media_gobj_destroy(&rlink->graph_obj);
+                       kfree(rlink);
 
-               if (--remote->num_links == 0)
-                       break;
+                       if (--remote->num_links == 0)
+                               break;
+               }
        }
+
        list_del(&link->list);
        media_gobj_destroy(&link->graph_obj);
        kfree(link);