[PATCH 3/5] staging: vme: add functions for bridge module refcounting

Emilio G. Cota cota at braap.org
Sat Aug 13 07:47:14 UTC 2011


On Fri, Aug 12, 2011 at 12:30:49 +0200, Manohar Vanga wrote:
> This patch adds functions that allow for reference counting
> bridge modules. The patch introduces the functions
> 'vme_bridge_get()' and 'vme_bridge_put()'.
> 
> The functions are automatically called during .probe and .remove
> for drivers.
(snip)
> @@ -52,6 +52,48 @@ static struct vme_bridge *dev_to_bridge(struct device *dev)
(snip)
> +int vme_bridge_get(unsigned int bus_id)

If it isn't exported, it should be declared as static.

> +{
> +	int ret = -1;

hmm perhaps -ENXIO here would be better, since the outcome
of this function is either that or success.

> +	struct vme_bridge *bridge;
> +
> +	mutex_lock(&vme_buses_lock);
> +	list_for_each_entry(bridge, &vme_bus_list, bus_list) {
> +		if (bridge->num == bus_id) {
> +			if (!bridge->owner)
> +				dev_warn(bridge->parent,
> +					"bridge->owner not set\n");

Don't do this; it will throw a false warning if the kernel is
built without module support. Note that in that case

	THIS_MODULE == (struct module *)0.

try_module_get() and module_put() do the right thing for all
possible configs. Trust them.

> +			else if (try_module_get(bridge->owner))
> +				ret = 0;
> +			break;
> +void vme_bridge_put(struct vme_bridge *bridge)

should be static as well

> +{
> +	if (!bridge->owner)
> +		dev_warn(bridge->parent, "bridge->owner not set\n");
> +	else
> +		module_put(bridge->owner);

ditto, remove the warning.

> +
> +/*
>   * Find the bridge that the resource is associated with.
>   */
>  static struct vme_bridge *find_bridge(struct vme_resource *resource)
> @@ -1496,14 +1538,20 @@ static int vme_bus_probe(struct device *dev)
>  {
>  	struct vme_bridge *bridge;
>  	struct vme_driver *driver;
> -	int retval = -ENODEV;
> +	int retval = 0;
>  
>  	driver = dev_to_vme_driver(dev);
>  	bridge = dev_to_bridge(dev);
>  
> +	if (vme_bridge_get(bridge->num))
> +		return -ENXIO;
> +
>  	if (driver->probe != NULL)
>  		retval = driver->probe(dev, bridge->num, vme_calc_slot(dev));
>  
> +	if (driver->probe && retval)
> +		vme_bridge_put(bridge);

If the driver doesn't provide a .probe, we would still increment
the refcount of the bridge module. Is that reasonable? I dunno.

If there's no .probe then the device is doing something
weird, and probably either it doesn't have much to do with a
particular bridge (i.e. it manages no "real" devices) or
it'd need to manage its own resources (in which case we could
easily export vme_bridge_get/put.)

Perhaps then the following would be more appropriate,
what do you think?

+	if (driver->probe) {
+		if (vme_bridge_get(bridge->num))
+			return -ENXIO; /* although this could change, see above comment */
+
 		retval = driver->probe(dev, bridge->num, vme_calc_slot(dev));
+		if (retval)
+			vme_bridge_put(bridge);
+	}
+
 	return retval;

.. and then remember to do
+ 	if (probe)
+ 		vme_bridge_put(bridge)
in vme_bus_remove(), which in your patch is unconditional (correctly
matching the unconditional get() in vme_bus_probe)

> @@ -1519,6 +1567,8 @@ static int vme_bus_remove(struct device *dev)
>  	if (driver->remove != NULL)
>  		retval = driver->remove(dev, bridge->num, vme_calc_slot(dev));
>  
> +	vme_bridge_put(bridge);
> +
>  	return retval;
>  }
> diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h
> index 4155d8c..eb00a5e 100644
> --- a/drivers/staging/vme/vme.h
> +++ b/drivers/staging/vme/vme.h
> @@ -165,6 +165,5 @@ int vme_slot_get(struct device *);
>  int vme_register_driver(struct vme_driver *);
>  void vme_unregister_driver(struct vme_driver *);
>  
> -
>  #endif /* _VME_H_ */

I'm certainly no checkpatch taliban, but guess you probably
didn't want to send this line change.

Cheers

		Emilio




More information about the devel mailing list