[svn-commits] sruffell: branch linux/2.6 r10629 - /linux/branches/2.6/drivers/dahdi/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Apr 3 15:10:12 CDT 2012


Author: sruffell
Date: Tue Apr  3 15:10:08 2012
New Revision: 10629

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=10629
Log:
dahdi_dynamic: Remove calls to __module_get().

The board drivers are the ones calling the unregister function, and
therefore we do not need to worry about them unloading while calling the
destroy callback.

When destroying spans with the ioctl, replace __module_get() with
try_module_get. This avoids hitting a BUG in module_get on kernel versions <
2.6.29.

ALSO move the call to try_module_get out of the dahdi_dynamic_release function
and into destroy. This way if the destroy callback isn't called because the
dynamic driver is unloading the dynamic device can be left on the list to be
cleaned up by the dahdi_dynamic_unregister_driver function().

Signed-off-by: Shaun Ruffell <sruffell at digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10624

Modified:
    linux/branches/2.6/drivers/dahdi/dahdi_dynamic.c

Modified: linux/branches/2.6/drivers/dahdi/dahdi_dynamic.c
URL: http://svnview.digium.com/svn/dahdi/linux/branches/2.6/drivers/dahdi/dahdi_dynamic.c?view=diff&rev=10629&r1=10628&r2=10629
==============================================================================
--- linux/branches/2.6/drivers/dahdi/dahdi_dynamic.c (original)
+++ linux/branches/2.6/drivers/dahdi/dahdi_dynamic.c Tue Apr  3 15:10:08 2012
@@ -385,16 +385,6 @@
 
 	WARN_ON(test_bit(DAHDI_FLAGBIT_REGISTERED, &d->span.flags));
 
-	if (d->pvt) {
-		if (d->driver && d->driver->destroy) {
-			__module_get(d->driver->owner);
-			d->driver->destroy(d);
-			module_put(d->driver->owner);
-		} else {
-			WARN_ON(1);
-		}
-	}
-
 	kfree(d->msgbuf);
 
 	for (x = 0; x < d->span.channels; x++)
@@ -468,6 +458,24 @@
 	if (atomic_read(&d->kref.refcount) > 2) {
 		dynamic_put(d);
 		return -EBUSY;
+	}
+
+	if (d->pvt) {
+		if (d->driver && d->driver->destroy) {
+			if (!try_module_get(d->driver->owner)) {
+				/* The driver for this device is in the
+				 * process of unloading. Leave this dynamic on
+				 * the list so it's cleaned up when the driver
+				 * unregisters. */
+				 dynamic_put(d);
+				 return -ENXIO;
+			}
+			d->driver->destroy(d);
+			module_put(d->driver->owner);
+		} else {
+			WARN_ON(1);
+		}
+		d->pvt = NULL;
 	}
 
 	dahdi_unregister_device(d->ddev);
@@ -767,19 +775,17 @@
 	list_for_each_entry_safe(d, n, &dspan_list, list) {
 		if (d->driver == dri) {
 			if (d->pvt) {
-				if (d->driver && d->driver->destroy) {
-					__module_get(d->driver->owner);
+				if (d->driver && d->driver->destroy)
 					d->driver->destroy(d);
-					module_put(d->driver->owner);
-				} else {
+				else
 					WARN_ON(1);
-				}
 			}
 			dahdi_unregister_device(d->ddev);
 			spin_lock_irqsave(&dspan_lock, flags);
 			list_del_rcu(&d->list);
 			spin_unlock_irqrestore(&dspan_lock, flags);
 			synchronize_rcu();
+			d->driver = NULL;
 			dynamic_put(d);
 		}
 	}




More information about the svn-commits mailing list