[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