Re: [RFC PATCH v2 1/2] media: Add function removing all media entity links

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Sylwester,

Thanks for the patch.

On Fri, May 10, 2013 at 12:00:37PM +0200, Sylwester Nawrocki wrote:
> This function allows to remove all media entity's links to other
> entities, leaving no references to a media entity's links array
> at its remote entities.
> 
> Currently when a driver of some entity is removed it will free its
> media entities links[] array, leaving dangling pointers at other
> entities that are part of same media graph. This is troublesome when
> drivers of a media device entities are in separate kernel modules,
> removing only some modules will leave others in incorrect state.
> 
> This function is intended to be used when an entity is being
> unregistered from a media device.
> 
> With an assumption that media links should be created only after
> they are registered to a media device and with the graph mutex held.
> 
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@xxxxxxxxxxx>
> Reviewed-by: Andrzej Hajda <a.hajda@xxxxxxxxxxx>
> [locking error in the initial patch version]
> Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>
> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
> ---
> Changes since the initial version:
>  - fixed erroneous double mutex lock in media_entity_links_remove() 
>    function.
> 
>  drivers/media/media-entity.c |   51 ++++++++++++++++++++++++++++++++++++++++++
>  include/media/media-entity.h |    3 +++
>  2 files changed, 54 insertions(+)
> 
> diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
> index e1cd132..bd85dc3 100644
> --- a/drivers/media/media-entity.c
> +++ b/drivers/media/media-entity.c
> @@ -429,6 +429,57 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
>  }
>  EXPORT_SYMBOL_GPL(media_entity_create_link);
>  
> +void __media_entity_remove_links(struct media_entity *entity)
> +{
> +	int i, r;

u16? r can be defined inside the loop.

> +	for (i = 0; i < entity->num_links; i++) {
> +		struct media_link *link = &entity->links[i];
> +		struct media_entity *remote;
> +		int num_links;

num_links is u16 in struct media_entity. I'd use the same type.

> +		if (link->source->entity == entity)
> +			remote = link->sink->entity;
> +		else
> +			remote = link->source->entity;
> +
> +		num_links = remote->num_links;
> +
> +		for (r = 0; r < num_links; r++) {

Is caching remote->num_links needed, or do I miss something?

> +			struct media_link *rlink = &remote->links[r];
> +
> +			if (rlink != link->reverse)
> +				continue;
> +
> +			if (link->source->entity == entity)
> +				remote->num_backlinks--;
> +
> +			remote->num_links--;
> +
> +			if (remote->num_links < 1)

How about: if (!remote->num_links) ?

> +				break;
> +
> +			/* Insert last entry in place of the dropped link. */
> +			remote->links[r--] = remote->links[remote->num_links];
> +		}
> +	}
> +
> +	entity->num_links = 0;
> +	entity->num_backlinks = 0;
> +}
> +EXPORT_SYMBOL_GPL(__media_entity_remove_links);
> +
> +void media_entity_remove_links(struct media_entity *entity)
> +{
> +	if (WARN_ON_ONCE(entity->parent == NULL))
> +		return;
> +
> +	mutex_lock(&entity->parent->graph_mutex);
> +	__media_entity_remove_links(entity);
> +	mutex_unlock(&entity->parent->graph_mutex);
> +}
> +EXPORT_SYMBOL_GPL(media_entity_remove_links);
> +
>  static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
>  {
>  	int ret;

-- 
Cheers,

Sakari Ailus
e-mail: sakari.ailus@xxxxxx	XMPP: sailus@xxxxxxxxxxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux