[SSI] openssi/kernel/cluster/ssi/util ssidev.c,1.27,1.28

Roger Tsang <[email protected]>
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv17937/cluster/ssi/util

Modified Files:
      Tag: OPENSSI-FC
	ssidev.c 
Log Message:
SSIDEV:
- Comment out unused ssidev_ssi_hash[] array and related.
- Use list_for_each_entry().
- Fix race reading invalid ssidev_hash_t structure.

SSIDEV (#ifdef SSIDEV_HASH_KMEM_CACHE):
- Fix ssidev_hash_t memory leak.
- Optimize away kfree/kmalloc when allocating from ssidev_free_list.


Index: ssidev.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/ssidev.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- ssidev.c	27 Oct 2009 03:18:29 -0000	1.27
+++ ssidev.c	2 Feb 2010 05:00:11 -0000	1.28
@@ -55,8 +55,11 @@
 #define SSIDEV_HASH_LINUXDEV(_node, _mode, _dev) \
 	(((MAJOR(_dev) << 6) + ((_node) << 3) + MINOR(_dev)) \
 	 & (SSIDEV_HASH_SIZE - 1))
+
+#ifdef SSI_NOTUSED
 #define SSIDEV_HASH_SSIDEV(_dev) \
 	((_dev) & (SSIDEV_HASH_SIZE - 1))
+#endif
 
 #define SSIDEV_POLLEV	(POLLERR | POLLHUP | POLLNVAL)
 
@@ -73,7 +76,9 @@
 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(ssidev_spinlock);
 #endif
 static ssidev_hash_t	*ssidev_linux_hash[SSIDEV_HASH_SIZE];
+#ifdef SSI_NOTUSED
 static ssidev_hash_t	*ssidev_ssi_hash[SSIDEV_HASH_SIZE];
+#endif
 static ssidev_hash_t	*ssidev_last;
 static LIST_HEAD(ssidev_unique_list);
 static LIST_HEAD(ssidev_free_list);
@@ -133,6 +138,7 @@
 	return hp;
 }
 
+#ifdef SSI_NOTUSED
 /* Called under ssidev_lock */
 static ssidev_hash_t *
 ssidev_search_ssitolinux(dev_t ssidev)
@@ -150,12 +156,16 @@
 
 	return hp;
 }
+#endif
 
 /* Called under ssidev_lock */
 static inline void ssidev_add(ssidev_hash_t *newp, clusternode_t devnode,
 			      int mode, dev_t linuxdev, dev_t ssidev)
 {
-	int lhash, shash;
+	int lhash;
+#ifdef SSI_NOTUSED
+	int shash;
+#endif
 
 	newp->sd_data.sd_devnode = devnode;
 	newp->sd_data.sd_ssidev = ssidev;
@@ -166,9 +176,11 @@
 	newp->sd_linuxnext = (void *)ssidev_linux_hash[lhash];
 	ssidev_linux_hash[lhash] = newp;
 
+#ifdef SSI_NOTUSED
 	shash = SSIDEV_HASH_SSIDEV(ssidev);
 	newp->sd_ssinext = (void *)ssidev_ssi_hash[shash];
 	ssidev_ssi_hash[shash] = newp;
+#endif
 }
 
 #ifdef SSIDEV_LOCK_MUTEX
@@ -258,7 +270,6 @@
 ssidev_add_last(ssidev_hash_data_t *dp)
 {
 	ssidev_hash_t *newp;
-	struct list_head *lp;
 	ssidev_hash_t *hp;
 
 	if (dp->sd_devnode != CLUSTERNODE_INVAL) {
@@ -302,8 +313,7 @@
 			list_add(&newp->sd_list, &ssidev_unique_list);
 		} else {
 			newp = NULL;
-			list_for_each(lp, &ssidev_unique_list) {
-				hp = list_entry(lp, ssidev_hash_t, sd_list);
+			list_for_each_entry(hp, &ssidev_unique_list, sd_list) {
 				if (hp->sd_data.sd_ssidev == dp->sd_ssidev) {
 					list_del(&hp->sd_list);
 					newp = hp;
@@ -379,14 +389,14 @@
 {
 	ssidev_hash_t *hp;
 	ssidev_hash_data_t *dp;
-	int i;
-	struct list_head *lp;
 
 	(void)to_node;
 	*rerror = 0;
 	ssidev_lock_busy();
 	ics_chunk_init(datap, sizeof(ssidev_hash_data_t));
 	if (secondary) {
+#ifdef SSI_NOTUSED
+		int i;
 		for (i = 0; i < SSIDEV_HASH_SIZE; i++) {
 			hp = ssidev_ssi_hash[i];
 			while (hp != NULL) {
@@ -395,13 +405,12 @@
 				hp = (void *)hp->sd_ssinext;
 			}
 		}
-		list_for_each(lp, &ssidev_free_list) {
-			hp = list_entry(lp, ssidev_hash_t, sd_list);
+#endif
+		list_for_each_entry(hp, &ssidev_free_list, sd_list) {
 			dp = ics_chunk_add_entry(datap);
 			*dp = hp->sd_data;
 		}
-		list_for_each(lp, &ssidev_unique_list) {
-			hp = list_entry(lp, ssidev_hash_t, sd_list);
+		list_for_each_entry(hp, &ssidev_unique_list, sd_list) {
 			dp = ics_chunk_add_entry(datap);
 			*dp = hp->sd_data;
 		}
@@ -423,6 +432,32 @@
 }
 
 /* Called under ssidev_lock */
+#ifdef SSIDEV_HASH_KMEM_CACHE
+static ssidev_hash_t *
+ssidev_alloc_next(dev_t *ssidevp)
+{
+	ssidev_hash_t *hp;
+
+	if (!list_empty(&ssidev_free_list)) {
+		hp = list_entry(ssidev_free_list.next, ssidev_hash_t, sd_list);
+		list_del(&hp->sd_list);
+		*ssidevp = hp->sd_data.sd_ssidev;
+		return hp;
+	}
+
+	if (ssidev_current >= SSIDEV_LAST) {
+		printk(KERN_WARNING "%s: Out of devices\n", __FUNCTION__);
+		return ERR_PTR(-ERANGE);
+	}
+
+	hp = kmem_cache_alloc(ssidev_hash_cachep, SLAB_KERNEL);
+	if (hp == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	*ssidevp = ssidev_current++;
+	return hp;
+}
+#else /* SSIDEV_HASH_KMEM_CACHE */
 static int ssidev_alloc_next(dev_t *ssidevp)
 {
 	ssidev_hash_t *hp;
@@ -431,11 +466,7 @@
 		hp = list_entry(ssidev_free_list.next, ssidev_hash_t, sd_list);
 		list_del(&hp->sd_list);
 		*ssidevp = hp->sd_data.sd_ssidev;
-#ifdef SSIDEV_HASH_KMEM_CACHE
-		kmem_cache_free(ssidev_hash_cachep, hp);
-#else
 		kfree(hp);
-#endif
 		return 0;
 	}
 	if (ssidev_current < SSIDEV_LAST) {
@@ -445,6 +476,7 @@
 	printk(KERN_WARNING "%s: Out of devices\n", __FUNCTION__);
 	return -ERANGE;
 }
+#endif /* !SSIDEV_HASH_KMEM_CACHE */
 
 int
 rssidev_new(clusternode_t to_node, int *rerror,
@@ -454,15 +486,13 @@
 	ssidev_hash_t *hp;
 
 	(void)to_node;
-#ifdef SSIDEV_HASH_KMEM_CACHE
-	newp = kmem_cache_alloc(ssidev_hash_cachep, SLAB_KERNEL);
-#else
+#ifndef SSIDEV_HASH_KMEM_CACHE
 	newp = kmalloc(sizeof(*newp), GFP_KERNEL);
-#endif
 	if (newp == NULL) {
 		*rerror = -ENOMEM;
 		return 0;
 	}
+#endif
 	ssidev_lock();
 	hp = ssidev_search_linuxtossi(devnode, mode, linuxdev);
 	if (hp != NULL) {
@@ -472,17 +502,20 @@
 		return 0;
 	}
 	ssidev_lock_makebusy();
+#ifdef SSIDEV_HASH_KMEM_CACHE
+	newp = ssidev_alloc_next(ssidevp);
+	if (IS_ERR(newp)) {
+		*rerror = PTR_ERR(newp);
+	} else {
+		*rerror = 0;
+#else
 	*rerror = ssidev_alloc_next(ssidevp);
 	if (*rerror == 0) {
+#endif
 		ssidev_add(newp, devnode, mode, linuxdev, *ssidevp);
 		ssidev_broadcast_new(newp);
 	}
-#ifdef SSIDEV_HASH_KMEM_CACHE
-	else
-		kmem_cache_free(ssidev_hash_cachep, newp);
-#endif
 	ssidev_unlock();
-
 	return 0;
 }
 
@@ -492,18 +525,24 @@
 	ssidev_hash_t *newp;
 
 	(void)to_node;
-#ifdef SSIDEV_HASH_KMEM_CACHE
-	newp = kmem_cache_alloc(ssidev_hash_cachep, SLAB_KERNEL);
-#else
+#ifndef SSIDEV_HASH_KMEM_CACHE
 	newp = kmalloc(sizeof(*newp), GFP_KERNEL);
-#endif
 	if (newp == NULL) {
 		*rerror = -ENOMEM;
 		return 0;
 	}
+#endif
 	ssidev_lock_busy();
+#ifdef SSIDEV_HASH_KMEM_CACHE
+	newp = ssidev_alloc_next(ssidevp);
+	if (IS_ERR(newp)) {
+		*rerror = PTR_ERR(newp);
+	} else {
+		*rerror = 0;
+#else
 	*rerror = ssidev_alloc_next(ssidevp);
 	if (*rerror == 0) {
+#endif
 		INIT_LIST_HEAD(&newp->sd_list);
 		newp->sd_data.sd_devnode = CLUSTERNODE_INVAL;
 		newp->sd_data.sd_ssidev = *ssidevp;
@@ -512,12 +551,7 @@
 		list_add(&newp->sd_list, &ssidev_unique_list);
 		ssidev_broadcast_new(newp);
 	}
-#ifdef SSIDEV_HASH_KMEM_CACHE
-	else
-		kmem_cache_free(ssidev_hash_cachep, newp);
-#endif
 	ssidev_unlock();
-
 	return 0;
 }
 
@@ -525,12 +559,10 @@
 rssidev_put_unique(clusternode_t to_node, int *rerror, dev_t ssidev)
 {
 	ssidev_hash_t *hp;
-	struct list_head *lp;
 
 	*rerror = -ENOENT;
 	ssidev_lock_busy();
-	list_for_each(lp, &ssidev_unique_list) {
-		hp = list_entry(lp, ssidev_hash_t, sd_list);
+	list_for_each_entry(hp, &ssidev_unique_list, sd_list) {
 		if (hp->sd_data.sd_ssidev == ssidev) {
 			list_del(&hp->sd_list);
 			hp->sd_data.sd_mode = 1;
@@ -564,9 +596,12 @@
 	SSI_ASSERT(devnode != CLUSTERNODE_INVAL);
 	ssidev_lock();
 	hp = ssidev_search_linuxtossi(devnode, mode, linuxdev);
+	if (hp) {
+		ssidev = hp->sd_data.sd_ssidev;
+		ssidev_unlock();
+		return ssidev;
+	}
 	ssidev_unlock();
-	if (hp != NULL)
-		return hp->sd_data.sd_ssidev;
 	error = ssidev_new(devnode, mode, linuxdev, &ssidev);
 	if (error >= 0) {
 		if (this_node != ssidev_node && !ssidev_secondary) {
@@ -589,6 +624,7 @@
 	return NODEV;
 }
 
+#ifdef SSI_NOTUSED
 dev_t ssidev_ssitolinux(dev_t ssidev, int *mode)
 {
 	ssidev_hash_t	*hp;
@@ -606,6 +642,7 @@
 
 	return NODEV;
 }
+#endif
 
 static void
 ssidev_snap_failover_data(ssidev_failover_data_t *fp)


------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.