netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] (1/4) remove hashbin from irlan
@ 2003-08-18 18:39 Stephen Hemminger
  2003-08-18 19:00 ` Jean Tourrilhes
  2003-08-20  4:13 ` David S. Miller
  0 siblings, 2 replies; 4+ messages in thread
From: Stephen Hemminger @ 2003-08-18 18:39 UTC (permalink / raw)
  To: Jean Tourrilhes, David S. Miller; +Cc: irda-users, netdev

The locking in hashbin_delete is a problem since unregister_netdevice
can't be called with locks held in 2.6.0-test3.

Replace it with simpler list macros.
Insertion/deletion protected with RTNL semaphore, and read
uses RCU.

Don't have client hardware to test, but load/unload works on SMP.

diff -Nru a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h
--- a/include/net/irda/irlan_common.h	Mon Aug 18 11:09:06 2003
+++ b/include/net/irda/irlan_common.h	Mon Aug 18 11:09:06 2003
@@ -33,7 +33,6 @@
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 
-#include <net/irda/irqueue.h>
 #include <net/irda/irttp.h>
 
 #define IRLAN_MTU        1518
@@ -161,9 +160,8 @@
  *  IrLAN control block
  */
 struct irlan_cb {
-	irda_queue_t q; /* Must be first */
-
 	int    magic;
+	struct list_head  dev_list;
 	struct net_device dev;        /* Ethernet device structure*/
 	struct net_device_stats stats;
 
@@ -204,6 +202,7 @@
 
 int irlan_run_ctrl_tx_queue(struct irlan_cb *self);
 
+struct irlan_cb *irlan_get_any(void);
 void irlan_get_provider_info(struct irlan_cb *self);
 void irlan_get_unicast_addr(struct irlan_cb *self);
 void irlan_get_media_char(struct irlan_cb *self);
@@ -221,8 +220,6 @@
 
 int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len);
 void print_ret_code(__u8 code);
-
-extern hashbin_t *irlan;
 
 #endif
 
diff -Nru a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c
--- a/net/irda/irlan/irlan_client.c	Mon Aug 18 11:09:06 2003
+++ b/net/irda/irlan/irlan_client.c	Mon Aug 18 11:09:06 2003
@@ -154,7 +154,6 @@
 	
 	IRDA_DEBUG(1, "%s()\n", __FUNCTION__ );
 
-	ASSERT(irlan != NULL, return;);
 	ASSERT(discovery != NULL, return;);
 
 	/*
@@ -170,7 +169,8 @@
 	daddr = discovery->daddr;
 
 	/* Find instance */
-	self = (struct irlan_cb *) hashbin_get_first(irlan);
+	rcu_read_lock();
+	self = irlan_get_any();
 	if (self) {
 		ASSERT(self->magic == IRLAN_MAGIC, return;);
 
@@ -179,6 +179,7 @@
 		
 		irlan_client_wakeup(self, saddr, daddr);
 	}
+	rcu_read_unlock();
 }
 	
 /*
diff -Nru a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
--- a/net/irda/irlan/irlan_common.c	Mon Aug 18 11:09:06 2003
+++ b/net/irda/irlan/irlan_common.c	Mon Aug 18 11:09:06 2003
@@ -33,6 +33,7 @@
 #include <linux/proc_fs.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -63,7 +64,8 @@
 /*
  *  Master structure
  */
-hashbin_t *irlan = NULL;
+static LIST_HEAD(irlans);
+
 static void *ckey;
 static void *skey;
 
@@ -124,12 +126,6 @@
 	__u16 hints;
 
 	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
-	/* Allocate master structure */
-	irlan = hashbin_new(HB_LOCK);	/* protect from /proc */
-	if (irlan == NULL) {
-		printk(KERN_WARNING "IrLAN: Can't allocate hashbin!\n");
-		return -ENOMEM;
-	}
 #ifdef CONFIG_PROC_FS
 	create_proc_info_entry("irlan", 0, proc_irda, irlan_proc_read);
 #endif /* CONFIG_PROC_FS */
@@ -158,6 +154,8 @@
 
 void __exit irlan_cleanup(void) 
 {
+	struct irlan_cb *self, *next;
+
 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	irlmp_unregister_client(ckey);
@@ -166,10 +164,13 @@
 #ifdef CONFIG_PROC_FS
 	remove_proc_entry("irlan", proc_irda);
 #endif /* CONFIG_PROC_FS */
-	/*
-	 *  Delete hashbin and close all irlan client instances in it
-	 */
-	hashbin_delete(irlan, (FREE_FUNC) __irlan_close);
+
+	/* Cleanup any leftover network devices */
+	rtnl_lock();
+	list_for_each_entry_safe(self, next, &irlans, dev_list) {
+		__irlan_close(self);
+	}
+	rtnl_unlock();
 }
 
 /*
@@ -210,7 +211,6 @@
 	struct irlan_cb *self;
 
 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
-	ASSERT(irlan != NULL, return NULL;);
 
 	/* 
 	 *  Initialize the irlan structure. 
@@ -243,7 +243,7 @@
 	init_timer(&self->client.kick_timer);
 	init_waitqueue_head(&self->open_wait);	
 
-	hashbin_insert(irlan, (irda_queue_t *) self, daddr, NULL);
+	list_add_rcu(&self->dev_list, &irlans);
 	
 	skb_queue_head_init(&self->client.txq);
 	
@@ -258,8 +258,7 @@
  * Function __irlan_close (self)
  *
  *    This function closes and deallocates the IrLAN client instances. Be 
- *    aware that other functions which calles client_close() must call 
- *    hashbin_remove() first!!!
+ *    aware that other functions which calles client_close()
  */
 static void __irlan_close(struct irlan_cb *self)
 {
@@ -267,6 +266,7 @@
 
 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 	
+	ASSERT_RTNL();
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
 
@@ -283,12 +283,23 @@
 	while ((skb = skb_dequeue(&self->client.txq)))
 		dev_kfree_skb(skb);
 
-	unregister_netdev(&self->dev);
+	unregister_netdevice(&self->dev);
 	
 	self->magic = 0;
 	kfree(self);
 }
 
+/* Find any instance of irlan, used for client discovery wakeup */
+struct irlan_cb *irlan_get_any(void)
+{
+	struct irlan_cb *self;
+
+	list_for_each_entry_rcu(self, &irlans, dev_list) {
+		return self;
+	}
+	return NULL;
+}
+
 /*
  * Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb)
  *
@@ -1086,18 +1097,16 @@
  */
 static int irlan_proc_read(char *buf, char **start, off_t offset, int len)
 {
- 	struct irlan_cb *self;
-	unsigned long flags;
-	ASSERT(irlan != NULL, return 0;);
+	struct irlan_cb *self;
      
 	len = 0;
 	
-	spin_lock_irqsave(&irlan->hb_spinlock, flags);
+	rcu_read_lock();
 
 	len += sprintf(buf+len, "IrLAN instances:\n");
 	
-	self = (struct irlan_cb *) hashbin_get_first(irlan);
-	while (self != NULL) {
+	list_for_each_entry_rcu(self, &irlans, dev_list) {
+
 		ASSERT(self->magic == IRLAN_MAGIC, break;);
 		
 		len += sprintf(buf+len, "ifname: %s,\n",
@@ -1126,10 +1135,8 @@
 			       netif_queue_stopped(&self->dev) ? "TRUE" : "FALSE");
 			
 		len += sprintf(buf+len, "\n");
-
-		self = (struct irlan_cb *) hashbin_get_next(irlan);
  	} 
-	spin_unlock_irqrestore(&irlan->hb_spinlock, flags);
+	rcu_read_unlock();
 
 	return len;
 }

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2003-08-20  4:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-08-18 18:39 [PATCH] (1/4) remove hashbin from irlan Stephen Hemminger
2003-08-18 19:00 ` Jean Tourrilhes
2003-08-18 19:34   ` Stephen Hemminger
2003-08-20  4:13 ` David S. Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).