[PATCH] (1/9) free_netdev - free network device on last class_device usage

flat view
DORMANTno replies

From: Stephen Hemminger <hidden>
Date: 2003-08-19 19:18:06

This patch adds the free_netdev function and associated
changes so that net_device structures are not freed until
last reference to the network device class is released.

diff -urNp -X dontdiff linux-2.5/include/linux/netdevice.h net-dev-2.5/include/linux/netdevice.h
--- linux-2.5/include/linux/netdevice.h	2003-08-18 09:20:55.749112711 -0700
+++ net-dev-2.5/include/linux/netdevice.h	2003-08-18 09:43:45.159545904 -0700
@@ -384,6 +384,7 @@ struct net_device
 	       NETREG_REGISTERED,	/* completed register todo */
 	       NETREG_UNREGISTERING,	/* called unregister_netdevice */
 	       NETREG_UNREGISTERED,	/* completed unregister todo */
+	       NETREG_RELEASED,		/* called free_netdev */
 	} reg_state;
 
 	/* Net device features */
@@ -516,6 +517,7 @@ extern int		dev_close(struct net_device 
 extern int		dev_queue_xmit(struct sk_buff *skb);
 extern int		register_netdevice(struct net_device *dev);
 extern int		unregister_netdevice(struct net_device *dev);
+extern void		free_netdev(struct net_device *dev);
 extern void		synchronize_net(void);
 extern int 		register_netdevice_notifier(struct notifier_block *nb);
 extern int		unregister_netdevice_notifier(struct notifier_block *nb);
diff -urNp -X dontdiff linux-2.5/net/core/dev.c net-dev-2.5/net/core/dev.c
--- linux-2.5/net/core/dev.c	2003-08-18 09:20:55.831097541 -0700
+++ net-dev-2.5/net/core/dev.c	2003-08-18 09:43:45.991391795 -0700
@@ -2643,7 +2643,7 @@ int register_netdevice(struct net_device
 	ASSERT_RTNL();
 
 	/* When net_device's are persistent, this will be fatal. */
-	WARN_ON(dev->reg_state != NETREG_UNINITIALIZED);
+	BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
 
 	spin_lock_init(&dev->queue_lock);
 	spin_lock_init(&dev->xmit_lock);
@@ -2788,6 +2788,8 @@ static void netdev_wait_allrefs(struct n
  *	unregister_netdevice(y2);
  *      ...
  *	rtnl_unlock();
+ *	free_netdev(y1);
+ *	free_netdev(y2);
  *
  * We are invoked by rtnl_unlock() after it drops the semaphore.
  * This allows us to deal with problems:
@@ -2827,7 +2829,7 @@ void netdev_run_todo(void)
 			break;
 
 		case NETREG_UNREGISTERING:
-			class_device_unregister(&dev->class_dev);
+			class_device_del(&dev->class_dev);
 			dev->reg_state = NETREG_UNREGISTERED;
 
 			netdev_wait_allrefs(dev);
@@ -2856,6 +2858,29 @@ void netdev_run_todo(void)
 	up(&net_todo_run_mutex);
 }
 
+/**
+ *	free_netdev - free network device
+ *	@dev: device
+ *
+ *	This function does the last stage of destroying an allocated device 
+ * 	interface. The reference to the device object is released.  
+ *	If this is the last reference then it will be freed.
+ */
+void free_netdev(struct net_device *dev)
+{
+	/*  Compatiablity with error handling in drivers */
+	if (dev->reg_state == NETREG_UNINITIALIZED) {
+		kfree(dev);
+		return;
+	}
+
+	BUG_ON(dev->reg_state != NETREG_UNREGISTERED);
+	dev->reg_state = NETREG_RELEASED;
+
+	/* will free via class release */
+	class_device_put(&dev->class_dev);
+}
+ 
 /* Synchronize with packet receive processing. */
 void synchronize_net(void) 
 {
diff -urNp -X dontdiff linux-2.5/net/core/net-sysfs.c net-dev-2.5/net/core/net-sysfs.c
--- linux-2.5/net/core/net-sysfs.c	2003-08-18 09:20:55.833097171 -0700
+++ net-dev-2.5/net/core/net-sysfs.c	2003-08-18 09:43:45.996390869 -0700
@@ -361,8 +361,23 @@ static int netdev_hotplug(struct class_d
 }
 #endif
 
+/*
+ *	netdev_release -- destroy and free a dead device. 
+ *	Called when last reference to class_device kobject is gone.
+ */
+static void netdev_release(struct class_device *cd)
+{
+	struct net_device *dev 
+		= container_of(cd, struct net_device, class_dev);
+
+	BUG_ON(dev->reg_state != NETREG_RELEASED);
+
+	kfree(dev);
+}
+
 static struct class net_class = {
 	.name = "net",
+	.release = netdev_release,
 #ifdef CONFIG_HOTPLUG
 	.hotplug = netdev_hotplug,
 #endif
diff -urNp -X dontdiff linux-2.5/net/netsyms.c net-dev-2.5/net/netsyms.c
--- linux-2.5/net/netsyms.c	2003-08-18 09:20:55.822099206 -0700
+++ net-dev-2.5/net/netsyms.c	2003-08-18 09:43:45.943400686 -0700
@@ -480,6 +480,7 @@ EXPORT_SYMBOL(call_netdevice_notifiers);
 EXPORT_SYMBOL(loopback_dev);
 EXPORT_SYMBOL(register_netdevice);
 EXPORT_SYMBOL(unregister_netdevice);
+EXPORT_SYMBOL(free_netdev);
 EXPORT_SYMBOL(synchronize_net);
 EXPORT_SYMBOL(netdev_state_change);
 EXPORT_SYMBOL(netdev_boot_setup_check);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help