[SSI] openssi/kernel/cluster/ssi/util load_level.c, 1.21, 1.22 rcopy.c, 1.11, 1.12 rmtfb.c, 1.20, 1.21 rmtsock.c, 1.20, 1.21 ssidev.c, 1.23, 1.24 ssidev_ics.c, 1.11, 1.12

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 fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv8553/cluster/ssi/util

Modified Files:
      Tag: OPENSSI-FC
	load_level.c rcopy.c rmtfb.c rmtsock.c ssidev.c ssidev_ics.c 
Log Message:
Bug fixes and enhancements. (see ChangeLog)


Index: rmtsock.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/rmtsock.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- rmtsock.c	7 Aug 2007 03:06:09 -0000	1.20
+++ rmtsock.c	3 Feb 2009 06:18:13 -0000	1.21
@@ -47,7 +47,7 @@
 #include <cluster/gen/ics_rmtfb_macros_gen.h>
 #include <cluster/gen/ics_rmtfb_protos_gen.h>
 
-struct rmtscm_fp_list;
+//struct rmtscm_fp_list;
 
 
 /*
@@ -933,8 +933,10 @@
 #endif
 	}
 
-	if (!siocb->scm)
+	if (!siocb->scm) {
 		siocb->scm = &tmp_scm;
+		memset(&tmp_scm, 0, sizeof(tmp_scm));
+	}
 	error = scm_send(sock, msg, siocb->scm);
 	if (error < 0)
 #ifndef RMTSOCK_SENDMSG_IOVECS

Index: load_level.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/load_level.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- load_level.c	10 Oct 2008 08:10:32 -0000	1.21
+++ load_level.c	3 Feb 2009 06:18:13 -0000	1.22
@@ -46,7 +46,11 @@
 int load_cnt;
 
 /* table used to determine whats loadlevelable */
+#ifdef LOADLEVEL_TABLE_LIST
+LIST_HEAD(loadlevel_table);
+#else
 struct inclusion_list *loadlevel_table;
+#endif
 
 extern clusternode_t clms_master_node;
 int loadlevel_on;
@@ -71,7 +75,11 @@
 #endif /* CONFIG_MOSIX_LL */
 extern void exec_balance(void);
 
+#ifdef LOADLEVEL_TABLE_LIST
+RW_LOCK_T loadlevellist_lock;
+#else
 LOCK_T loadlevellist_lock;
+#endif
 
 #define LOADLOG_DEPTH	64
 #define LOADLVL_MSGS	11
@@ -459,14 +467,18 @@
 	struct vm_area_struct * vma;
 	struct dentry *dentry = NULL;
 	struct vfsmount *mnt = NULL;
+#ifndef LOADLEVEL_TABLE_LIST
 	int held;
+#endif
 
 	if (!loadlist_lockinit || (p->exit_state >= EXIT_ZOMBIE) || 
 			!(p->p_vproc) || (p->p_vproc->vp_pid != p->pid))
 		return 0;
 
 	pvp = PVP(p->p_vproc);
+#ifndef LOADLEVEL_TABLE_LIST
 	held = VPROC_LOCK_EXCL_HELD(p->p_vproc);
+#endif
 	if (pvp->pvp_loadlevel == -1) {
 		if (!fname) {
 			/* Check to see if process has dentry filled in */
@@ -515,6 +527,21 @@
 
 		}
 
+#ifdef LOADLEVEL_TABLE_LIST
+		if (dentry && mnt) {
+			/* check list and set loadlevel field accordingly */
+			LOADLIST_LOCK_SHARED();
+			list_for_each_entry(ent, &loadlevel_table, inc_list) {
+				if (dentry == ent->de && mnt == ent->mnt) {
+					LOADLIST_UNLOCK_SHARED();
+					pvp->pvp_loadlevel = 1;
+					goto out_nolock;
+				}
+			}
+			LOADLIST_UNLOCK_SHARED();
+		}
+		pvp->pvp_loadlevel = 0;
+#else /* !LOADLEVEL_TABLE_LIST */
 		if (!held)
 			if (!TRY_VPROC_LOCK_EXCL(p->p_vproc,"is_loadlevelable"))
 				return 0;
@@ -534,21 +561,26 @@
 		}
 		pvp->pvp_loadlevel = 0;
 		LOADLIST_UNLOCK();
+#endif /* !LOADLEVEL_TABLE_LIST */
 	}
 	else if ((pvp->pvp_loadlevel == 0) && fname) {
+#ifndef LOADLEVEL_TABLE_LIST
 		if (!held)
 			VPROC_LOCK_EXCL(p->p_vproc,"is_loadlevelable");
+#endif
 		/* reset so that it can be resolved again since process is
 		 * about to exec
 		 */
 		pvp->pvp_loadlevel = -1;
 	}
+#ifndef LOADLEVEL_TABLE_LIST
 	else
 		goto out_nolock;
 
 out:
 	if (!held)
 		VPROC_UNLOCK_EXCL(p->p_vproc, "is_loadlevelable");
+#endif
 out_nolock:
 	dput(dentry);
 	mntput(mnt);
@@ -576,8 +608,13 @@
 
 	/* get inclusion list */
 	str = page;
+#ifdef LOADLEVEL_TABLE_LIST
+	LOADLIST_LOCK_SHARED();
+	list_for_each_entry(ptr, &loadlevel_table, inc_list) {
+#else
 	LOADLIST_LOCK();
 	for(ptr = loadlevel_table; ptr != NULL; ptr = ptr->next) {
+#endif
 		path = d_path(ptr->de, ptr->mnt, tmp, PAGE_SIZE);
 		len = tmp + PAGE_SIZE - 1 - path;
 		memcpy(str, path, len);
@@ -586,7 +623,11 @@
 		*str = '\n';
 		str++;
 	}
+#ifdef LOADLEVEL_TABLE_LIST
+	LOADLIST_UNLOCK_SHARED();
+#else
 	LOADLIST_UNLOCK();
+#endif
 	read = off - *ppos;
 	if (read == 0)
 		goto out;
@@ -653,7 +694,12 @@
 ssize_t
 do_write_loadlist(int flags, char * buf, size_t count, loff_t *ppos)
 {
+#ifdef LOADLEVEL_TABLE_LIST
+	struct inclusion_list *ptr, *ent;
+	LIST_HEAD(oldlist);
+#else
 	struct inclusion_list *ptr, *ent, *oldlist = NULL;
+#endif
 	char *line, *str, *tmpbuf;
 	int len, size;
 	struct nameidata nd;
@@ -691,8 +737,12 @@
 	 * will be read in again.  Free oldlist after setting up new list.
 	 */
 	if (!(flags & O_APPEND)) {
+#ifdef LOADLEVEL_TABLE_LIST
+		list_splice_init(&loadlevel_table, &oldlist);
+#else
 		oldlist = loadlevel_table;
 		loadlevel_table = NULL;
+#endif
 	}
 line:
 	for(str = tmpbuf; str && (*str != '\n' && *str != '\0'); str++);
@@ -719,6 +769,11 @@
 
 		ent->de = nd.dentry;
 		ent->mnt = nd.mnt;
+#ifdef LOADLEVEL_TABLE_LIST
+		INIT_LIST_HEAD(&ent->inc_list);
+
+		list_add_tail(&ent->inc_list, &loadlevel_table);
+#else
 		ent->next = NULL;
 
 		ptr = loadlevel_table;
@@ -729,6 +784,7 @@
 			for(; ptr->next; ptr = ptr->next);
 			ptr->next = ent;
 		}
+#endif
 	}
 
 	if (len && write < count)
@@ -746,6 +802,14 @@
 	kfree(line);
 
 	/* Now free oldlist if there is one */
+#ifdef LOADLEVEL_TABLE_LIST
+	list_for_each_entry_safe(ptr, ent, &oldlist, inc_list) {
+		dput(ptr->de);
+		mntput(ptr->mnt);
+		list_del(&ptr->inc_list);
+		kfree(ptr);
+	}
+#else
 	for(ptr = oldlist; ptr != NULL;) {
 		ent = ptr->next;
 		dput(ptr->de);
@@ -753,6 +817,7 @@
 		kfree(ptr);
 		ptr = ent;
 	}
+#endif
 
 	return count;
 }

Index: rcopy.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/rcopy.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- rcopy.c	10 Oct 2008 08:10:32 -0000	1.11
+++ rcopy.c	3 Feb 2009 06:18:13 -0000	1.12
@@ -105,15 +105,8 @@
 	SSI_ASSERT(*data_len <= ICS_MAX_OOL_DATA_SIZE);
 	if (v != NULL) {
 		pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-		p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
 		p = pvp->pvp_pproc;
-#endif
 		SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(v, "rssi_rcopy_from_user(vprocptr v)");
-#endif
 	}
 	else
 		p = NULL;
@@ -136,6 +129,10 @@
 		*rerror = -ESRCH;
 		*data_len = 0;
 	}
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+	if (v)
+		VPROC_RELE(v, "rssi_rcopy_from_user");
+#endif
 
 	return 0;
 }
@@ -155,15 +152,8 @@
 	SSI_ASSERT(data_len <= ICS_MAX_OOL_DATA_SIZE);
 	if (v != NULL) {
 		pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-		p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
 		p = pvp->pvp_pproc;
-#endif
 		SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(v, "rssi_rcopy_to_user(vprocptr v)");
-#endif
 	}
 	else
 		p = NULL;
@@ -178,6 +168,10 @@
 		*rerror = -ESRCH;
 		*n = data_len;
 	}
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+	if (v)
+		VPROC_RELE(v, "rssi_rcopy_to_user");
+#endif
 
 	return 0;
 }
@@ -196,15 +190,8 @@
 	SSI_ASSERT(*data_len <= ICS_MAX_OOL_DATA_SIZE);
 	if (v != NULL) {
 		pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-		p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
 		p = pvp->pvp_pproc;
-#endif
 		SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(v, "rssi_rcopy_strncpy_from_user(vprocptr v)");
-#endif
 	}
 	else
 		p = NULL;
@@ -222,6 +209,10 @@
 		*rerror = -ESRCH;
 		*data_len = 0;
 	}
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+	if (v)
+		VPROC_RELE(v, "rssi_rcopy_strncpy_from_user");
+#endif
 
 	return 0;
 }
@@ -238,15 +229,8 @@
 	SSI_ASSERT(*n <= ICS_MAX_OOL_DATA_SIZE);
 	if (v != NULL) {
 		pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-		p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
 		p = pvp->pvp_pproc;
-#endif
 		SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(v, "rssi_rcopy_strnlen_user(vprocptr v)");
-#endif
 	}
 	else
 		p = NULL;
@@ -256,6 +240,10 @@
 		*rerror = -ESRCH;
 		(*n)++;
 	}
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+	if (v)
+		VPROC_RELE(v, "rssi_rcopy_strnlen_user");
+#endif
 
 	return 0;
 }
@@ -275,15 +263,8 @@
 	SSI_ASSERT(*n <= ICS_MAX_OOL_DATA_SIZE);
 	if (v != NULL) {
 		pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-		p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
 		p = pvp->pvp_pproc;
-#endif
 		SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(v, "rssi_rcopy_clear_user(vprocptr v)");
-#endif
 	}
 	else
 		p = NULL;
@@ -312,6 +293,10 @@
 			*rerror = -ENOMEM;
 	} else
 		*rerror = -ESRCH;
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+	if (v)
+		VPROC_RELE(v, "rssi_rcopy_clear_user");
+#endif
 
 	return 0;
 }

Index: rmtfb.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/rmtfb.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- rmtfb.c	10 Oct 2008 08:10:32 -0000	1.20
+++ rmtfb.c	3 Feb 2009 06:18:13 -0000	1.21
@@ -703,8 +703,13 @@
 		struct pathdata *path,
 		int flags,
 		unsigned long id,
-		clusternode_t svr,
 		short socket_type)
+#elif defined(REOP_EXPORT_PATH_SVRNODE)
+struct rmtfb_cli *
+rmtfb_getcli_id(
+		struct pathdata *path,
+		int flags,
+		unsigned long id)
 #else
 struct rmtfb_cli *
 rmtfb_getcli_id(
@@ -718,8 +723,13 @@
 	struct file *file;
 	struct socket *sock;
 	int loop = 0;
+#ifdef REOP_EXPORT_PATH_SVRNODE
+	int svr = 0;
 
+	if (!path || !(svr = path->svrnode) || inval(id,svr)) {
+#else
 	if (!path || !svr || inval(id,svr)) {
+#endif
 		printk(KERN_ERR "rmtfb_getcli_id: bad arguments\n");
 #ifdef RMTFB_GETCLI_ID__RFB_SERVER_INVAL_FIX
 		WARN_ON(svr == CLUSTERNODE_INVAL);
@@ -948,8 +958,7 @@
 		rmtfb_remote_tty_ino(file, svr);
 #endif
 	file->f_op = &ssidev_remote_fops;
-	rfb = newrfb;
-	file->private_data = rfb;
+	file->private_data = rfb = newrfb;
 	list_add(&rfb->common.rfb_hash, &rmtfb_clitbl[hash(id)]);
 	SSI_ASSERT(ftocli(file) == rfb);
 	UNLOCK_EXCL_RW_LOCK(&rmtfb_clitbl_lock);

Index: ssidev.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/ssidev.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- ssidev.c	10 Oct 2008 08:10:32 -0000	1.23
+++ ssidev.c	3 Feb 2009 06:18:13 -0000	1.24
@@ -63,11 +63,15 @@
 char			ssidev_inited;
 char			ssidev_udev_mounted;
 static char		ssidev_secondary;
-static char		ssidev_busy;
 static char		ssidev_updated;
 volatile clusternode_t	ssidev_node = CLUSTERNODE_INVAL;
 static int		ssidev_transid;
+#ifdef SSIDEV_LOCK_MUTEX
+static DECLARE_MUTEX(ssidev_sem);
+#else
+static char		ssidev_busy;
 static DEFINE_SPINLOCK(ssidev_spinlock);
+#endif
 static ssidev_hash_t	*ssidev_linux_hash[SSIDEV_HASH_SIZE];
 static ssidev_hash_t	*ssidev_ssi_hash[SSIDEV_HASH_SIZE];
 static ssidev_hash_t	*ssidev_last;
@@ -89,6 +93,18 @@
 static void ssidev_broadcast_mount_sem(clusternode_t, pid_t, int);
 static void ssidev_broadcast_failover(void);
 
+#ifdef SSIDEV_HASH_KMEM_CACHE
+static kmem_cache_t *ssidev_hash_cachep;
+#endif
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+static kmem_cache_t *ssidev_poll_node_cachep;
+static void ssidev_poll_node_init(void);
+#endif
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+static kmem_cache_t *ssidev_poll_cli_cachep;
+static void ssidev_poll_cli_init(void);
+#endif
+
 static inline ssidev_hash_t *
 ssidev_search_linuxtossi(clusternode_t devnode, int mode, dev_t linuxdev)
 {
@@ -146,6 +162,12 @@
 	ssidev_ssi_hash[shash] = newp;
 }
 
+#ifdef SSIDEV_LOCK_MUTEX
+#define ssidev_lock()		down(&ssidev_sem)
+#define ssidev_lock_busy	ssidev_lock
+#define ssidev_lock_makebusy()	do { } while(0)
+#define ssidev_unlock()		up(&ssidev_sem)
+#else
 static void
 ssidev_do_locksleep(void)
 {
@@ -191,13 +213,6 @@
 	spin_unlock(&ssidev_spinlock);
 }
 
-static void ssidev_lock_failover(void)
-{
-	if (ssidev_node == this_node)
-		return;
-	ssidev_lock_busy();
-}
-
 static void
 ssidev_unlock(void)
 {
@@ -209,6 +224,24 @@
 	} else
 		spin_unlock(&ssidev_spinlock);
 }
+#endif /* !SSIDEV_LOCK_MUTEX */
+
+static void ssidev_lock_failover(void)
+{
+	if (ssidev_node == this_node)
+		return;
+	ssidev_lock_busy();
+}
+
+#ifdef SSIDEV_HASH_KMEM_CACHE
+static void ssidev_hash_init(void)
+{
+	ssidev_hash_cachep = kmem_cache_create("ssidev_hash",
+				sizeof(ssidev_hash_t), 0,
+				SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+				NULL, NULL);
+}
+#endif
 
 static ssidev_hash_t *
 ssidev_add_last(ssidev_hash_data_t *dp)
@@ -227,7 +260,11 @@
 			list_del(&hp->sd_list);
 			newp = hp;
 		} else
+#ifdef SSIDEV_HASH_KMEM_CACHE
+			newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#else
 			newp = kmalloc_nofail(sizeof(*newp));
+#endif
 		ssidev_add(newp, dp->sd_devnode, dp->sd_mode,
 			   dp->sd_linuxdev, dp->sd_ssidev);
 	} else {
@@ -243,7 +280,11 @@
 				newp = hp;
 				newp->sd_data.sd_mode = 0;
 			} else {
+#ifdef SSIDEV_HASH_KMEM_CACHE
+				newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#else
 				newp = kmalloc_nofail(sizeof(*newp));
+#endif
 				newp->sd_data = *dp;
 			}
 			list_add(&newp->sd_list, &ssidev_unique_list);
@@ -274,8 +315,12 @@
 	int j;
 	ssidev_hash_t *newp;
 
-	for (j = 0; j < num; j++) {
+	for (j = 0; j < num; j++, dp++) {
+#ifdef SSIDEV_HASH_KMEM_CACHE
+		newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#else
 		newp = kmalloc_nofail(sizeof(*newp));
+#endif
 		if (dp->sd_devnode != CLUSTERNODE_INVAL) {
 			ssidev_add(newp, dp->sd_devnode, dp->sd_mode,
 				   dp->sd_linuxdev, dp->sd_ssidev);
@@ -289,7 +334,6 @@
 				list_add_tail(&newp->sd_list,
 					      &ssidev_free_list);
 		}
-		dp++;
 	}
 }
 
@@ -372,7 +416,11 @@
 		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) {
@@ -391,7 +439,11 @@
 	ssidev_hash_t *hp;
 
 	(void)to_node;
+#ifdef SSIDEV_HASH_KMEM_CACHE
+	newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL);
+#else
 	newp = kmalloc(sizeof(*newp), GFP_KERNEL);
+#endif
 	if (newp == NULL) {
 		*rerror = -ENOMEM;
 		return 0;
@@ -421,7 +473,11 @@
 	ssidev_hash_t *newp;
 
 	(void)to_node;
+#ifdef SSIDEV_HASH_KMEM_CACHE
+	newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL);
+#else
 	newp = kmalloc(sizeof(*newp), GFP_KERNEL);
+#endif
 	if (newp == NULL) {
 		*rerror = -ENOMEM;
 		return 0;
@@ -490,7 +546,11 @@
 	error = ssidev_new(devnode, mode, linuxdev, &ssidev);
 	if (error >= 0) {
 		if (this_node != ssidev_node && !ssidev_secondary) {
+#ifdef SSIDEV_HASH_KMEM_CACHE
+			hp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#else
 			hp = kmalloc_nofail(sizeof(*hp));
+#endif
 			ssidev_lock();
 			ssidev_add(hp, devnode, mode & S_IFMT,
 				   linuxdev, ssidev);
@@ -620,7 +680,16 @@
 {
 	/* Wait for the SSI device server if we're not it. */
 	ssidev_node = clms_get_key_server_node(ssidev_key_service, 1);
-	wmb();
+	/* wmb(); */
+#ifdef SSIDEV_HASH_KMEM_CACHE
+	ssidev_hash_init();
+#endif
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+	ssidev_poll_node_init();
+#endif
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+	ssidev_poll_cli_init();
+#endif
 	if (ssidev_node == this_node) {
 		ssidev_inited = 1;
 		clms_set_key_service_ready(ssidev_key_service);
@@ -712,6 +781,19 @@
 static inline signed long ssidev_poll_cli_wait(ssidev_poll_cli_t *pcp,
 					       signed long timeout)
 {
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+	LOCK_SPIN_LOCK(&pcp->pc_spinlock);
+	if (!pcp->pc_wakeup) {
+		pcp->pc_proc = current;
+		UNLOCK_SPIN_LOCK(&pcp->pc_spinlock);
+		if (!pcp->pc_wakeup)
+			timeout = schedule_timeout(timeout);
+		LOCK_SPIN_LOCK(&pcp->pc_spinlock);
+		pcp->pc_wakeup = 0;
+		pcp->pc_proc = NULL;
+	}
+	UNLOCK_SPIN_LOCK(&pcp->pc_spinlock);
+#else
 	spin_lock(&ssidev_poll_cli_spinlock);
 	pcp->pc_proc = current;
 	spin_unlock(&ssidev_poll_cli_spinlock);
@@ -721,15 +803,33 @@
 	pcp->pc_proc = NULL;
 	pcp->pc_wakeup = 0;
 	spin_unlock(&ssidev_poll_cli_spinlock);
+#endif /* !RCU_SSIDEV_POLL_CLI_LIST */
 
 	return timeout;
 }
 
 void ssidev_poll_wake_cli(caddr_t cpcp)
 {
-	struct list_head *ltmp;
 	ssidev_poll_cli_t *pcp;
 
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+	rcu_read_lock();
+	list_for_each_entry_rcu(pcp, &ssidev_poll_cli_list, pc_list) {
+		if (pcp == (ssidev_poll_cli_t *)cpcp) {
+			LOCK_SPIN_LOCK(&pcp->pc_spinlock);
+			pcp->pc_wakeup = 1;
+			if (pcp->pc_proc) {
+				wake_up_process(pcp->pc_proc);
+				pcp->pc_proc = NULL; /* avoid race */
+			}
+			UNLOCK_SPIN_LOCK(&pcp->pc_spinlock);
+			break;
+		}
+	}
+	rcu_read_unlock();
+#else
+	struct list_head *ltmp;
+
 	spin_lock(&ssidev_poll_cli_spinlock);
 	list_for_each(ltmp, &ssidev_poll_cli_list) {
 		pcp = list_entry(ltmp, ssidev_poll_cli_t, pc_list);
@@ -741,6 +841,7 @@
 		}
 	}
 	spin_unlock(&ssidev_poll_cli_spinlock);
+#endif /* !RCU_SSIDEV_POLL_CLI_LIST */
 }
 
 static int ssidev_poll_return(ssidev_pollfd_t *sfdp)
@@ -781,11 +882,25 @@
 	return ucount;
 }
 
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+static void ssidev_poll_node_init(void)
+{
+	ssidev_poll_node_cachep = kmem_cache_create("ssidev_poll_node",
+				sizeof(ssidev_poll_node_t), 0,
+				SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+				NULL, NULL);
+}
+#endif
+
 static inline ssidev_poll_node_t *ssidev_poll_node_alloc(void)
 {
 	ssidev_poll_node_t *pnp;
 
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+	pnp = kmem_cache_alloc(ssidev_poll_node_cachep, GFP_KERNEL);
+#else
 	pnp = kmalloc(sizeof(*pnp), GFP_KERNEL);
+#endif
 	if (pnp == NULL)
 		return NULL;
 	pnp->pn_waiting = 0;
@@ -800,25 +915,51 @@
 	if (pnp == NULL)
 		return;
 	ics_chunk_free(&pnp->pn_pollfd);
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+	kmem_cache_free(ssidev_poll_node_cachep, pnp);
+#else
 	kfree(pnp);
+#endif
+}
+
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+static void ssidev_poll_cli_init(void)
+{
+	ssidev_poll_cli_cachep = kmem_cache_create("ssidev_poll_cli",
+				sizeof(ssidev_poll_cli_t), 0,
+				SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+				NULL, NULL);
 }
+#endif
 
 ssidev_poll_cli_t *ssidev_poll_cli_alloc(unsigned int events,
 					 int (*retfunc)(ssidev_pollfd_t *))
 {
 	ssidev_poll_cli_t *pcp;
 
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+	pcp = kmem_cache_alloc(ssidev_poll_cli_cachep, GFP_KERNEL);
+#else
 	pcp = kmalloc(sizeof(*pcp), GFP_KERNEL);
+#endif
 	if (pcp == NULL)
 		return NULL;
 	INIT_LIST_HEAD(&pcp->pc_list);
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+	INIT_RCU_HEAD(&pcp->pc_rcu);
+	INIT_SPIN_LOCK(&pcp->pc_spinlock);
+#endif
 	pcp->pc_proc = NULL;
 	pcp->pc_events = events;
 	pcp->pc_wakeup = 0;
 	pcp->pc_retfunc = retfunc;
 	memset(pcp->pc_node, 0, sizeof(pcp->pc_node));
 	spin_lock(&ssidev_poll_cli_spinlock);
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+	list_add_rcu(&pcp->pc_list, &ssidev_poll_cli_list);
+#else
 	list_add(&pcp->pc_list, &ssidev_poll_cli_list);
+#endif
 	spin_unlock(&ssidev_poll_cli_spinlock);
 
 	return pcp;
@@ -828,11 +969,20 @@
 {
 	ssidev_poll_node_t *pnp;
 	int i;
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+	extern void ssidev_poll_cli_dealloc(struct rcu_head *);
+#endif
 
 	if (pcp == NULL)
 		return;
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+	SSI_ASSERT(pcp->pc_proc == NULL);
+	spin_lock(&ssidev_poll_cli_spinlock);
+	list_del_rcu(&pcp->pc_list);
+#else
 	spin_lock(&ssidev_poll_cli_spinlock);
 	list_del(&pcp->pc_list);
+#endif
 	spin_unlock(&ssidev_poll_cli_spinlock);
 	for (i = 0; i < NSC_MAX_NODE_VALUE; i++) {
 		pnp = pcp->pc_node[i];
@@ -842,7 +992,19 @@
 			ssidev_rpoll_wake_svr(i + 1, pcp);
 		ssidev_poll_node_free(pnp);
 	}
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+	call_rcu(&pcp->pc_rcu, ssidev_poll_cli_dealloc);
+}
+
+void ssidev_poll_cli_dealloc(struct rcu_head *pc_rcu)
+{
+	ssidev_poll_cli_t *pcp = container_of(pc_rcu, ssidev_poll_cli_t, pc_rcu);
+#endif
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+	kmem_cache_free(ssidev_poll_cli_cachep, pcp);
+#else
 	kfree(pcp);
+#endif
 }
 
 int ssidev_pollfd_add(ssidev_poll_cli_t *pcp, struct pollfd *fdp, void *src)
@@ -1567,11 +1729,17 @@
 ics_chan_t ics_ssidev_chan;
 clms_key_svc_t ssidev_key_service;
 extern int ics_ssidev_svc_init(void);
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+extern void ssidev_poll_svr_init(void);
+#endif
 
 static int __init ci_init_ssidev(void)
 {
 	int ret;
 
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+	ssidev_poll_svr_init();
+#endif
 	/* Register SSIDEV ICS channel. */
 	/* XXX: The ICS channel numbers are hard-coded to ensure consistency
 	 * among cluster nodes. This should go away once dynamic channels

Index: ssidev_ics.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/ssidev_ics.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- ssidev_ics.c	23 Oct 2007 04:08:47 -0000	1.11
+++ ssidev_ics.c	3 Feb 2009 06:18:13 -0000	1.12
@@ -52,6 +52,16 @@
 
 static LIST_HEAD(ssidev_poll_svr_list);
 static DEFINE_SPINLOCK(ssidev_poll_svr_spinlock); 
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+static kmem_cache_t *ssidev_poll_svr_cachep;
+#endif
+
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+/*
+ * Bits in ssidev_poll_svr_t.ps_state
+ */
+#define ps_wakeup	0x1	/* wake ps_proc */
+#endif
 
 int ssidev_new(clusternode_t devnode, int mode, dev_t linuxdev,
 	       dev_t *ssidevp)
@@ -552,6 +562,16 @@
 	return error;
 }
 
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+void ssidev_poll_svr_init(void)
+{
+	ssidev_poll_svr_cachep = kmem_cache_create("ssidev_poll_svr",
+				sizeof(ssidev_poll_svr_t), 0,
+				SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+				NULL, NULL);
+}
+#endif
+
 static inline ssidev_poll_svr_t *ssidev_poll_svr_alloc(clusternode_t cnode,
 						       caddr_t cpcp,
 						       u_int events,
@@ -560,22 +580,39 @@
 {
 	ssidev_poll_svr_t *psp;
 
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+	psp = kmem_cache_alloc(ssidev_poll_svr_cachep, GFP_KERNEL);
+#else
 	psp = kmalloc(sizeof(*psp), GFP_KERNEL);
+#endif
 	if (psp == NULL)
 		return NULL;
 	INIT_LIST_HEAD(&psp->ps_list);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	atomic_set(&psp->ps_usecount, 2);
+	INIT_RCU_HEAD(&psp->ps_rcu);
+#else
 	psp->ps_usecount = 2;
+#endif
 	init_MUTEX_LOCKED(&psp->ps_sem);
 	psp->ps_cnode = cnode;
 	psp->ps_cpcp = cpcp;
 	psp->ps_proc = NULL;
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	psp->ps_state = 0;
+#else
 	psp->ps_wakeup = 0;
+#endif
 	psp->ps_events = events;
 	psp->ps_icp = icp;
 	psp->ps_retval = 0;
 	psp->ps_pstate = pstate;
 	spin_lock(&ssidev_poll_svr_spinlock);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	list_add_rcu(&psp->ps_list, &ssidev_poll_svr_list);
+#else
 	list_add(&psp->ps_list, &ssidev_poll_svr_list);
+#endif
 	spin_unlock(&ssidev_poll_svr_spinlock);
 
 	return psp;
@@ -583,22 +620,62 @@
 
 static inline void ssidev_poll_svr_free(ssidev_poll_svr_t *psp)
 {
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	extern void ssidev_poll_svr_dealloc(struct rcu_head *);
+
+	if (psp == NULL)
+		return;
+	if (!atomic_dec_and_lock(&psp->ps_usecount, &ssidev_poll_svr_spinlock))
+		return;
+	list_del_rcu(&psp->ps_list);
+	spin_unlock(&ssidev_poll_svr_spinlock);
+	call_rcu(&psp->ps_rcu, ssidev_poll_svr_dealloc);
+}
+
+void ssidev_poll_svr_dealloc(struct rcu_head *ps_rcu)
+{
+	ssidev_poll_svr_t *psp = container_of(ps_rcu, ssidev_poll_svr_t, ps_rcu);
+
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+	kmem_cache_free(ssidev_poll_svr_cachep, psp);
+#else
+	kfree(psp);
+#endif
+#else
 	if (psp == NULL)
 		return;
 	spin_lock(&ssidev_poll_svr_spinlock);
 	if (--(psp->ps_usecount) == 0) {
 		list_del_init(&psp->ps_list);
 		spin_unlock(&ssidev_poll_svr_spinlock);
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+		kmem_cache_free(ssidev_poll_svr_cachep, psp);
+#else
 		kfree(psp);
+#endif
 	} else
 		spin_unlock(&ssidev_poll_svr_spinlock);
+#endif /* !RCU_SSIDEV_POLL_SVR_LIST */
 }
 
 static inline void ssidev_poll_wake_svr(clusternode_t cnode, caddr_t cpcp)
 {
-	struct list_head *ltmp;
 	ssidev_poll_svr_t *psp;
 
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	rcu_read_lock();
+	list_for_each_entry_rcu(psp, &ssidev_poll_svr_list, ps_list) {
+		if (psp->ps_cnode == cnode && psp->ps_cpcp == cpcp) {
+			if (!test_and_set_bit(ps_wakeup, &psp->ps_state) &&
+			    psp->ps_proc != NULL)
+				wake_up_process(psp->ps_proc);
+			break;
+		}
+	}
+	rcu_read_unlock();
+#else
+	struct list_head *ltmp;
+
 	spin_lock(&ssidev_poll_svr_spinlock);
 	list_for_each(ltmp, &ssidev_poll_svr_list) {
 		psp = list_entry(ltmp, ssidev_poll_svr_t, ps_list);
@@ -611,6 +688,7 @@
 		}
 	}
 	spin_unlock(&ssidev_poll_svr_spinlock);
+#endif /* !RCU_SSIDEV_POLL_SVR_LIST */
 }
 
 void ssidev_poll_svr_nodedown(clusternode_t node)
@@ -618,6 +696,17 @@
 	struct list_head *ltmp, *lnext;
 	ssidev_poll_svr_t *psp;
 
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	rcu_read_lock();
+	list_for_each_safe_rcu(ltmp, lnext, &ssidev_poll_svr_list) {
+		psp = list_entry(ltmp, ssidev_poll_svr_t, ps_list);
+		if (psp->ps_cnode == node &&
+		    !test_and_set_bit(ps_wakeup, &psp->ps_state) &&
+		    psp->ps_proc != NULL)
+			wake_up_process(psp->ps_proc);
+	}
+	rcu_read_unlock();
+#else
 	spin_lock(&ssidev_poll_svr_spinlock);
 	lnext = ssidev_poll_svr_list.next;
 	while (lnext != &ssidev_poll_svr_list) {
@@ -632,6 +721,7 @@
 		}
 	}
 	spin_unlock(&ssidev_poll_svr_spinlock);
+#endif /* !RCU_SSIDEV_POLL_SVR_LIST */
 }
 
 static void ssidev_rpoll_svr(void *arg)
@@ -653,23 +743,40 @@
 	if (tmpret < 0)
 		psp->ps_retval = tmpret;
 	set_current_state(TASK_INTERRUPTIBLE);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	/* serialized by ps_wakeup bit */
+	psp->ps_proc = current;
+#else
 	spin_lock(&ssidev_poll_svr_spinlock);
 	psp->ps_proc = current;
 	spin_unlock(&ssidev_poll_svr_spinlock);
+#endif
 	ssi_procstate_set(psp->ps_pstate);
 	tmpret = ssidev_do_poll_node(icp, psp->ps_events, wait);
 	ssi_procstate_set(&save_pstate);
 	if (tmpret != 0)
 		psp->ps_retval = tmpret;
 	up(&psp->ps_sem);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	if (!psp->ps_retval && !test_bit(ps_wakeup, &psp->ps_state))
+#else
 	if (!psp->ps_retval && !psp->ps_wakeup)
+#endif
 		schedule();
 	set_current_state(TASK_RUNNING);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	psp->ps_proc = NULL;
+#else
 	spin_lock(&ssidev_poll_svr_spinlock);
 	psp->ps_proc = NULL;
 	spin_unlock(&ssidev_poll_svr_spinlock);
+#endif
 	poll_freewait(&table);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+	if (!psp->ps_retval && !test_bit(ps_wakeup, &psp->ps_state))
+#else
 	if (!psp->ps_retval && !psp->ps_wakeup)
+#endif
 		ssidev_rpoll_wake_cli(psp);
 	ssidev_poll_svr_free(psp);
 
@@ -714,7 +821,11 @@
 	}
 	*retval = spawn_daemon_proc("ssi rpoll svr", ssidev_rpoll_svr, psp);
 	if (*retval < 0) {
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+		atomic_set(&psp->ps_usecount, 1);
+#else
 		psp->ps_usecount = 1;
+#endif
 		ssidev_poll_svr_free(psp);
 
 		return 0;


------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-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.