[svn-commits] sruffell: linux/trunk r10626 - /linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue Apr 3 14:44:44 CDT 2012
Author: sruffell
Date: Tue Apr 3 14:44:41 2012
New Revision: 10626
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=10626
Log:
dahdi_dynamic_eth: Make ztdeth_exit() symetrical with ztdeth_init() and fix race on unload.
Minor change to follow generally recommended practice. Prevents new packets
from being queued up for devices when they are about to be cleaned up. Also
clean up any skbs that may still be on the queue after unloading.
Also closes anoter potential kernel oops on module unload. It was possible to
delete the private structure while the master span process was running. The
result was an attempt to page memory from interrupt context.
Make sure that the pvt function is set and cleared under the zlock. Also do
not assume that the pvt pointer is valid in ztdeth_transmit.
Signed-off-by: Shaun Ruffell <sruffell at digium.com>
Modified:
linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c
Modified: linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c?view=diff&rev=10626&r1=10625&r2=10626
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c (original)
+++ linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c Tue Apr 3 14:44:41 2012
@@ -146,7 +146,7 @@
spin_lock_irqsave(&zlock, flags);
z = dyn->pvt;
- if (z->dev) {
+ if (z && z->dev) {
/* Copy fields to local variables to remove spinlock ASAP */
dev = z->dev;
memcpy(addr, z->addr, sizeof(z->addr));
@@ -307,11 +307,12 @@
prev = cur;
cur = cur->next;
}
- spin_unlock_irqrestore(&zlock, flags);
if (cur == z) { /* Successfully removed */
+ dyn->pvt = NULL;
printk(KERN_INFO "TDMoE: Removed interface for %s\n", z->span->name);
kfree(z);
}
+ spin_unlock_irqrestore(&zlock, flags);
}
static int ztdeth_create(struct dahdi_dynamic *dyn, const char *addr)
@@ -434,12 +435,12 @@
static int __init ztdeth_init(void)
{
+ skb_queue_head_init(&skbs);
+
dev_add_pack(&ztdeth_ptype);
register_netdevice_notifier(&ztdeth_nblock);
dahdi_dynamic_register_driver(&ztd_eth);
- skb_queue_head_init(&skbs);
-
return 0;
}
@@ -450,9 +451,11 @@
#else
cancel_work_sync(&dahdi_dynamic_eth_flush_work);
#endif
+ dahdi_dynamic_unregister_driver(&ztd_eth);
+ unregister_netdevice_notifier(&ztdeth_nblock);
dev_remove_pack(&ztdeth_ptype);
- unregister_netdevice_notifier(&ztdeth_nblock);
- dahdi_dynamic_unregister_driver(&ztd_eth);
+
+ skb_queue_purge(&skbs);
}
MODULE_DESCRIPTION("DAHDI Dynamic TDMoE Support");
More information about the svn-commits
mailing list