Re: [PATCH RFC v2 08/16] media: convert links from array to list

2015-08-11 Thread Hans Verkuil
On 08/07/15 16:20, Mauro Carvalho Chehab wrote:
 Using memory realloc to increase the size of an array
 is complex and makes harder to remove links. Also, by
 embedding the link inside an array at the entity makes harder
 to change the code to add interfaces, as interfaces will
 also need to use links.
 
 So, convert the links from arrays to lists.
 
 Signed-off-by: Mauro Carvalho Chehab mche...@osg.samsung.com
 
 diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
 index 9fb3f8958265..a95ca981aabb 100644
 --- a/drivers/media/media-device.c
 +++ b/drivers/media/media-device.c

snip

 @@ -452,27 +445,21 @@ EXPORT_SYMBOL_GPL(media_entity_put);
  
  static struct media_link *media_entity_add_link(struct media_entity *entity)
  {
 - if (entity-num_links = entity-max_links) {
 - struct media_link *links = entity-links;
 - unsigned int max_links = entity-max_links + 2;
 - unsigned int i;
 + struct media_link *link;
  
 - links = krealloc(links, max_links * sizeof(*links), GFP_KERNEL);
 - if (links == NULL)
 - return NULL;
 + link = kzalloc(sizeof(*link), GFP_KERNEL);
 + if (link == NULL)
 + return NULL;
  
 - for (i = 0; i  entity-num_links; i++)
 - links[i].reverse-reverse = links[i];
 -
 - entity-max_links = max_links;
 - entity-links = links;
 - }
 + link-reverse-reverse = link;

Huh? link points to a zeroed struct, so link-reverse will be NULL.
This can't work.

Are you sure this line should be here? The original code doesn't set it
either for the new link, it just updates the reverse links for the
realloced links.

 + INIT_LIST_HEAD(link-list);
 + list_add(entity-links, link-list);
  
   /* Initialize graph object embedded at the new link */
   graph_obj_init(entity-parent, MEDIA_GRAPH_LINK,
 - entity-links[entity-num_links].graph_obj);
 + link-graph_obj);
  
 - return entity-links[entity-num_links++];
 + return link;
  }
  
  int

Regards,

Hans
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v2 08/16] media: convert links from array to list

2015-08-11 Thread Mauro Carvalho Chehab
Em Tue, 11 Aug 2015 12:49:40 +0200
Hans Verkuil hverk...@xs4all.nl escreveu:

 On 08/07/15 16:20, Mauro Carvalho Chehab wrote:
  Using memory realloc to increase the size of an array
  is complex and makes harder to remove links. Also, by
  embedding the link inside an array at the entity makes harder
  to change the code to add interfaces, as interfaces will
  also need to use links.
  
  So, convert the links from arrays to lists.
  
  Signed-off-by: Mauro Carvalho Chehab mche...@osg.samsung.com
  
  diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
  index 9fb3f8958265..a95ca981aabb 100644
  --- a/drivers/media/media-device.c
  +++ b/drivers/media/media-device.c
 
 snip
 
  @@ -452,27 +445,21 @@ EXPORT_SYMBOL_GPL(media_entity_put);
   
   static struct media_link *media_entity_add_link(struct media_entity 
  *entity)
   {
  -   if (entity-num_links = entity-max_links) {
  -   struct media_link *links = entity-links;
  -   unsigned int max_links = entity-max_links + 2;
  -   unsigned int i;
  +   struct media_link *link;
   
  -   links = krealloc(links, max_links * sizeof(*links), GFP_KERNEL);
  -   if (links == NULL)
  -   return NULL;
  +   link = kzalloc(sizeof(*link), GFP_KERNEL);
  +   if (link == NULL)
  +   return NULL;
   
  -   for (i = 0; i  entity-num_links; i++)
  -   links[i].reverse-reverse = links[i];
  -
  -   entity-max_links = max_links;
  -   entity-links = links;
  -   }
  +   link-reverse-reverse = link;
 
 Huh? link points to a zeroed struct, so link-reverse will be NULL.
 This can't work.
 
 Are you sure this line should be here? The original code doesn't set it
 either for the new link, it just updates the reverse links for the
 realloced links.

You're right. I think I can just remove that line.

I had to confess that I didn't understand well that the reverse links
stuff. I mean, IMHO, the entire concept of storing a second copy of
the link, calling it as reverse on some places and as backlink
on others is messy, and I guess we should get rid of duplicating the
number of links for no good reason.

It is easy to just add the same link to a list at the other entity,
and keep the link just once in the memory.

 
  +   INIT_LIST_HEAD(link-list);
  +   list_add(entity-links, link-list);
   
  /* Initialize graph object embedded at the new link */
  graph_obj_init(entity-parent, MEDIA_GRAPH_LINK,
  -   entity-links[entity-num_links].graph_obj);
  +   link-graph_obj);
   
  -   return entity-links[entity-num_links++];
  +   return link;
   }
   
   int
 
 Regards,
 
   Hans
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v2 08/16] media: convert links from array to list

2015-08-07 Thread Mauro Carvalho Chehab
Using memory realloc to increase the size of an array
is complex and makes harder to remove links. Also, by
embedding the link inside an array at the entity makes harder
to change the code to add interfaces, as interfaces will
also need to use links.

So, convert the links from arrays to lists.

Signed-off-by: Mauro Carvalho Chehab mche...@osg.samsung.com

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 9fb3f8958265..a95ca981aabb 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -25,6 +25,7 @@
 #include linux/ioctl.h
 #include linux/media.h
 #include linux/types.h
+#include linux/slab.h
 
 #include media/media-device.h
 #include media/media-devnode.h
@@ -148,22 +149,22 @@ static long __media_device_enum_links(struct media_device 
*mdev,
}
 
if (links-links) {
-   struct media_link_desc __user *ulink;
-   unsigned int l;
+   struct media_link *ent_link;
+   struct media_link_desc __user *ulink = links-links;
 
-   for (l = 0, ulink = links-links; l  entity-num_links; l++) {
+   list_for_each_entry(ent_link, entity-links, list) {
struct media_link_desc link;
 
/* Ignore backlinks. */
-   if (entity-links[l].source-entity != entity)
+   if (ent_link-source-entity != entity)
continue;
 
memset(link, 0, sizeof(link));
-   media_device_kpad_to_upad(entity-links[l].source,
+   media_device_kpad_to_upad(ent_link-source,
  link.source);
-   media_device_kpad_to_upad(entity-links[l].sink,
+   media_device_kpad_to_upad(ent_link-sink,
  link.sink);
-   link.flags = entity-links[l].flags;
+   link.flags = ent_link-flags;
if (copy_to_user(ulink, link, sizeof(*ulink)))
return -EFAULT;
ulink++;
@@ -471,6 +472,7 @@ void media_device_unregister_entity(struct media_entity 
*entity)
 {
int i;
struct media_device *mdev = entity-parent;
+   struct media_link *link, *tmp;
 
if (mdev == NULL)
return;
@@ -479,8 +481,11 @@ void media_device_unregister_entity(struct media_entity 
*entity)
graph_obj_remove(entity-graph_obj);
for (i = 0; entity-num_pads; i++)
graph_obj_remove(entity-pads[i].graph_obj);
-   for (i = 0; entity-num_links; i++)
-   graph_obj_remove(entity-links[i].graph_obj);
+   list_for_each_entry_safe(link, tmp, entity-links, list) {
+   graph_obj_remove(link-graph_obj);
+   list_del(link-list);
+   kfree(link);
+   }
list_del(entity-list);
spin_unlock(mdev-lock);
entity-parent = NULL;
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index e8451a4a403b..4a42ccfeffab 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -76,14 +76,6 @@ void graph_obj_remove(struct media_graph_obj *gobj)
  * use cases the entity driver can guess the number of links which can safely
  * be assumed to be equal to or larger than the number of pads.
  *
- * For those reasons the links array can be preallocated based on the entity
- * driver guess and will be reallocated later if extra links need to be
- * created.
- *
- * This function allocates a links array with enough space to hold at least
- * 'num_pads' + 'extra_links' elements. The media_entity::max_links field will
- * be set to the number of allocated elements.
- *
  * The pads array is managed by the entity driver and passed to
  * media_entity_init() where its pointer will be stored in the entity 
structure.
  */
@@ -91,21 +83,14 @@ int
 media_entity_init(struct media_entity *entity, u16 num_pads,
  struct media_pad *pads)
 {
-   struct media_link *links;
-   unsigned int max_links = num_pads;
unsigned int i;
 
-   links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL);
-   if (links == NULL)
-   return -ENOMEM;
-
entity-group_id = 0;
-   entity-max_links = max_links;
entity-num_links = 0;
entity-num_backlinks = 0;
entity-num_pads = num_pads;
entity-pads = pads;
-   entity-links = links;
+   INIT_LIST_HEAD(entity-links);
 
for (i = 0; i  num_pads; i++) {
pads[i].entity = entity;
@@ -119,7 +104,13 @@ EXPORT_SYMBOL_GPL(media_entity_init);
 void
 media_entity_cleanup(struct media_entity *entity)
 {
-   kfree(entity-links);
+   struct media_link *link, *tmp;
+
+   list_for_each_entry_safe(link, tmp, entity-links, list) {
+