[SSI] openssi/kernel/cluster/ssi/vproc as_xscribe.c, 1.15, 1.16 dvp_async.c, 1.10, 1.11 dvp_move.c, 1.12, 1.13 dvp_pvpops.c, 1.37, 1.38 dvp_pvpsops.c, 1.15, 1.16 dvp_vpops.c, 1.37, 1.38 nd_carelist.c, 1.6, 1.7 nd_object.c, 1.5, 1.6 nd_origin.c, 1.8, 1.9 nd_subr.c, 1.5, 1.6 nsc_initproc.c, 1.20, 1.21 pproc_subr.c, 1.10, 1.11 reopen.c, 1.28, 1.29 rproc_cli_pproc.c, 1.20, 1.21 rproc_cli_vproc.c, 1.9, 1.10 rproc_svr_pproc.c, 1.22, 1.23 rproc_svr_vproc.c, 1.13, 1.14 rvp_pvpops_server.c, 1.13, 1.14 vp_debug.c, 1.13, 1.14 vp_init.c, 1.6, 1.7 vp_subr.c, 1.14, 1.15

Roger Tsang <[email protected]>
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv8553/cluster/ssi/vproc

Modified Files:
      Tag: OPENSSI-FC
	as_xscribe.c dvp_async.c dvp_move.c dvp_pvpops.c dvp_pvpsops.c 
	dvp_vpops.c nd_carelist.c nd_object.c nd_origin.c nd_subr.c 
	nsc_initproc.c pproc_subr.c reopen.c rproc_cli_pproc.c 
	rproc_cli_vproc.c rproc_svr_pproc.c rproc_svr_vproc.c 
	rvp_pvpops_server.c vp_debug.c vp_init.c vp_subr.c 
Log Message:
Bug fixes and enhancements. (see ChangeLog)


Index: pproc_subr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/pproc_subr.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- pproc_subr.c	10 Oct 2008 08:10:32 -0000	1.10
+++ pproc_subr.c	3 Feb 2009 06:18:13 -0000	1.11
@@ -113,11 +113,10 @@
 	read_lock(&tasklist_lock);
 	if (p->signal) {
 #ifdef PPROC_SETCTTY_SIGLOCK
-		unsigned long flags;
-
 		SSI_ASSERT((flag & (VCTTY_SETCTTY|VCTTY_CLEARCTTY)) !=
 					(VCTTY_SETCTTY|VCTTY_CLEARCTTY));
-		spin_lock_irqsave(&p->sighand->siglock, flags);
+		/* SSI: Caller should have FLAG LOCK */
+		/* SSI_XXX: do the assert */
 #else
 		/* SSI_XXX: task_lock() doesn't protect ->signal */
 		task_lock(p);
@@ -137,9 +136,7 @@
 				p->signal->tty_old_pgrp = 0;
 			}
 		}
-#ifdef PPROC_SETCTTY_SIGLOCK
-		spin_unlock_irqrestore(&p->sighand->siglock, flags);
-#else
+#ifndef PPROC_SETCTTY_SIGLOCK
 		task_unlock(p);
 #endif
 	}
@@ -162,7 +159,7 @@
 	read_lock(&tasklist_lock);
 	if (p->signal) {
 #ifdef PPROC_SETCTTY_SIGLOCK
-		spin_lock_irq(&p->sighand->siglock);
+		/* SSI: Caller should have FLAG LOCK */
 #else
 		task_lock(p);
 #endif
@@ -170,9 +167,7 @@
 			*cttydev = p->signal->cttydev;
 		if (cttynode)
 			*cttynode = p->signal->cttynode;
-#ifdef PPROC_SETCTTY_SIGLOCK
-		spin_unlock_irq(&p->sighand->siglock);
-#else
+#ifndef PPROC_SETCTTY_SIGLOCK
 		task_unlock(p);
 #endif
 	}
@@ -198,8 +193,15 @@
 	pinfo->pi_pid = p->pid;
 	pinfo->pi_uid = p->uid;
 	pinfo->pi_sid = p->signal->session;
+#ifdef VPROC_NOTIFY_PARENT_CLDSTOP__SA_HANDLER_SIGINFO
+	/* do_notify_parent_cldstop behavior */
+	/* FIXME: find out whether or not this is supposed to be c*time. */
+	pinfo->pi_utime = cputime_to_jiffies(p->utime);
+	pinfo->pi_stime = cputime_to_jiffies(p->stime);
+#else
 	pinfo->pi_utime = p->utime;
 	pinfo->pi_stime = p->stime;
+#endif
 
 	status = p->exit_code & 0x7f;
 	if (p->exit_code & 0x80)

Index: vp_subr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/vp_subr.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- vp_subr.c	10 Oct 2008 08:10:32 -0000	1.14
+++ vp_subr.c	3 Feb 2009 06:18:13 -0000	1.15
@@ -28,8 +28,6 @@
 #include <linux/errno.h>
 #include <linux/dpvproc.h>
 
-static struct vproc *vproc_new(void);		/* Forward reference */
-
 struct vproc *
 #ifndef VPROC_RCU_LIST
 vprocptr(
@@ -74,7 +72,7 @@
 #endif
 		UNLOCK_SHR_RW_LOCK(&vproc_list_lock);
 	}
-#else
+#else /* VPROC_RCU_LIST */
 #ifdef VPROC_RELEASE__REFCNT_RACE_FIX
 	/* [ ssic-linux-Bugs-1842982 ] vproc dealloc'ed */
 	if (found && hold != -1 && !VPROC_HOLD_AND_CHECK(v, "vprocptr"))
@@ -105,6 +103,52 @@
 #endif /* !VPROC_HASH_LIST */
 }
 
+#ifdef VPROC_KMEM_CACHE
+static kmem_cache_t *vproc_cachep;
+
+void
+vproc_cache_init(void)
+{
+	size_t size = sizeof(struct vproc) + sizeof(struct pvproc);
+
+	vproc_cachep = kmem_cache_create("vproc_cache",
+				size, 0,
+				SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+				NULL, NULL);
+}
+#endif /* VPROC_KMEM_CACHE */
+
+/*
+ * Allocate a new vproc and pvproc.
+ * New vproc and pvproc are zero'd and then
+ * vproc reference count lock is init'd.
+ */
+static inline struct vproc *
+vproc_new(void)
+{
+	register struct vproc *v;
+
+	/*
+	 * We allocate the vproc and pvproc in a single continguous chunk
+	 * of memory.
+	 */
+#ifdef VPROC_KMEM_CACHE
+	v = kmem_cache_alloc(vproc_cachep, GFP_KERNEL|__GFP_NOFAIL);
+	memset(v, 0, kmem_cache_size(vproc_cachep));
+#else
+	v = kzmalloc_nofail(size);
+#endif
+	v->vp_data = ((char *)v) + sizeof(struct vproc);
+#if !defined(ATOMIC_VPROC_REFCNT) || defined(VPROC_RCU_LIST)
+	VPROC_REFCNT_LOCK_INIT(v);
+#endif
+
+#ifdef VPROC_DEBUG
+	nvproc++;
+#endif
+
+	return(v);
+}
 
 struct vproc *
 vproc_alloc(void)
@@ -136,17 +180,20 @@
 #ifndef VPROC_RCU_LIST
 vproc_dealloc(
 	struct vproc	*vp)
+{
 #else
 vproc_dealloc(
-	struct rcu_head *rhead)
-#endif
+	struct rcu_head *vp_rcu)
 {
-#ifdef VPROC_RCU_LIST
-	struct vproc *vp = container_of(rhead, struct vproc, vp_rcu);
+	struct vproc *vp = container_of(vp_rcu, struct vproc, vp_rcu);
 #endif
 	vp->vp_magic = 0;
 	dpvproc_struct_deinit(vp);
+#ifdef VPROC_KMEM_CACHE
+	kmem_cache_free(vproc_cachep, vp);
+#else
 	kfree(vp);
+#endif
 #ifdef VPROC_DEBUG
 	nvproc--;
 #endif
@@ -173,7 +220,9 @@
 #else
 	extern void vproc_dealloc(struct vproc	*);
 #endif
+#ifndef VPROC_LIST_SPINLOCK
 	int giveback = 0;	/* dealloc vproc */
+#endif
 #ifndef VPROC_HASH_LIST
 	int locked = 0;		/* tncvpd_scan() has lock ? */
 #endif
@@ -202,6 +251,8 @@
 #else
 	BUG_ON(READ_ATOMIC_INT(&v->vp_ref_cnt) < 1);
 
+	if (atomic_read(&v->vp_ref_cnt) == 1)
+		might_sleep();
 #ifdef VPROC_LIST_SPINLOCK
 	if (!atomic_dec_and_lock(&v->vp_ref_cnt, &(&vproc_list_lock)->sp_lock))
 #else
@@ -242,6 +293,15 @@
 
 #ifdef ATOMIC_VPROC_REFCNT
 #ifdef VPROC_LIST_SPINLOCK
+#ifdef VPROC_RCU_LIST
+	VPROC_REFCNT_LOCK(v);
+	if (READ_ATOMIC_INT(&v->vp_ref_cnt)) {
+		VPROC_REFCNT_UNLOCK(v);
+		goto out_unlock;
+	}
+	v->vp_magic = 0;
+	VPROC_REFCNT_UNLOCK(v);
+#endif
 	BUG_ON(READ_ATOMIC_INT(&v->vp_ref_cnt));
 #else
 	/*
@@ -250,7 +310,7 @@
 	if (READ_ATOMIC_INT(&v->vp_ref_cnt) > 0)
 		goto out_unlock;
 #endif
-#else
+#else /* !ATOMIC_VPROC_REFCNT */
 	/*
 	 * Reference count got bumped; just
 	 * do our decrement and return.
@@ -283,12 +343,11 @@
 	else
 		vproc_hash[VPROCPIDHASH(v->vp_pid)] = v->vp_hashfwd;
 #endif
-	v->vp_magic = 0;
+#ifndef VPROC_LIST_SPINLOCK
 	giveback = 1;
+#endif
 
-#ifndef VPROC_LIST_SPINLOCK
 out_unlock:
-#endif
 #ifndef VPROC_HASH_LIST
 	if (locked)
 		VPROC_LIST_UNLOCK();
@@ -296,21 +355,25 @@
 #ifndef VPROC_RCU_LIST
 	UNLOCK_EXCL_RW_LOCK(&vproc_list_lock);
 #else
+#ifdef VPROC_LIST_SPINLOCK
+	spin_unlock(&(&vproc_list_lock)->sp_lock);
+#else
 	VPROC_LIST_UNLOCK();
 #endif
+#endif
 #endif /* !VPROC_HASH_LIST */
 
 	/*
 	 * Give back vproc storage
 	 */
+#ifndef VPROC_LIST_SPINLOCK
 	if (giveback) {
+#endif
 #ifdef VPROC_HOLD_ZERO_GET_TASK
-		task_t *tsk = PVP(v)->pvp_pproc;
-
-		if (tsk) {
+		if (PVP(v)->pvp_pproc) {
 			WARN_ON(PV_IS_ALIVE(PVP(v)));
+			put_task_struct(PVP(v)->pvp_pproc);
 			PVP(v)->pvp_pproc = NULL;
-			put_task_struct(tsk);
 		}
 #endif
 #ifdef VPROC_RCU_LIST
@@ -318,7 +381,9 @@
 #else
 		vproc_dealloc(v);
 #endif
+#ifndef VPROC_LIST_SPINLOCK
 	}
+#endif
 
 	return(ESUCCESS);
 }
@@ -326,37 +391,25 @@
 int
 vproc_hold(
 	struct vproc *v,
-	int recheck)
+	int check)
 {
 #ifdef VPROC_RELEASE__REFCNT_RACE_FIX
 #ifdef VPROC_RCU_LIST
-	if (recheck) {
-#ifndef VPROC_LIST_SPINLOCK
-		SSI_ASSERT_UNLOCKED_LOCK(&vproc_list_lock);
-#endif
-		VPROC_LIST_LOCK();
+	if (check) {
+		VPROC_REFCNT_LOCK(v);
 		if (!VPROCPTR_VALID(v)) {
 			/* Lost the race */
-			VPROC_LIST_UNLOCK();
+			VPROC_REFCNT_UNLOCK(v);
 			return -ESRCH;
 		}
-	} else
-		BUG_ON(!VPROCPTR_VALID(v));
+		INCR_ATOMIC_INT(&v->vp_ref_cnt);
+		VPROC_REFCNT_UNLOCK(v);
+		return (ESUCCESS);
+	}
 #else
 #error not yet implemented
 #endif
-#ifndef ATOMIC_VPROC_REFCNT
-	VPROC_REFCNT_LOCK(v);
-	v->vp_ref_cnt++;
-	VPROC_REFCNT_UNLOCK(v);
-#else
-	INCR_ATOMIC_INT(&v->vp_ref_cnt);
-#endif
-#ifdef VPROC_RCU_LIST
-	if (recheck)
-		VPROC_LIST_UNLOCK();
-#endif
-#else /* !VPROC_RELEASE__REFCNT_RACE_FIX */
+#endif /* VPROC_RELEASE__REFCNT_RACE_FIX */
 	BUG_ON(!VPROCPTR_VALID(v));
 #ifndef ATOMIC_VPROC_REFCNT
 	VPROC_REFCNT_LOCK(v);
@@ -365,43 +418,12 @@
 #else
 	INCR_ATOMIC_INT(&v->vp_ref_cnt);
 #endif
-#endif /* !VPROC_RELEASE__REFCNT_RACE_FIX */
 #ifdef NSCVPD_DEBUG
 	PVP(v)->pvp_lasthold = TICKS();
 #endif
 	return(ESUCCESS);
 }
 
-
-/*
- * Allocate a new vproc and pvproc.
- * New vproc and pvproc are zero'd and then
- * vproc reference count lock is init'd.
- */
-static struct vproc *
-vproc_new(void)
-{
-	register struct vproc *v;
-	int size;
-
-	/*
-	 * We allocate the vproc and pvproc in a single continguous chunk
-	 * of memory.
-	 */
-	size = sizeof(struct vproc) + sizeof(struct pvproc);
-	v = kzmalloc_nofail(size);
-	v->vp_data = ((char *)v) + sizeof(struct vproc);
-#ifndef VPROC_RCU_LIST
-	VPROC_REFCNT_LOCK_INIT(v);
-#endif
-
-#ifdef VPROC_DEBUG
-	nvproc++;
-#endif
-
-	return(v);
-}
-
 pid_t ssi_get_ppid(pid_t pid)
 {
 	struct vproc *vp = LOCATE_VPROC_PID(pid, "tmp get_ssi_pid");

Index: rproc_cli_pproc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/rproc_cli_pproc.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- rproc_cli_pproc.c	20 Apr 2008 05:49:23 -0000	1.20
+++ rproc_cli_pproc.c	3 Feb 2009 06:18:13 -0000	1.21
@@ -963,7 +963,7 @@
 	/*
 	 * If the process is a system process it cannot go remote.
 	 */
-	if ((PVP(t->p_vproc)->pvp_flag) & PV_SYS) {
+	if (IS_SYSPROC(PVP(t->p_vproc))) {
 		error = -EBUSY;
 		printk(KERN_DEBUG "Cannot move process %d - "
 		       "%s is a system process\n",

Index: nd_origin.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/nd_origin.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- nd_origin.c	10 Oct 2008 08:10:32 -0000	1.8
+++ nd_origin.c	3 Feb 2009 06:18:13 -0000	1.9
@@ -31,8 +31,14 @@
 #include <linux/nd.h>
 
 
+#ifdef RCU_VPROC_ORIGIN_LIST
+spinlock_t vproc_origin_list_lock;
+#else
 RW_LOCK_T vproc_origin_list_lock;
+#endif
+#ifdef SSI_NOTUSED
 SPIN_LOCK_T vproc_origin_list_add_lock;
+#endif
 RW_LOCK_T vproc_origin_deactivate_lock;
 
 #ifdef VOD_HLIST
@@ -55,8 +61,14 @@
  */
 void vproc_origin_list_init(void)
 {
+#ifdef RCU_VPROC_ORIGIN_LIST
+	spin_lock_init(&vproc_origin_list_lock);
+#else
 	INIT_RW_LOCK(&vproc_origin_list_lock);
+#endif
+#ifdef SSI_NOTUSED
 	INIT_SPIN_LOCK(&vproc_origin_list_add_lock);
+#endif
 	INIT_RW_LOCK(&vproc_origin_deactivate_lock);
 	INIT_CONDITION(&vproc_origin_create_cond);
 	INIT_COND_LOCK(&vproc_origin_create_mutex);
@@ -116,11 +128,22 @@
 			error = 0;
 		}
 
+#ifdef ND_ORIGIN_DEADLOCK_FIX
+		UNLOCK_SHR_RW_LOCK(&vodp->vod_rwlock);
+#else
 		UNLOCK_EXCL_RW_LOCK(&vodp->vod_rwlock);
+#endif
 		goto out;
 	}
 
-	vodp = kzmalloc_nofail(sizeof(vproc_origin_data_t));
+	vodp = kzmalloc_nofail(sizeof(*vodp));
+#ifdef VOD_HLIST
+	INIT_HLIST_NODE(&vodp->vod_list);
+#ifdef RCU_VPROC_ORIGIN_LIST
+	INIT_RCU_HEAD(&vodp->vod_rcu);
+	/* atomic_set(&vodp->vod_refcnt, 0); */
+#endif
+#endif
 	INIT_RW_LOCK(&vodp->vod_rwlock);
 
 	vodp->vod_node = node;
@@ -156,10 +179,13 @@
 	INIT_COND_LOCK(&vodp->vod_response_mutex);
 
 	LOCK_SHR_RW_LOCK(&vproc_origin_deactivate_lock);
+#ifdef RCU_VPROC_ORIGIN_LIST
+	spin_lock(&vproc_origin_list_lock);
+#else
 	LOCK_EXCL_RW_LOCK(&vproc_origin_list_lock);
+#endif
 
 #ifdef VOD_HLIST
-	INIT_HLIST_NODE(&vodp->vod_list);
 	hlist_add_head(&vodp->vod_list, &vproc_origin_list);
 #else
 	vodp->vod_next = vproc_origin_list;
@@ -172,7 +198,11 @@
 #endif
 
 	LOCK_COND_LOCK(&vproc_origin_create_mutex);
+#ifdef RCU_VPROC_ORIGIN_LIST
+	spin_unlock(&vproc_origin_list_lock);
+#else
 	UNLOCK_EXCL_RW_LOCK(&vproc_origin_list_lock);
+#endif
 	UNLOCK_SHR_RW_LOCK(&vproc_origin_deactivate_lock);
 	/*
 	 * Wake up any threads waiting in vproc_origin_inform_surrogate().
@@ -193,40 +223,68 @@
 vproc_origin_deactivate(
 	clusternode_t	node)
 {
-#ifndef VOD_HLIST
 	vproc_origin_data_t *vodp;
-	int i;
-#else
-	vproc_origin_data_t *vodp = NULL;
+#ifdef VOD_HLIST
 	struct hlist_node *pos;
-	int i, found = 0;
+#endif
+#ifdef RCU_VPROC_ORIGIN_LIST
+	extern void vproc_origin_dealloc(struct rcu_head *);
+#else
+	int i;
 #endif
 
+#ifdef ND_ORIGIN_DEADLOCK_FIX
+	LOCK_SHR_RW_LOCK(&vproc_origin_deactivate_lock);
+#else
 	LOCK_EXCL_RW_LOCK(&vproc_origin_deactivate_lock);
+#endif
+#ifndef RCU_VPROC_ORIGIN_LIST
 	LOCK_EXCL_RW_LOCK(&vproc_origin_list_lock);
-
+#endif
 #ifdef VOD_HLIST
+#ifdef RCU_VPROC_ORIGIN_LIST
+	rcu_read_lock();
+#endif
 	VOD_FOR_EACH(vodp, pos) {
 #else
 	for (vodp = vproc_origin_list; vodp; vodp = vodp->vod_next) {
-#endif
+#endif /* !VOD_HLIST */
 		if (vodp->vod_node == node) {
-#ifdef VOD_HLIST
-			found = 1;
-#endif
+#ifdef RCU_VPROC_ORIGIN_LIST
+			LOCK_SPIN_LOCK(&vodp->vod_mutex);
+			if (vodp->vod_flags & VOD_REMOVED) {
+				UNLOCK_SPIN_LOCK(&vodp->vod_mutex);
+				break;
+			}
+			vodp->vod_flags |= VOD_REMOVED;
+			UNLOCK_SPIN_LOCK(&vodp->vod_mutex);
+			rcu_read_unlock();
+			goto found;
+		}
+	}
+	rcu_read_unlock();
+#else
 			break;
 		}
 	}
 
-#ifdef VOD_HLIST
-	if (!found) { 
-#else
 	if (vodp == NULL) {
-#endif
 		UNLOCK_EXCL_RW_LOCK(&vproc_origin_list_lock);
+#endif
+#ifdef ND_ORIGIN_DEADLOCK_FIX
+		UNLOCK_SHR_RW_LOCK(&vproc_origin_deactivate_lock);
+#else
 		UNLOCK_EXCL_RW_LOCK(&vproc_origin_deactivate_lock);
+#endif
 		return;
+#ifndef RCU_VPROC_ORIGIN_LIST
 	}
+#else
+found:
+	/* Wait for lookups that won the race to obtain shared vod_rwlock */
+	while (atomic_read(&vodp->vod_refcnt))
+		idelay(HZ/10);
+#endif
 
 	LOCK_EXCL_RW_LOCK(&vodp->vod_rwlock);
 
@@ -235,7 +293,13 @@
 	 * linked list of (surrogate) origin nodes.
 	 */
 #ifdef VOD_HLIST
+#ifdef RCU_VPROC_ORIGIN_LIST
+	spin_lock(&vproc_origin_list_lock);
+	hlist_del_rcu(&vodp->vod_list);
+	spin_unlock(&vproc_origin_list_lock);
+#else
 	hlist_del_init(&vodp->vod_list);
+#endif /* !RCU_VPROC_ORIGIN_LIST */
 #else
 	if (vodp->vod_prev)
 		vodp->vod_prev->vod_next = vodp->vod_next;
@@ -248,7 +312,9 @@
 
 	UNLOCK_EXCL_RW_LOCK(&vodp->vod_rwlock);
 
+#ifndef RCU_VPROC_ORIGIN_LIST
 	UNLOCK_EXCL_RW_LOCK(&vproc_origin_list_lock);
+#endif
 
 	/*
 	 * Disable origin vproc holds and flags for processes that
@@ -259,9 +325,26 @@
 	 *	 which holds the VPROC_LIST_LOCK() before indirectly
 	 *	 calling vproc_origin_find().
 	 */
+#ifdef ND_ORIGIN_DEADLOCK_FIX
+	/* RT - No point holding deactivate lock beyond this point. */
+	UNLOCK_SHR_RW_LOCK(&vproc_origin_deactivate_lock);
+#endif
 	vproc_release_origin_vprocs(node);
 
+#ifndef ND_ORIGIN_DEADLOCK_FIX
 	UNLOCK_EXCL_RW_LOCK(&vproc_origin_deactivate_lock);
+#endif
+
+#ifdef RCU_VPROC_ORIGIN_LIST
+	call_rcu(&vodp->vod_rcu, vproc_origin_dealloc);
+}
+
+void
+vproc_origin_dealloc(struct rcu_head *vod_rcu)
+{
+	vproc_origin_data_t *vodp = container_of(vod_rcu, vproc_origin_data_t, vod_rcu);
+	int i;
+#endif
 
 	for (i=0; i < VPROC_CAREHASHSZ; i++)
 		vproc_carehead_list_release(vodp->vod_carehash[i]);
@@ -286,37 +369,56 @@
 vproc_origin_find_nolock(
 	clusternode_t	node)
 {
+	vproc_origin_data_t *vodp;
 #ifdef VOD_HLIST
-	vproc_origin_data_t *vodp = NULL;
 	struct hlist_node *pos;
-	int found = 0;
 
+#ifdef RCU_VPROC_ORIGIN_LIST
+	rcu_read_lock();
+#endif
 	VOD_FOR_EACH(vodp, pos) {
 #else
-	vproc_origin_data_t *vodp;
-
 	for (vodp = vproc_origin_list; vodp; vodp = vodp->vod_next) {
 #endif
 		if (vodp->vod_node == node) {
+#ifdef RCU_VPROC_ORIGIN_LIST
+			LOCK_SPIN_LOCK(&vodp->vod_mutex);
+			if (vodp->vod_flags & VOD_REMOVED) {
+				UNLOCK_SPIN_LOCK(&vodp->vod_mutex);
+				break;
+			}
+			atomic_inc(&vodp->vod_refcnt);
+			UNLOCK_SPIN_LOCK(&vodp->vod_mutex);
+			goto found;
+#else
 			LOCK_SHR_RW_LOCK(&vodp->vod_rwlock);
-#ifdef VOD_HLIST
-			found = 1;
+			return vodp;
 #endif
-			break;
 		}
 	}
-#ifdef VOD_HLIST
-	if (!found)
-		return NULL;	
-#endif
+#ifdef RCU_VPROC_ORIGIN_LIST
+	vodp = NULL;
+found:
+	rcu_read_unlock();
+
+	if (vodp) {
+		LOCK_SHR_RW_LOCK(&vodp->vod_rwlock);
+		atomic_dec(&vodp->vod_refcnt);
+	}
 
 	return vodp;
+#else
+	return NULL;
+#endif
 }
 
 vproc_origin_data_t *
 vproc_origin_find(
 	clusternode_t	node)
 {
+#ifdef RCU_VPROC_ORIGIN_LIST
+	return vproc_origin_find_nolock(node);
+#else
 	vproc_origin_data_t *vodp;
 
 	LOCK_SHR_RW_LOCK(&vproc_origin_list_lock);
@@ -324,6 +426,7 @@
 	UNLOCK_SHR_RW_LOCK(&vproc_origin_list_lock);
 
 	return vodp;
+#endif
 }
 
 void
@@ -506,6 +609,7 @@
 	else
 		vproc_carehead_list_release(vodp->vod_rmvcare_queue);
 
+	rmb();
 	vodp->vod_addcare_queue = NULL;
 	vodp->vod_rmvcare_queue = NULL;
 
@@ -769,10 +873,18 @@
 	 * and SIGNALs us.
 	 */
 	while (vodp == NULL) {
+#ifdef RCU_VPROC_ORIGIN_LIST
+		spin_lock(&vproc_origin_list_lock);
+#else
 		LOCK_SHR_RW_LOCK(&vproc_origin_list_lock);
+#endif
 		vodp = vproc_origin_find_nolock(trans_node);
 		LOCK_COND_LOCK(&vproc_origin_create_mutex);
+#ifdef RCU_VPROC_ORIGIN_LIST
+		spin_unlock(&vproc_origin_list_lock);
+#else
 		UNLOCK_SHR_RW_LOCK(&vproc_origin_list_lock);
+#endif
 		if (vodp == NULL) {
 			WAIT_CONDITION(&vproc_origin_create_cond,
 				       &vproc_origin_create_mutex);
@@ -1050,7 +1162,24 @@
 	 * origin node's vod_rwlock because we hold the deactivate
 	 * lock throughout.
 	 */
+#ifndef ND_ORIGIN_DEADLOCK_FIX
 	LOCK_SHR_RW_LOCK(&vproc_origin_deactivate_lock);
+#else
+	LOCK_EXCL_RW_LOCK(&vproc_origin_deactivate_lock);
+	/* Not necessary to hold vproc origin list lock as we hold
+	 * the deactivate lock exclusively.
+	 */
+	/* Lock ordering:
+	 * down_read origin list        (vproc_origin_cleanup)
+	 *                              (vproc_origin_fgpgrp_cleanup)
+	 *                              (pvpop_getctty)
+	 *                              (rpvpop_start_op)
+	 *                              (pvpopsop_get_execnode)
+	 *                              (vproc_lock_origin_node)
+	 * down_read origin list        (vproc_origin_find)
+	 */
+	/* LOCK_SHR_RW_LOCK(&vproc_origin_list_lock); */
+#endif
 
 	/*
 	 * Resolve any (surrogate) origin node setups pending on a
@@ -1065,11 +1194,6 @@
 	 * node.
 	 */
 #ifdef VOD_HLIST
-	/* Not necessary to hold vproc origin list lock as we hold
-	 * the deactivate lock throughout.
-	 */
-	/* LOCK_SHR_RW_LOCK(&vproc_origin_list_lock); */
-
 	VOD_FOR_EACH(vodp, pos) {
 #else
 	for (vodp = vproc_origin_list; vodp; vodp = vodp->vod_next) {
@@ -1111,10 +1235,12 @@
 		vproc_origin_fgpgrp_cleanup(vodp, down_node);
 	}
 
-#ifdef VOD_HLIST
+#ifdef ND_ORIGIN_DEADLOCK_FIX
 	/* UNLOCK_SHR_RW_LOCK(&vproc_origin_list_lock); */
-#endif
+	UNLOCK_EXCL_RW_LOCK(&vproc_origin_deactivate_lock);
+#else
 	UNLOCK_SHR_RW_LOCK(&vproc_origin_deactivate_lock);
+#endif
 }
 
 #if defined(DEBUG) || defined(DEBUG_TOOLS)
@@ -1156,42 +1282,15 @@
 	clusternode_t	node,
 	int		flags)
 {
-#ifdef VOD_HLIST
-	vproc_origin_data_t *vodp = NULL;
-#else
 	vproc_origin_data_t *vodp;
-#endif
 	vproc_carehead_t *vchp;
 	vproc_caredata_t *vcdp;
 	int i;
 
 	extern void print_vproc_caredata(vproc_caredata_t *);
 
-#ifdef VOD_HLIST
-	struct hlist_node *pos;
-	int found = 0;
-
-	LOCK_SHR_RW_LOCK(&vproc_origin_list_lock);
-
-	VOD_FOR_EACH(vodp, pos) {
-#else
-	for (vodp = vproc_origin_list; vodp; vodp = vodp->vod_next) {
-#endif
-		if (vodp->vod_node == node) {
-#ifdef VOD_HLIST
-			found = 1;
-#endif
-			break;
-		}
-	}
-
-#ifdef VOD_HLIST
-	UNLOCK_SHR_RW_LOCK(&vproc_origin_list_lock);
-
-	if (!found) {
-#else
+	vodp = vproc_origin_find(node);
 	if (vodp == NULL) {
-#endif
 		printk(KERN_DEBUG "Origin node %d isn't surrogate'd on"
 			     " this node.\n", (int) node);
 		return;

Index: dvp_move.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/dvp_move.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- dvp_move.c	10 Oct 2008 08:10:32 -0000	1.12
+++ dvp_move.c	3 Feb 2009 06:18:13 -0000	1.13
@@ -287,19 +287,13 @@
 static struct move_header *
 __find_move_header(int id, int type)
 {
-	struct move_header *found = NULL;
 	struct move_header *h;
-	struct list_head *curr;
 
-	list_for_each(curr, &movement_list) {
-		h = list_entry(curr, struct move_header, mh_list);
-		if (h->mh_id == id && (h->mh_type & type)) {
-			found = get_move_header(h);
-			break;
-		}
+	list_for_each_entry(h, &movement_list, mh_list) {
+		if (h->mh_id == id && (h->mh_type & type))
+			return get_move_header(h);
 	}
-
-	return found;
+	return NULL;
 }
 
 struct move_header *
@@ -317,19 +311,13 @@
 static struct move_data *
 __find_move_data(struct move_header *h, int pid)
 {
-	struct move_data *found = NULL;
 	struct move_data *d;
-	struct list_head *curr;
 
-	list_for_each(curr, &h->mh_datalist) {
-		d = list_entry(curr, struct move_data, m_list);
-		if (d->m_pid == pid) {
-			found = get_move_data(d);
-			break;
-		}
+	list_for_each_entry(d, &h->mh_datalist, m_list) {
+		if (d->m_pid == pid)
+			return get_move_data(d);
 	}
-
-	return found;
+	return NULL;
 }
 
 static struct move_data *
@@ -396,11 +384,9 @@
 __set_state_datalist(struct move_header *h, enum move_state state)
 {
 	struct move_data *d;
-	struct list_head *curr;
 
 	h->mh_state = state;
-	list_for_each(curr, &h->mh_datalist) {
-		d = list_entry(curr, struct move_data, m_list);
+	list_for_each_entry(d, &h->mh_datalist, m_list) {
 		d->m_state = state;
 	}
 }
@@ -579,7 +565,12 @@
 
 	/* Wait for daemon to tell us to start the migrate */
 	state = move_data_wait_for_state_change(d, PM_QUIESCED);
+#ifdef VPROC_MIGRATE_THREAD_GROUP_FIX
+	if (state == PM_CONTINUE /* SSI_XXX: unseen */ ||
+	    check_move_data_state(d, state, PM_MIGRATE_OUT_START)) {
+#else
 	if (check_move_data_state(d, state, PM_MIGRATE_OUT_START)) {
+#endif
 		if (select_node)
 			cleanup_load(node);
 		error = -EINVAL;
@@ -658,6 +649,29 @@
 	return d;
 }
 
+static inline int
+__proc_is_shared(task_t *p, task_t *t)
+{
+#ifdef VPROC_MIGRATE_THREAD_GROUP_FIX
+	if ((!p->mm || p->mm != t->mm) &&
+	    (!p->fs || p->fs != t->fs) &&
+	    (!p->files || p->files != t->files) &&
+	    (!p->signal || p->signal != t->signal) &&
+	    (!p->sighand || p->sighand != t->sighand) &&
+	    (!p->sysvsem.undo_list || p->sysvsem.undo_list != t->sysvsem.undo_list) &&
+	    (!p->group_info || p->group_info != t->group_info))
+#else
+	if (p->mm != t->mm && p->fs != t->fs &&
+	    p->files != t->files && p->signal != t->signal &&
+	    p->sighand != t->sighand &&
+	    p->sysvsem.undo_list != t->sysvsem.undo_list &&
+	    p->group_info != t->group_info)
+#endif
+		return 0;
+
+	return 1;
+}
+
 static int
 add_thread_group(struct move_header *h, struct task_struct *p)
 {
@@ -682,11 +696,7 @@
 	for_each_process(t) {
 		if (t == p)
 			continue;
-		if (p->mm != t->mm && p->fs != t->fs &&
-		    p->files != t->files && p->signal != t->signal &&
-		    p->sighand != t->sighand &&
-		    p->sysvsem.undo_list != t->sysvsem.undo_list &&
-		    p->group_info != t->group_info)
+		if (!__proc_is_shared(p, t))
 			continue;
 		count++;
 	}
@@ -702,20 +712,17 @@
 		for_each_process(t) {
 			if (t == p)
 				continue;
-			if (p->mm != t->mm && p->fs != t->fs &&
-			    p->files != t->files && p->signal != t->signal &&
-			    p->sighand != t->sighand &&
-			    p->sysvsem.undo_list != t->sysvsem.undo_list &&
-			    p->group_info != t->group_info)
+			if (!__proc_is_shared(p, t))
 				continue;
 			tpid = t->pid;
 			ttgid = t->tgid;
-			memcpy(tcomm, t->comm, sizeof(tcomm));
+#ifndef VPROC_MIGRATE_THREAD_GROUP_FIX
 			if (p->mm != t->mm || p->fs != t->fs ||
 			    p->files != t->files || p->signal != t->signal ||
 			    p->sighand != t->sighand ||
 			    p->sysvsem.undo_list != t->sysvsem.undo_list ||
 			    p->group_info != t->group_info) {
+				memcpy(tcomm, t->comm, sizeof(tcomm));
 				read_unlock(&tasklist_lock);
 				kfree(pidp);
 				printk(KERN_DEBUG
@@ -726,7 +733,9 @@
 				       tcomm);
 				return -EINVAL;
 			}
+#endif
 			if (leader > 0 && ttgid != leader) {
+				memcpy(tcomm, t->comm, sizeof(tcomm));
 				read_unlock(&tasklist_lock);
 				kfree(pidp);
 				printk(KERN_DEBUG
@@ -738,6 +747,7 @@
 				return -EINVAL;
 			}
 			if (leader < 0 && ttgid != tpid) {
+				memcpy(tcomm, t->comm, sizeof(tcomm));
 				read_unlock(&tasklist_lock);
 				kfree(pidp);
 				printk(KERN_DEBUG
@@ -745,7 +755,7 @@
 				       "has different tgid %d"
 				       " (expected %d)\n",
 				       __FUNCTION__, tpid, tcomm, ttgid,
-				       leader);
+				       tpid);
 				return -EINVAL;
 			}
 			if (i < count)
@@ -787,12 +797,11 @@
 			retval = -EINVAL;
 		}
 		if (leader > 0) {
-			tcount = 0;
+			tcount = 1;
+			t = p;
 			read_lock(&tasklist_lock);
-			for (t = next_thread(p); t != p ; t = next_thread(t))
-				tcount++;
+			while_each_thread(p, t) tcount++;
 			read_unlock(&tasklist_lock);
-			tcount++;
 			if (tcount != count) {
 				printk(KERN_DEBUG
 				       "%s: group(%d)/share imbalance %d/%d\n",
@@ -808,9 +817,7 @@
 static int
 setup_pid_move(struct move_header *h, pid_t pid, pid_t leader)
 {
-	int retval = 0;
-	int was_seen = 0;
-	int tmpret;
+	int retval = 0, was_seen = 0, tmpret;
 	struct move_data *d;
 	struct task_struct *p;
 	unsigned long flags;
@@ -993,14 +1000,11 @@
 	int retval;
 	int do_drop;
 
-	struct list_head *curr;
-	struct list_head *next;
-	struct move_data *d;
+	struct move_data *d, *next;
 	LIST_HEAD(unseen_list);
 
 	spin_lock(&h->mh_lock);
-	list_for_each(curr, &h->mh_datalist) {
-		d = list_entry(curr, struct move_data, m_list);
+	list_for_each_entry(d, &h->mh_datalist, m_list) {
 		d->m_seen = 0;
 	}
 	spin_unlock(&h->mh_lock);
@@ -1011,8 +1015,7 @@
 		retval = setup_pid_move(h, h->mh_id, 0);
 
 	spin_lock(&h->mh_lock);
-	list_for_each_safe(curr, next, &h->mh_datalist) {
-		d = list_entry(curr, struct move_data, m_list);
+	list_for_each_entry_safe(d, next, &h->mh_datalist, m_list) {
 		if (!d->m_seen)
 			list_move(&d->m_list, &unseen_list);
 	}
@@ -1148,7 +1151,6 @@
 	int leaders;
 	int ret;
 	int tmperr;
-	struct list_head *curr;
 
 	nsc_daemonize();
 
@@ -1202,8 +1204,7 @@
 	leaders = 0;
 	j = total;
 	spin_lock(&h->mh_lock);
-	list_for_each(curr, &h->mh_datalist) {
-		d = list_entry(curr, struct move_data, m_list);
+	list_for_each_entry(d, &h->mh_datalist, m_list) {
 		proc_list[i++] = d->m_pid;
 		if (!d->m_leader)
 			data_list[leaders++] = get_move_data(d);
@@ -1734,27 +1735,24 @@
 void
 move_out_nodedown(struct move_header *h)
 {
-	struct list_head *curr;
 	struct move_data *d;
 
 	for (;;) {
-		d = NULL;
 		spin_lock(&h->mh_lock);
-		list_for_each(curr, &h->mh_datalist) {
-			d = list_entry(curr, struct move_data, m_list);
+		list_for_each_entry(d, &h->mh_datalist, m_list) {
 			if (d->m_state == PM_MIGRATE_OUT_START) {
 				(void)get_move_data(d);
-				break;
+				spin_unlock(&h->mh_lock);
+				goto wait_migrate;
 			}
 			if (d->m_state == PM_MIGRATE_OUT)
 				(void)set_move_both_states(d, PM_MIGRATE_OUT,
 							   PM_MIGRATE_OUT,
 							   PM_MIGRATE_OUT_DONE);
-			d = NULL;
 		}
 		spin_unlock(&h->mh_lock);
-		if (!d)
-			break;
+		break;
+wait_migrate:
 		(void)move_data_wait_for_state_change(d, PM_MIGRATE_OUT_START);
 		put_move_data(d);
 	}
@@ -1764,14 +1762,11 @@
 void
 move_nodedown_cleanup(clusternode_t node)
 {
-	struct move_header *h;
-	struct list_head *curr;
-	struct list_head *next;
+	struct move_header *h, *next;
 	LIST_HEAD(down_list);
 
 	spin_lock(&movement_list_lock);
-	list_for_each_safe(curr, next, &movement_list) {
-		h = list_entry(curr, struct move_header, mh_list);
+	list_for_each_entry_safe(h, next, &movement_list, mh_list) {
 		if (h->mh_ctlnode == node || h->mh_dstnode == node) {
 			(void)get_move_header(h);
 			list_move(&h->mh_list, &down_list);
@@ -1931,8 +1926,7 @@
 		count++;
 	printk(KERN_DEBUG "wait_queue_head_t @ %p (%d waiters)\n",
 	       wqhp, count);
-	list_for_each(curr, &wqhp->task_list) {
-		wqp = list_entry(curr, wait_queue_t, task_list);
+	list_for_each_entry(wqp, &wqhp->task_list, task_list) {
 		printk(KERN_DEBUG "waiter procp %p pid %d flags 0x%x\n",
 		       wqp->task, wqp->task->pid, wqp->flags);
 	}
@@ -1957,7 +1951,6 @@
 void
 print_move_header(struct move_header *h)
 {
-	struct list_head *curr;
 	struct move_data *d;
 
 #define TYPE_STR(_type, _flag)	((_type & _flag) ? " "#_flag : "")
@@ -1985,8 +1978,7 @@
 	printk(KERN_DEBUG "mh_timeout = %d\n", h->mh_timeout);
 	printk(KERN_DEBUG "mh_aborting = %d\n", h->mh_aborting);
 	print_wqh(&h->mh_wqh);
-	list_for_each(curr, &h->mh_datalist) {
-		d = list_entry(curr, struct move_data, m_list);
+	list_for_each_entry(d, &h->mh_datalist, m_list) {
 		print_move_data(d);
 	}
 

Index: rproc_svr_vproc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/rproc_svr_vproc.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- rproc_svr_vproc.c	10 Oct 2008 08:10:32 -0000	1.13
+++ rproc_svr_vproc.c	3 Feb 2009 06:18:13 -0000	1.14
@@ -388,8 +388,9 @@
 						    "perm svr parent");
 		if (vp == 0) {
 			printk("rexecve_server: cannot find parent");
-#ifndef VPROC_HOLD_ZERO_GET_TASK
 			pve->pvp_pproc = NULL;
+#ifdef VPROC_HOLD_ZERO_GET_TASK
+			put_task_struct(procp);
 #endif
 			VPROC_UNLOCK_EXCL(ve,"rexecve_server");
 			return -EREMOTE;
@@ -413,8 +414,9 @@
 		 */
 		if (g == 0) {
 			if (pgrp_member_pid_cnt) {
-#ifndef VPROC_HOLD_ZERO_GET_TASK
 				pve->pvp_pproc = NULL;
+#ifdef VPROC_HOLD_ZERO_GET_TASK
+				put_task_struct(procp);
 #endif
 				VPROC_RELE(fvp, "rexecve_server");
 				VPROC_RELE(vp, "rexecve_server");
@@ -455,17 +457,16 @@
                 PVP(vc)->pvp_flag |= child_stat[i];
                 PVP(vc)->pvp_wstate = child_wstate[i];
 		VPROC_UNLOCK_FLAG(vc, "rexecve_server(child)");
-#ifdef VPROC_PVP_CHILD_LL
-		/* Need this lock? */
 		VPROC_LOCK_ND_LIST_EXCL(ve, "rexecve_server");
+#ifdef VPROC_PVP_CHILD_LL
 		SSI_ASSERT(list_empty(&PVP(vc)->pvp_sibling));
 		PVP_ADD_PARENT(PVP(vc), pve);
-		VPROC_UNLOCK_ND_LIST_EXCL(ve, "rexecve_server");
 #else
 		PVP(vc)->pvp_childl = pve->pvp_head_childl;
 		mb();
 		pve->pvp_head_childl = vc;
 #endif /* !VPROC_PVP_CHILD_LL */
+		VPROC_UNLOCK_ND_LIST_EXCL(ve, "rexecve_server");
 	}
 
 	/*
@@ -694,8 +695,9 @@
 						    "perm svr parent");
 		if (vp == 0) {
 			printk("migrate_server: cannot find parent");
-#ifndef VPROC_HOLD_ZERO_GET_TASK
 			pvm->pvp_pproc = NULL;
+#ifdef VPROC_HOLD_ZERO_GET_TASK
+			put_task_struct(procp);
 #endif
 			VPROC_UNLOCK_EXCL(vm,"migrate_server");
 			return -EREMOTE;
@@ -719,8 +721,9 @@
 		 */
 		if (g == 0) {
 			if (pgrp_member_pid_cnt) {
-#ifndef VPROC_HOLD_ZERO_GET_TASK
 				pvm->pvp_pproc = NULL;
+#ifdef VPROC_HOLD_ZERO_GET_TASK
+				put_task_struct(procp);
 #endif
 				VPROC_RELE(fvp, "migrate_server");
 				VPROC_RELE(vp, "migrate_server");
@@ -761,17 +764,16 @@
                 PVP(vc)->pvp_flag |= child_stat[i];
                 PVP(vc)->pvp_wstate = child_wstate[i];
 		VPROC_UNLOCK_FLAG(vc, "migrate_server(child)");
-#ifdef VPROC_PVP_CHILD_LL
-		/* Need this lock? */
 		VPROC_LOCK_ND_LIST_EXCL(vm, "migrate_server");
+#ifdef VPROC_PVP_CHILD_LL
 		SSI_ASSERT(list_empty(&PVP(vc)->pvp_sibling));
 		PVP_ADD_PARENT(PVP(vc), pvm);
-		VPROC_UNLOCK_ND_LIST_EXCL(vm, "migrate_server");
 #else
 		PVP(vc)->pvp_childl = pvm->pvp_head_childl;
 		mb();
 		pvm->pvp_head_childl = vc;
 #endif /* !VPROC_PVP_CHILD_LL */
+		VPROC_UNLOCK_ND_LIST_EXCL(vm, "migrate_server");
 	}
 
 	/*

Index: nd_object.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/nd_object.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- nd_object.c	21 Oct 2004 23:40:50 -0000	1.5
+++ nd_object.c	3 Feb 2009 06:18:13 -0000	1.6
@@ -215,12 +215,21 @@
 				 * Queue the carelist for callbacks to be
 				 * performed asynchronously.
 				 */
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+				error = nsc_async_queue(
+						nsc_generic_async_queue,
+						vproc_object_nodedown_handler,
+						(void *)vchp,
+						sizeof(*vchp),
+						NSC_ASYNC_ARGS_FREE);
+#else
 				error = nsc_async_queue(
 						nsc_generic_async_queue,
 						vproc_object_nodedown_handler,
 						(void *)vchp,
 						sizeof(vproc_carehead_t),
 						0);
+#endif
 				if (error) {
 					printk(KERN_WARNING
 						"vproc_object_nodedown: unable"
@@ -228,12 +237,14 @@
 						" error=%d", error);
 				}
 
+#ifndef NSC_ASYNC_ARGS_ZERO_COPY
 				/*
 				 * Release the carehead structure.  Queueing
 				 * the carelist results in the carehead being
 				 * copied, so the carelist will not be lost.
 				 */
 				vproc_carehead_dealloc(vchp);
+#endif
 			}
 
 			vchp = nvchp;

Index: reopen.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/reopen.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- reopen.c	10 Oct 2008 08:10:32 -0000	1.28
+++ reopen.c	3 Feb 2009 06:18:13 -0000	1.29
@@ -533,7 +533,16 @@
 		kfree(flckp);
 	}
 
-	free_page((unsigned long) path->pathpage);
+	/* Free the page we allocated to hold the pathname */
+	if (path->pathpage) {
+		if ((u_long) path->pathpage == ((u_long) path->pathname & PAGE_MASK))
+			path->pathname = NULL;
+		free_page((unsigned long) path->pathpage);
+	}
+
+	/* JH: Free the pathname if it was not allocated as a page */
+	kfree(path->pathname);
+
 	kfree(path);
 	*pathp = NULL;
 }
@@ -918,7 +927,11 @@
 	cli = rmtfb_getcli_file(file);
 	if (cli) {
 		SSI_ASSERT(!isreg);
+#ifdef REOP_EXPORT_PATH_SVRNODE
+		fb_datap->fb_svrnode = cli->rfb_server;
+#else
 		fb_datap->svrnode = cli->rfb_server;
+#endif
 		fb_datap->fileid = cli->common.rfb_id;
 		rmtfb_putcli(cli);
 	}
@@ -928,7 +941,11 @@
 			error = PTR_ERR(svr);
 			goto free_out;
 		}
+#ifdef REOP_EXPORT_PATH_SVRNODE
+		fb_datap->fb_svrnode = this_node;
+#else
 		fb_datap->svrnode = this_node;
+#endif
 		fb_datap->fileid = svr->common.rfb_id;
 		fb_datap->rfb = (char *) svr;
 	}
@@ -940,9 +957,6 @@
 		fb_datap->pos = file->f_pos;
 		get_f_owner(file, &fb_datap->f_owner);
 	}
-#ifdef REOP_EXPORT_PATH_SVRNODE
-	fb_datap->path->svrnode = fb_datap->svrnode;
-#endif
 
 	fb_datap->ino = inode->i_ino;
 	fb_datap->flags = file->f_flags;
@@ -996,8 +1010,8 @@
 		int flags,
 		clusternode_t svr)
 {
-	struct dentry *dentry;
-	struct vfsmount *mnt;
+	struct dentry *dentry = NULL;
+	struct vfsmount *mnt = NULL;
 	int error;
 	clusternode_t save_nc;
 	struct file *filp;
@@ -1046,7 +1060,11 @@
 		fb_data	*fb_datap,
 		struct file **filep)
 {
+#ifdef REOP_EXPORT_PATH_SVRNODE
+	clusternode_t svrnode = fb_datap->fb_svrnode;
+#else
 	clusternode_t svrnode = fb_datap->svrnode;
+#endif
 	struct file *file = NULL;
 	int error;
 
@@ -1068,12 +1086,11 @@
 		struct rmtfb_cli *cli = rmtfb_getcli_id(
 						fb_datap->path,
 						fb_datap->flags,
-						fb_datap->fileid,
+						fb_datap->fileid
 #ifdef SSI_SOCK_REOP_TYPE
-						fb_datap->svrnode,
-						fb_datap->socket_type
-#else
-						fb_datap->svrnode
+						,fb_datap->socket_type
+#elif !defined(REOP_EXPORT_PATH_SVRNODE)
+						,fb_datap->svrnode
 #endif
 						);
 		error = PTR_ERR(cli);

Index: vp_init.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/vp_init.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- vp_init.c	10 Oct 2008 08:10:32 -0000	1.6
+++ vp_init.c	3 Feb 2009 06:18:13 -0000	1.7
@@ -26,6 +26,9 @@
 #include <linux/init.h>
 #include <linux/nd.h>
 #include <linux/nd_origin.h>
+#ifdef ALLOC_VPROC_HASH_TABLE
+#include <linux/bootmem.h>
+#endif
 #include <cluster/clms.h>
 #include <cluster/icsgen.h>
 #include <cluster/ics_proto.h>
@@ -33,13 +36,19 @@
 /*
  * Actual declarations of vproc table and vproc hash table.
  */
+#ifdef SSI_NOTUSED
 struct vproc *vproc = NULL, *vprocNVPROC = NULL, *vprocfree = NULL;
+#endif
 #ifdef VPROC_HASH_LIST
 struct list_head *vproc_hash;
 #else
 struct vproc **vproc_hash;
 #endif
+#ifdef ALLOC_VPROC_HASH_TABLE
+int vprochsz;
+#else
 int vprochsz = VPROC_NHASH;
+#endif
 
 #if defined(VPROC_HASH_LIST) && !defined(VPROC_RCU_LIST)
 RW_LOCK_T vproc_list_lock;	/* Lock for free list and hash table */
@@ -58,6 +67,9 @@
 {
 #ifdef VPROC_HASH_LIST
 	int i;
+#ifdef ALLOC_VPROC_HASH_TABLE
+	unsigned int v_hash_shift;
+#endif
 #endif
 	extern void dpvproc_async_init(void);
 
@@ -71,7 +83,20 @@
 	 * Though the number of vprocs is actually 0 at this stage.
 	 */
 #ifdef VPROC_HASH_LIST
+#ifdef ALLOC_VPROC_HASH_TABLE
+	vproc_hash =
+		alloc_large_system_hash("VProc",
+					sizeof(struct list_head),
+					0,
+					15,
+					HASH_HIGHMEM,
+					&v_hash_shift,
+					NULL,
+					0);
+	vprochsz = 1 << v_hash_shift;
+#else
 	vproc_hash = kzmalloc_nofail(vprochsz * sizeof(struct list_head));
+#endif
 
 	for (i=0; i < vprochsz; i++)
 		INIT_LIST_HEAD(&vproc_hash[i]);
@@ -86,6 +111,9 @@
 
 	VPROC_LIST_LOCK_INIT();
 #endif
+#ifdef VPROC_KMEM_CACHE
+	vproc_cache_init();
+#endif
 
 	vproc_origin_list_init();
 	vproc_object_nodedown_init();

Index: dvp_async.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/dvp_async.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- dvp_async.c	10 Oct 2008 08:10:32 -0000	1.10
+++ dvp_async.c	3 Feb 2009 06:18:13 -0000	1.11
@@ -90,6 +90,43 @@
 	int flag,
 	cred_t *cr)
 {
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+	struct dvp_sigproc_async *sigproc_data;
+	int error;
+
+	sigproc_data = kmalloc(sizeof(*sigproc_data), GFP_ATOMIC);
+	if (!sigproc_data) {
+		error = -ENOMEM;
+		goto out_err;
+	}
+
+	sigproc_data->pid = pid;
+	sigproc_data->sig = sig;
+	if (pinfo != NULL)
+		sigproc_data->procinfo = *pinfo;
+	sigproc_data->have_procinfo = (pinfo != NULL);
+	sigproc_data->flag = flag;
+	if (cr != NULL)
+		get_rpccred(cr);
+	sigproc_data->cr = cr;
+
+	error = nsc_async_queue(nsc_generic_async_queue,
+				dpvproc_sigproc_async_handler,
+				sigproc_data,
+				sizeof(*sigproc_data),
+				NSC_ASYNC_DUPCHECK | NSC_ASYNC_ARGS_FREE);
+	if (error) {
+		if (cr != NULL)
+			put_rpccred(cr);
+		goto out_err;
+	}
+
+	return error;
+
+out_err:
+	printk(KERN_WARNING "%s: unable to allocate async event; error=%d",
+			__FUNCTION__, error);
+#else
 	struct dvp_sigproc_async sigproc_data;
 	int error = 0;
 
@@ -111,9 +148,9 @@
 	if (error) {
 		if (cr != NULL)
 			put_rpccred(cr);
-
 		printk(KERN_WARNING "dpvproc_sigproc_async_queue: unable to allocate async event; error=%d", error);
 	}
+#endif /* !NSC_ASYNC_ARGS_ZERO_COPY */
 
 	return error;
 }
@@ -168,6 +205,43 @@
 	int flag,
 	cred_t *cr)
 {
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+	struct dvp_sigpgrp_async *sigpgrp_data;
+	int error;
+
+	sigpgrp_data = kmalloc(sizeof(*sigpgrp_data), GFP_ATOMIC);
+	if (!sigpgrp_data) {
+		error = -ENOMEM;
+		goto out_err;
+	}
+
+	sigpgrp_data->pgrp = pgrp;
+	sigpgrp_data->sig = sig;
+	if (pinfo != NULL)
+		sigpgrp_data->procinfo = *pinfo;
+	sigpgrp_data->have_procinfo = (pinfo != NULL);
+	sigpgrp_data->flag = flag;
+	if (cr != NULL)
+		get_rpccred(cr);
+	sigpgrp_data->cr = cr;
+
+	error = nsc_async_queue(nsc_generic_async_queue,
+				dpvproc_sigpgrp_async_handler,
+				sigpgrp_data,
+				sizeof(*sigpgrp_data),
+				NSC_ASYNC_DUPCHECK | NSC_ASYNC_ARGS_FREE);
+	if (error) {
+		if (cr != NULL)
+			put_rpccred(cr);
+		goto out_err;
+	}
+
+	return error;
+
+out_err:
+	printk(KERN_WARNING "%s: unable to allocate async event; error=%d",
+			__FUNCTION__, error);
+#else
 	struct dvp_sigpgrp_async sigpgrp_data;
 	int error = 0;
 
@@ -193,6 +267,7 @@
 		printk(KERN_WARNING
 "dpvproc_sigpgrp_async_queue: unable to allocate async event; error=%d", error);
 	}
+#endif /* !NSC_ASYNC_ARGS_ZERO_COPY */
 
 	return error;
 }
@@ -299,15 +374,11 @@
 #else
 		do {
 #endif
-			error = PVPOP_REAP(vc,
-				   WAIT_ANY,
-			           VPROC_WZOMBIE,
-				   tgid,
-			           &wstat,
+			error = PVPOP_REAP(vc, WAIT_ANY, VPROC_WZOMBIE, tgid,
 #ifdef VPROC_RW_LOCK
-			           &pu_loc, FALSE);
+					&wstat, &pu_loc, FALSE);
 #else
-			           &pu_loc);
+					&wstat, &pu_loc);
 #endif
 #ifdef VPROC_CONTINUE
 			if (error >= 0)
@@ -334,7 +405,7 @@
 #else
 		if (!IS_SYSPROC(PVP(vc)) && PVP(vp)->pvp_pproc)
 #endif
-			(void)pproc_add_pusage(PVP(vp)->pvp_pproc, &pu_loc);
+			(void) pproc_add_pusage(PVP(vp)->pvp_pproc, &pu_loc);
 		if (PIDNODE(vp->vp_pid))
 			dpvproc_remove_parent_child_care(vp->vp_pid,
 							vc->vp_pid, TRUE);
@@ -362,8 +433,14 @@
 	struct vproc *vp,
 	struct vproc *vc)
 {
-	struct dvp_nocldwait_async nocldwait_data;
 	int error;
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+	struct dvp_nocldwait_async *nocldwait_data;
+
+	nocldwait_data = kmalloc_nofail(sizeof(*nocldwait_data));
+#else
+	struct dvp_nocldwait_async nocldwait_data;
+#endif
 
 	if (vp) {
 		VPROC_HOLD(vp, "temp nocldwait async (parent)");
@@ -376,6 +453,16 @@
 	VPROC_HOLD(vc, "temp nocldwait async (child)");
 #endif
 
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+	nocldwait_data->vp = vp;
+	nocldwait_data->vc = vc;
+
+	error = nsc_async_queue(nsc_async_nocldwait_queue,
+				dpvproc_nocldwait_async_handler,
+				nocldwait_data,
+				sizeof(*nocldwait_data),
+				NSC_ASYNC_SLEEP | NSC_ASYNC_ARGS_FREE);
+#else
 	nocldwait_data.vp = vp;
 	nocldwait_data.vc = vc;
 
@@ -384,6 +471,7 @@
 				&nocldwait_data,
 				sizeof(struct dvp_nocldwait_async),
 				NSC_ASYNC_SLEEP);
+#endif /* !NSC_ASYNC_ARGS_ZERO_COPY */
 #ifdef VPROC_DEBUG
 	printk(KERN_DEBUG "%s:child %d for parent %d\n",
 			__FUNCTION__, vc->vp_pid, vp? vp->vp_pid : -1);
@@ -433,8 +521,34 @@
 	struct vproc *vc,
 	int	ppid)
 {
-	struct dvp_rmv_pgrp_async rmv_data;
 	int error;
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+	struct dvp_rmv_pgrp_async *rmv_data;
+
+	rmv_data = kmalloc(sizeof(*rmv_data), GFP_ATOMIC);
+	if (!rmv_data) {
+		error = -ENOMEM;
+		goto out;
+	}
+
+	VPROC_HOLD(vg, "temp rmv_pgrp async (pgrp ldr)");
+
+	VPROC_HOLD(vc, "temp rmv_pgrp async (pgrp member)");
+
+	VPROC_HOLD_MOVEMENT(vg, "dpvproc_rmv_pgrp_async_queue");
+
+	rmv_data->vg = vg;
+	rmv_data->vc = vc;
+	rmv_data->ppid = ppid;
+
+	error = nsc_async_queue(nsc_generic_async_queue,
+				dpvproc_rmv_pgrp_async_handler,
+				rmv_data,
+				sizeof(*rmv_data),
+				NSC_ASYNC_DUPCHECK | NSC_ASYNC_ARGS_FREE);
+out:
+#else
+	struct dvp_rmv_pgrp_async rmv_data;
 
 	VPROC_HOLD(vg, "temp rmv_pgrp async (pgrp ldr)");
 
@@ -451,8 +565,8 @@
 				&rmv_data,
 				sizeof(struct dvp_rmv_pgrp_async),
 				NSC_ASYNC_DUPCHECK);
-	if (error) {
-		printk(KERN_WARNING
-"dpvproc_rmv_pgrp_async_queue:unable to allocate async event; error=%d", error);
-	}
+#endif /* !NSC_ASYNC_ARGS_ZERO_COPY */
+	if (error)
+		printk(KERN_WARNING "%s: unable to allocate async event; error=%d",
+				__FUNCTION__, error);
 }

Index: nd_subr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/nd_subr.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- nd_subr.c	21 Oct 2004 23:40:50 -0000	1.5
+++ nd_subr.c	3 Feb 2009 06:18:13 -0000	1.6
@@ -50,9 +50,7 @@
 vproc_lock_origin_node(
 	clusternode_t origin_node)
 {
-	vproc_origin_data_t *vodp;
-
-	vodp = vproc_origin_find(origin_node);
+	vproc_origin_data_t *vodp = vproc_origin_find(origin_node);
 
 	/*
 	 * If the origin to be locked is marked pending, then
@@ -61,16 +59,16 @@
 	 * a deadlock with processes needed to load modules. This may be
 	 * wrong.
 	 */
-	if (vodp != NULL && (vodp->vod_flags & VOD_PENDING) &&
-	    origin_node != this_node) {
-		UNLOCK_SHR_RW_LOCK(&vodp->vod_rwlock);
-		return NULL;
+	if (vodp) {
+		if ((vodp->vod_flags & VOD_PENDING) &&
+		    origin_node != this_node) {
+			UNLOCK_SHR_RW_LOCK(&vodp->vod_rwlock);
+			return NULL;
+		}
+		return (void *)(&vodp->vod_rwlock);
 	}
 
-	if (vodp == NULL)
-		return NULL;
-	else
-		return (void *)(&vodp->vod_rwlock);
+	return NULL;
 }
 
 /*

Index: rproc_cli_vproc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/rproc_cli_vproc.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- rproc_cli_vproc.c	10 Oct 2008 08:10:32 -0000	1.9
+++ rproc_cli_vproc.c	3 Feb 2009 06:18:13 -0000	1.10
@@ -188,17 +188,16 @@
 	}
 
 	pvc = PVP(vc);
-#ifdef VPROC_PVP_CHILD_LL
-	/* Need this lock? */
 	VPROC_LOCK_ND_LIST_EXCL(vp, "cli_rfork");
+#ifdef VPROC_PVP_CHILD_LL
 	SSI_ASSERT(list_empty(&pvc->pvp_sibling));
 	PVP_ADD_PARENT(pvc, pvp);
-	VPROC_UNLOCK_ND_LIST_EXCL(vp, "cli_rfork");
 #else
 	pvc->pvp_childl = pvp->pvp_head_childl;
 	mb();
 	pvp->pvp_head_childl = vc;
 #endif /* !VPROC_PVP_CHILD_LL */
+	VPROC_UNLOCK_ND_LIST_EXCL(vp, "cli_rfork");
 	pvc->pvp_ppid = vp->vp_pid;		/* parent's pid */
 	pvc->pvp_oppid = 0;			/* clear original parent */
 
@@ -385,19 +384,10 @@
 	 * Adjust reference counts for parent, pgrp, and session leader of
 	 * the rexec'ing process.
 	 */
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-	VPROC_RELE(VPROCPTR_NOHOLD(pve->pvp_ppid), "rexecve (parent on child node)");
-#else
-	VPROC_RELE(VPROCPTR(pve->pvp_ppid), "rexecve (parent on child node)");
-#endif
+	VPROC_RELE_PID(pve->pvp_ppid, "rexecve (parent on child node)");
 	if (pve->pvp_pgid != 0)
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(VPROCPTR_NOHOLD(pve->pvp_pgid),
-			   "rexecve (pgrp leader on member node)");
-#else
-		VPROC_RELE(VPROCPTR(pve->pvp_pgid),
+		VPROC_RELE_PID(pve->pvp_pgid,
 			   "rexecve (pgrp leader on member node)");
-#endif
 
 	/*
 	 * The parent-child-sibling list is now on the remote node.  Clean
@@ -427,17 +417,13 @@
 		VPROC_LOCK_FLAG(ve, "rexecve");
 		pve->pvp_flag &= ~PV_PGRPLEADER;
 		VPROC_UNLOCK_FLAG(ve, "rexecve");
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(VPROCPTR_NOHOLD(pve->pvp_sid),
-			      "rexecve (session leader on member node)");
-#else
-		VPROC_RELE(VPROCPTR(pve->pvp_sid),
+		VPROC_RELE_PID(pve->pvp_sid,
 			      "rexecve (session leader on member node)");
-#endif
 		while (pve->pvp_head_pgrpl != NULL) {
 			register struct vproc *vg = pve->pvp_head_pgrpl;
 
 			pve->pvp_head_pgrpl = PVP(vg)->pvp_pgrpl;
+			mb();
 			PVP(vg)->pvp_pgrpl = NULL;
 			VPROC_RELE(vg, "rexecve (pgrp member on ldr node)");
 			VPROC_RELE(ve, "rexecve (pgrp leader on ldr node)");
@@ -669,19 +655,10 @@
 	 * Adjust reference counts for parent, pgrp, and session leader of
 	 * the migrated process.
 	 */
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-	VPROC_RELE(VPROCPTR_NOHOLD(pvm->pvp_ppid), "migrate (parent on child node)");
-#else
-	VPROC_RELE(VPROCPTR(pvm->pvp_ppid), "migrate (parent on child node)");
-#endif
+	VPROC_RELE_PID(pvm->pvp_ppid, "migrate (parent on child node)");
 	if (pvm->pvp_pgid != 0)
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(VPROCPTR_NOHOLD(pvm->pvp_pgid),
-			   "migrate (pgrp leader on member node)");
-#else
-		VPROC_RELE(VPROCPTR(pvm->pvp_pgid),
+		VPROC_RELE_PID(pvm->pvp_pgid,
 			   "migrate (pgrp leader on member node)");
-#endif
 
 	/*
 	 * The parent-child-sibling list is now on the remote node.  Clean
@@ -711,13 +688,8 @@
 		VPROC_LOCK_FLAG(vm, "migrate");
 		pvm->pvp_flag &= ~PV_PGRPLEADER;
 		VPROC_UNLOCK_FLAG(vm, "migrate");
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(VPROCPTR_NOHOLD(pvm->pvp_sid),
-			      "migrate (session leader on member node)");
-#else
-		VPROC_RELE(VPROCPTR(pvm->pvp_sid),
+		VPROC_RELE_PID(pvm->pvp_sid,
 			      "migrate (session leader on member node)");
-#endif
 		while (pvm->pvp_head_pgrpl != NULL) {
 			register struct vproc *vg = pvm->pvp_head_pgrpl;
 

Index: dvp_pvpsops.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/dvp_pvpsops.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- dvp_pvpsops.c	10 Oct 2008 08:10:32 -0000	1.15
+++ dvp_pvpsops.c	3 Feb 2009 06:18:13 -0000	1.16
@@ -1782,8 +1782,15 @@
 
 	/* perform local operation */
 
+#ifdef LOADLEVEL_TABLE_LIST
+	LOADLIST_LOCK_SHARED();
+	if (action && list_empty(&loadlevel_table))
+		printk("Warning: /proc/cluster/loadlevellist is empty\n");
+	LOADLIST_UNLOCK_SHARED();
+#else
 	if (action && !loadlevel_table)
 		printk("Warning: /proc/cluster/loadlevellist is empty\n");
+#endif
 
 	/* get some lock */
 	loadlevel_on = action;

Index: nsc_initproc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/nsc_initproc.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- nsc_initproc.c	10 Oct 2008 08:10:32 -0000	1.20
+++ nsc_initproc.c	3 Feb 2009 06:18:13 -0000	1.21
@@ -376,9 +376,11 @@
 				break;
 		}
 		if (cvp == NULL) {
+			VPROC_LOCK_ND_LIST_EXCL(vp, "initproc_add_reclaim_children");
 			PVP(nvp)->pvp_childl = pvp->pvp_head_childl;
 			mb();
 			pvp->pvp_head_childl = nvp;
+			VPROC_UNLOCK_ND_LIST_EXCL(vp, "initproc_add_reclaim_children");
 			VPROC_HOLD(vp, "initproc_add_reclaim_children");
 		}
 #endif /* !VPROC_PVP_CHILD_LL */

Index: dvp_vpops.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/dvp_vpops.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- dvp_vpops.c	10 Oct 2008 08:10:32 -0000	1.37
+++ dvp_vpops.c	3 Feb 2009 06:18:13 -0000	1.38
@@ -398,21 +398,21 @@
 	pvc->pvp_pproc = procp;
 
 	/* sort out the immediate family relationships */
+	VPROC_LOCK_ND_LIST_EXCL(pp, "vpop_fork");
 #ifdef VPROC_PVP_CHILD_LL
 #if 0
 	/* already done in vproc_alloc; keep for reference */
 	INIT_LIST_HEAD(&pvc->pvp_sibling);
 	INIT_LIST_HEAD(&pvc->pvp_children);
 #endif
-	VPROC_LOCK_ND_LIST_EXCL(pp, "vpop_fork");
 	PVP_ADD_PARENT(pvc, pvp);
-	VPROC_UNLOCK_ND_LIST_EXCL(pp, "vpop_fork");
 #else
 	pvc->pvp_childl = pvp->pvp_head_childl; /* put child on its parent's */
 	mb();
 	pvp->pvp_head_childl = vc;	/* child list */
 	pvc->pvp_head_childl = NULL;	/* child has no children */
 #endif /* !VPROC_PVP_CHILD_LL */
+	VPROC_UNLOCK_ND_LIST_EXCL(pp, "vpop_fork");
 	pvc->pvp_ppid = pp->vp_pid;	/* set child's parent id */
 	pvc->pvp_pgid = pvp->pvp_pgid;	/* child's pgrp is parent's */
 	pvc->pvp_sid = pvp->pvp_sid;	/* child's session is parent's */
@@ -932,9 +932,7 @@
 #ifdef VPROC_PVP_CHILD_LL
 	struct pvproc *n;
 #else
-#ifndef VPROC_RW_LOCK
 	register struct vproc *vo;
-#endif
 #endif /* !VPROC_PVP_CHILD_LL */
 	int found;
 	int cur_options = 0;
@@ -943,6 +941,28 @@
 	pid_t pgid = WAIT_ANY;
 	int exit_code = 0;
 	int tgid;
+#ifdef DE_THREAD__OOPS_FIX
+	int switch_exec_pids = 0;
+#endif
+
+#ifdef VPROC_VPROC_WNOTHREAD
+#ifndef VPROC_WAIT_THREADS
+#define VPROC_WAIT_THREADS(_vp, _options) {			\
+		if (!(_options & VPROC_WNOTHREAD)) {		\
+			task_t *tsk = PVP(_vp)->pvp_pproc;	\
+			read_lock(&tasklist_lock);		\
+			tsk = next_thread(tsk);			\
+			if (tsk->signal != current->signal)	\
+				BUG();				\
+			read_unlock(&tasklist_lock);		\
+			if (tsk != current) {			\
+				/* next thread */		\
+				break;				\
+			}					\
+		}						\
+	}
+#endif
+#endif
 
 #ifdef VPROC_DEBUG
 	extern int vpoptrace;
@@ -973,15 +993,15 @@
 loop:
 	found = FALSE;
 #ifdef VPROC_RW_LOCK
-	VPROC_LOCK_SHARED(vp, "vpop_wait");
-	tgid = pvp->pvp_pproc->tgid;
-#ifdef VPROC_PVP_CHILD_LL
-	PVP_CHILD_FOR_EACH(pvc, n, pvp) {
-		vc = VP(pvc);
-#else
-	for (vc = pvp->pvp_head_childl; vc; vc = PVP(vc)->pvp_childl) {
-#endif /* !VPROC_PVP_CHILD_LL */
-#else
+	/* Lock ordering:
+	 * pvp_generic_lock	(vpop_wait)
+	 *			...
+	 *			(wait_task_zombie)
+	 *			(__ptrace_unlink)
+	 *			...
+	 * EX pvp_generic_lock	(pvpop_reclaim_child)
+	 */
+#endif
 	VPROC_LOCK_EXCL(vp, "vpop_wait");
 	tgid = pvp->pvp_pproc->tgid;
 #ifdef VPROC_PVP_CHILD_LL
@@ -992,7 +1012,6 @@
 				vc != NULL;
 				vo = vc, vc = PVP(vc)->pvp_childl) {
 #endif /* !VPROC_PVP_CHILD_LL */
-#endif /* !VPROC_RW_LOCK */
 #ifdef VPROC_DEBUG
 		if (vpoptrace)
 		printk("vpop_wait: child vproc 0x%x, child pid %d\n",
@@ -1006,8 +1025,20 @@
 					(int) pid, (int) vc->vp_pid);
 #endif /* VPROC_DEBUG */
 			/* we're waiting for a specific child */
+#ifdef DE_THREAD__OOPS_FIX
+			if (vc->vp_pid != pid ) {
+				/* SSI_XXX: potentially remote */
+				if (PVP(vc)->pvp_pproc &&
+				    PVP(vc)->pvp_pproc->pid == pid)
+					/* de_thread() switched pproc pids */
+					switch_exec_pids = 1;
+				else
+					continue;
+			}
+#else
 			if (vc->vp_pid != pid )
 				continue;
+#endif
 		}
 #ifndef VPROC_PVP_CHILD_LL
 		pvc = PVP(vc);
@@ -1101,37 +1132,24 @@
 				/* thread group leader of a non empty list */
 				if (ret == -EBUSY)
 					found = TRUE;
+				if (ret == -EDEADLK) {
 #else
-#ifndef VPROC_WAIT_THREADS
-#define VPROC_WAIT_THREADS(_vp, _options) {			\
-		if (!(_options & VPROC_WNOTHREAD)) {		\
-			task_t *tsk = PVP(_vp)->pvp_pproc;	\
-			read_lock(&tasklist_lock);		\
-			tsk = next_thread(tsk);			\
-			if (tsk->signal != current->signal)	\
-				BUG();				\
-			read_unlock(&tasklist_lock);		\
-			if (tsk != current) {			\
-				/* next thread */		\
-				break;				\
-			}					\
-		}						\
-	} 
+				if (ret == -EAGAIN || ret == -EDEADLK) {
 #endif
-				if (ret == -EAGAIN) {
-#ifdef VPROC_RW_LOCK
-					VPROC_UNLOCK_SHARED(vp, "vpop_wait");
-#else
 					VPROC_UNLOCK_EXCL(vp, "vpop_wait");
+#ifdef VPROC_RW_LOCK
+					idelay(HZ/10);
 #endif
 					goto loop;
-				} else
+				}
+#ifdef VPROC_VPROC_WNOTHREAD
+				else
 				/* thread group leader of a non empty list */
 				if (ret == -EBUSY) {
 					VPROC_WAIT_THREADS(vp, options);
 					found = TRUE;
 				}
-#endif /* VPROC_VPROC_WNOTHREAD */
+#endif
 				break;
 			}
 
@@ -1149,6 +1167,11 @@
 				break;
 
 			/* remember child's ID */
+#ifdef DE_THREAD__OOPS_FIX
+			if (switch_exec_pids)
+				*ret_val = pid;
+			else
+#endif
 			*ret_val = vc->vp_pid;
 
 			/*
@@ -1157,20 +1180,12 @@
 			 */
 			if (!(options & VPROC_WNOWAIT))
 			{
-#ifdef VPROC_RW_LOCK
-				VPROC_UNLOCK_SHARED(vp, "vpop_wait");
-				VPROC_LOCK_EXCL(vp, "vpop_wait");
-#endif
 #ifdef CONFIG_VPROC_ND
 				if (vp->vp_pid == 1 || PIDNODE(vp->vp_pid))
 				   dpvproc_remove_child_parent_care(vp->vp_pid,
 								 vc->vp_pid,
 								 FALSE);
 #endif
-#ifdef VPROC_RW_LOCK
-				VPROC_HOLD(vc, "vpop_wait(child)");
-				PVPOP_RMV_CHILD_FROM_PARENT(vp, vc, TRUE);
-#else
 				VPROC_LOCK_ND_LIST_EXCL(vp, "vpop_wait");
 #ifdef VPROC_PVP_CHILD_LL
 				PVP_REMOVE_PARENT(pvc);
@@ -1184,10 +1199,9 @@
 				pvc->pvp_childl = NULL;
 #endif /* !VPROC_PVP_CHILD_LL */
 				VPROC_UNLOCK_ND_LIST_EXCL(vp, "vpop_wait");
-#endif /* !VPROC_RW_LOCK */
 
 				/* Accumulate child's stats in parent */
-				pproc_add_pusage(PVP(vp)->pvp_pproc, pu_loc);
+				(void) pproc_add_pusage(PVP(vp)->pvp_pproc, pu_loc);
 
 				/*
 				 * Now release the child vproc on the node of
@@ -1198,18 +1212,10 @@
 				pvc->pvp_flag |= PV_WAITED;
 				VPROC_UNLOCK_FLAG(vc, "vpop_wait");
 				VPROC_RELE(vc, "vpop_wait(child)");
-#ifdef VPROC_RW_LOCK
-				VPROC_UNLOCK_EXCL(vp, "vpop_wait");
-				return(ESUCCESS);
-#endif
 			}
 out:
 
-#ifdef VPROC_RW_LOCK
-			VPROC_UNLOCK_SHARED(vp, "vpop_wait");
-#else
 			VPROC_UNLOCK_EXCL(vp, "vpop_wait");
-#endif
 			return(ESUCCESS);
 
 #ifdef CONFIG_VPROC_ND
@@ -1233,26 +1239,14 @@
 			*ret_val = vc->vp_pid;
 
 			if (options & VPROC_WNOWAIT) {
-#ifdef VPROC_RW_LOCK
-				VPROC_UNLOCK_SHARED(vp, "vpop_wait");
-#else
 				VPROC_UNLOCK_EXCL(vp, "vpop_wait");
-#endif
 				return(ESUCCESS);
 			}
 
-#ifdef VPROC_RW_LOCK
-			VPROC_UNLOCK_SHARED(vp, "vpop_wait");
-			VPROC_LOCK_EXCL(vp, "vpop_wait");
-#endif
 			dpvproc_remove_child_parent_care(vp->vp_pid,
 							 vc->vp_pid,
 							 FALSE);
 
-#ifdef VPROC_RW_LOCK
-			VPROC_HOLD(vc, "vpop_wait(child)");
-			PVPOP_RMV_CHILD_FROM_PARENT(vp, vc, TRUE);
-#else
 			VPROC_LOCK_ND_LIST_EXCL(vp, "vpop_wait");
 #ifdef VPROC_PVP_CHILD_LL
 			PVP_REMOVE_PARENT(pvc);
@@ -1265,7 +1259,6 @@
 			pvc->pvp_childl = NULL;
 #endif /* !VPROC_PVP_CHILD_LL */
 			VPROC_UNLOCK_ND_LIST_EXCL(vp, "vpop_wait");
-#endif /* !VPROC_RW_LOCK */
 
 			/*
 			 * Release a hold on the process's origin node vproc.
@@ -1323,15 +1316,18 @@
 				/* Didnt find a matching child */
 				if (ret == -ESRCH)
 					break;
-#ifdef VPROC_VPROC_WNOTHREAD
-				if (ret == -EAGAIN) {
-#ifdef VPROC_RW_LOCK
-					VPROC_UNLOCK_SHARED(vp, "vpop_wait");
+#ifndef VPROC_VPROC_WNOTHREAD
+				if (ret == -EDEADLK) {
 #else
+				if (ret == -EAGAIN || ret == -EDEADLK) {
+#endif
 					VPROC_UNLOCK_EXCL(vp, "vpop_wait");
+#ifdef VPROC_RW_LOCK
+					idelay(HZ/10);
 #endif
 					goto loop;
 				}
+#ifdef VPROC_VPROC_WNOTHREAD
 				VPROC_WAIT_THREADS(vp, options);
 #endif
 				/*
@@ -1366,11 +1362,7 @@
 				VPROC_UNLOCK_FLAG(vc, "vpop_wait");
 			}
 
-#ifdef VPROC_RW_LOCK
-			VPROC_UNLOCK_SHARED(vp, "vpop_wait");
-#else
 			VPROC_UNLOCK_EXCL(vp, "vpop_wait");
-#endif
 			return(ESUCCESS);
 
 		default:
@@ -1401,11 +1393,7 @@
 			break;
 	}
 
-#ifdef VPROC_RW_LOCK
-	VPROC_UNLOCK_SHARED(vp, "vpop_wait");
-#else
 	VPROC_UNLOCK_EXCL(vp, "vpop_wait");
-#endif
 
 	if (!found) {
 #ifdef VPROC_DEBUG
@@ -1648,12 +1636,25 @@
 			    PVP(vp)->pvp_flag & PV_IS_LOCAL) {
 				read_lock(&tasklist_lock);
 				if (tsk->ptrace || (sig != -1 &&
-						thread_group_empty(tsk)))
+						thread_group_empty(tsk))) {
+					read_unlock(&tasklist_lock);
 					error = PVPOP_REPORT_STATE(vp, v, &sig,
 								pinfo, state);
-				read_unlock(&tasklist_lock);
+				} else
+					read_unlock(&tasklist_lock);
 			} else
 #endif
+#ifdef VPROC_CONTINUE_SIGCHLD
+			/* Create pinfo for (remote) parent
+			 * required for glibc waitid test
+			 * optional SIGCHLD for SIGCONT.
+			 */
+			if (state == VPROC_UNSTOP) {
+				procinfo_t _pinfo;
+				pproc_pinfo(PVP(v)->pvp_pproc, &_pinfo);
+				error = PVPOP_REPORT_STATE(vp, v, &sig, &_pinfo, state);
+			} else
+#endif /* VPROC_CONTINUE_SIGCHLD */
 				error = PVPOP_REPORT_STATE(vp, v, &sig, pinfo, state);
 			/* set_current_state(current_state); */
 		}
@@ -1668,9 +1669,11 @@
 				if (thread_group_empty(tsk))
 					tsk->exit_signal = -1;
 				if (likely(tsk->ptrace == 0) ||
-				    unlikely(parent && (parent->signal->flags & SIGNAL_GROUP_EXIT)))
-				read_unlock(&tasklist_lock);
+				    unlikely(parent && (parent->signal->flags & SIGNAL_GROUP_EXIT))) {
+					read_unlock(&tasklist_lock);
 					dpvproc_nocldwait_async_queue(vp, v);
+				} else
+					read_unlock(&tasklist_lock);
 #else
 				tsk->exit_signal = -1;
 #endif
@@ -1939,7 +1942,7 @@
 		VPROC_UNLOCK_FLAG(v, "vpop_setctty");
 
 		if (!error) {
-			error = PVPOP_SETCTTY(v, cttydev, cttynode, pgid,
+			(void) PVPOP_SETCTTY(v, cttydev, cttynode, pgid,
 				      flags|PVCTTY_PGRPLDR);
 			error = 0;
 		}
@@ -2105,7 +2108,7 @@
 						  pvp->pvp_pproc->tgid,
 						  &wstat,
 #ifdef VPROC_RW_LOCK
-						  &pu_loc, FALSE);
+						  &pu_loc, TRUE);
 #else
 						  &pu_loc);
 #endif
@@ -2190,11 +2193,7 @@
 		 * add SIGCHLD to parent's signal set.
 		 */
 		if (is_ssig && func != (void *) SIG_DFL && func != (void *) SIG_IGN) {
-#ifdef VPROC_RW_LOCK
-			VPROC_LOCK_SHARED(v, "dpvpop_sigaction(SIGCHLD)");
-#else
 			VPROC_LOCK_EXCL(v, "dpvpop_sigaction(SIGCHLD)");
-#endif
 #ifdef VPROC_PVP_CHILD_LL
 			PVP_CHILD_FOR_EACH(pvc, pvp) {
 #else
@@ -2209,11 +2208,7 @@
 					break;
 				}
 			}
-#ifdef VPROC_RW_LOCK
-			VPROC_UNLOCK_SHARED(v, "vpop_sigaction(SIGCHLD)");
-#else
 			VPROC_UNLOCK_EXCL(v, "vpop_sigaction(SIGCHLD)");
-#endif
 		}
 	}
 

Index: rproc_svr_pproc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/rproc_svr_pproc.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- rproc_svr_pproc.c	20 Apr 2008 05:49:23 -0000	1.22
+++ rproc_svr_pproc.c	3 Feb 2009 06:18:13 -0000	1.23
@@ -308,8 +308,8 @@
 static inline int
 import_dirs(rvp_common_data *comm_datap)
 {
-	struct dentry *root, *pwd, *altroot;
-	struct vfsmount *rootmnt, *pwdmnt, *altrootmnt;
+	struct dentry *root = NULL, *pwd = NULL, *altroot = NULL;
+	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
 	int error;
 
 	error = reop_import_path(comm_datap->comm_p_cdir,

Index: dvp_pvpops.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/dvp_pvpops.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- dvp_pvpops.c	10 Oct 2008 08:10:32 -0000	1.37
+++ dvp_pvpops.c	3 Feb 2009 06:18:13 -0000	1.38
@@ -239,7 +239,7 @@
 	int tgid,			/* parent's thread group id */
 	int *wstat,			/* child termination status */
 	struct pusage_dev *pu_loc,	/* pointer to child resource usage */
-	int pp_read_locked)		/* parent vproc lock is read locked */
+	int pp_locked)			/* parent vproc lock is r/w locked */
 #else
 pvpop_reap(
 	struct vproc *v,		/* child vproc */
@@ -310,9 +310,18 @@
 	 * Note that this lock ensures that we're not reaping
 	 * a process that is still in vproc exit code.
 	 */
+#ifdef VPROC_RW_LOCK
+	if (!pp_locked) {
+		VPROC_LOCK_EXCL(v, "pvpop_reap");
+	} else if (!TRY_VPROC_LOCK_EXCL(v, "pvpop_reap")) {
+		/* RT - Avoid deadlock with parent in SIGCONT path. */
+		VPROC_RELEASE_MOVEMENT(v, "pvpop_reap");
+		return -EDEADLK;
+	}
+#else
 	VPROC_LOCK_EXCL(v, "pvpop_reap");
-	/* SSI_XXX: ...and makes p_exiting useless? */
-	if ((options & VPROC_WZOMBIE) && !(pvp->pvp_flag & PV_EXITING)) { 
+#endif /* !VPROC_RW_LOCK */
+	if ((options & VPROC_WZOMBIE) && !(pvp->pvp_flag & PV_EXITING)) {
 #ifdef VPROC_CONTINUE
 		error = -EBUSY;
 #else
@@ -374,11 +383,6 @@
 		VPROC_LOCK_FLAG(v, "pvpop_reap");
 		pvp->pvp_flag &= ~PV_PROCESS;
 		VPROC_UNLOCK_FLAG(v, "pvpop_reap");
-#else
-		/* If vproc persists as non-empty pgrp or session, the death of
-		 * the leader is determined by PV_IS_ALIVE() macro.
-		 */
-		/* PVPOP_SIGPROC() needs pproc to get to shared signal queue */
 #endif
 
 		/*
@@ -422,6 +426,11 @@
 		VPROC_LOCK_FLAG(v, "pvpop_reap");
 		pvp->pvp_pproc = NULL;
 		VPROC_UNLOCK_FLAG(v, "pvpop_reap");
+#else
+		/* If vproc persists as non-empty pgrp or session, the death of
+		 * the leader is determined by PV_IS_ALIVE() macro.
+		 */
+		/* PVPOP_SIGPROC() needs pproc to get to shared signal queue */
 #endif
 
 		/* Resign from the pgrp */
@@ -446,14 +455,8 @@
 #endif
 		}
 
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(VPROCPTR_NOHOLD(pvp->pvp_ppid),
-			   "pvpop_reap(parent on child node)");
-#else
-		VPROC_RELE(VPROCPTR(pvp->pvp_ppid),
+		VPROC_RELE_PID(pvp->pvp_ppid,
 			   "pvpop_reap(parent on child node)");
-#endif
-
 		VPROC_RELE(v,"pvpop_reap(active)");
 
 
@@ -483,7 +486,9 @@
 
 		if (!(held = VPROC_LOCK_EXCL_HELD(pp))) {
 #ifdef VPROC_RW_LOCK
-			if (pp_read_locked) {
+#error not yet completed
+			if (pp_locked) {
+				/* SSI_XXX: could be ex. locked */
 				VPROC_UNLOCK_SHARED(pp, "pvpop_reap(parent)");
 			}
 #endif
@@ -522,7 +527,8 @@
 #ifndef VPROC_RW_LOCK
 			VPROC_UNLOCK_EXCL(pp, "pvpop_reap(parent)");
 #else
-			if (pp_read_locked) {
+			if (pp_locked) {
+				/* SSI_XXX: could be ex. locked */
 				RW_LOCK_T *lockp = &PVP(pp)->pvp_generic_lock;
 				downgrade_write(&lockp->rwsl_semaphore);
 			} else
@@ -601,13 +607,8 @@
 	 * Add child to its new parent's parent-sibling-child list
 	 */
 	 if (!held) {
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-		if (pp->vp_pid != 1 &&
-		    PV_IS_ALIVE(PVP(v)) && PVP(v)->pvp_pproc->ptrace) {
-#else
 		if (pp->vp_pid != 1 &&
 		    PVP(v)->pvp_pproc && PVP(v)->pvp_pproc->ptrace) {
-#endif
 			if (!(TRY_VPROC_LOCK_EXCL(pp, 
 					"pvpop_add_child_to_parent(parent)"))) {
 				error = -EAGAIN;
@@ -739,7 +740,7 @@
 
 		/* Avoid deadlock */
 		held = 1;
-		while (count++ < 10) {
+		for (;;) {
 			if (TRY_VPROC_LOCK_EXCL(pp,
 			    "pvpop_rmv_child_from_parent(parent)")) {
 				/* Got lock */
@@ -747,12 +748,12 @@
 				break;
 			}
 			idelay(HZ/10);
-		}
-#ifdef VPROC_DEBUG
-		if (count > 10)
-			printk(KERN_DEBUG "%s: skipped parent lock %d\n",
+			if (count++ < 10)
+				continue;
+			printk(KERN_WARNING "%s: waiting for parent lock %d\n",
 				__FUNCTION__, pp->vp_pid);
-#endif
+			count = 0;
+		}
 	}
 #endif
 
@@ -995,7 +996,7 @@
 	VPROC_UNLOCK_EXCL(vi, "pvpop_reassign_child");
 
 	if (pvp->pvp_oppid) {
-		PVPOP_RMV_FROM_ORIGINALCHILD_LIST(vi, v);
+		(void) PVPOP_RMV_FROM_ORIGINALCHILD_LIST(vi, v);
 		pvp->pvp_oppid = 0;
 	}
 #ifdef CONFIG_VPROC_ND
@@ -1203,14 +1204,13 @@
 	 */
 #ifndef VPROC_RW_LOCK
 	/* SSI_XXX: not held when ptrace? */
-	if (!islocked && !VPROC_LOCK_EXCL_HELD(vi)) {
+	if (!islocked) { //&& !VPROC_LOCK_EXCL_HELD(vi)) {
 #else
 	if (rforkpt)
 		goto skip_remove;
 
-	/* SSI_XXX: not held when ptrace? */
-	pp_held = VPROC_LOCK_EXCL_HELD(vi);
-	/* Remote should re-check even when passed islocked TRUE */
+	/* We could be remote so check even when client says islocked */
+	pp_held = islocked && VPROC_LOCK_EXCL_HELD(vi);
 	if (!pp_held) {
 #endif
 		if (!(TRY_VPROC_LOCK_EXCL(vi, "pvpop_reclaim_child"))) {
@@ -1224,17 +1224,33 @@
 	/*
 	 * Remove process from parent.
 	 */
+#ifdef VPROC_RW_LOCK
+	error = PVPOP_RMV_CHILD_FROM_PARENT(vi, v, TRUE);
+	if (error) {
+		if (!pp_held)
+			VPROC_UNLOCK_EXCL(vi, "pvpop_reclaim_child");
+#ifdef DEBUG
+		printk("pvpop_child_reclaim: failed pvpop_rmv_child_from_parent");
+#endif
+		goto out;
+	}
+
+	if (pvp->pvp_pproc->ptrace && pvp->pvp_oppid != ppid) {
+		error = PVPOP_ADD_TO_ORIGINALCHILD_LIST(vi, v);
+		SSI_ASSERT(!error);
+		PVP(v)->pvp_oppid = vi->vp_pid;
+	}
+
+	if (!pp_held)
+		VPROC_UNLOCK_EXCL(vi, "pvpop_reclaim_child");
+
+	VPROC_RELE(vi, "pvpop_reclaim_child(parent on child node");
+#else
 	 if (!rforkpt)
 		error = PVPOP_RMV_CHILD_FROM_PARENT(vi, v, TRUE);
 
-#ifndef VPROC_RELEASE__REFCNT_RACE_FIX
 	if (!islocked)
 		VPROC_UNLOCK_EXCL(vi, "pvpop_reclaim_child");
-#else
-	if (!pp_held)
-		VPROC_UNLOCK_EXCL(vi, "pvpop_reclaim_child");
-skip_remove:
-#endif
 
 	if (error) {
 #ifdef DEBUG
@@ -1251,7 +1267,11 @@
 
 	if (!rforkpt)
 		VPROC_RELE(vi, "pvpop_reclaim_child(parent on child node");
+#endif /* !VPROC_RW_LOCK */
 
+#ifdef VPROC_RW_LOCK
+skip_remove:
+#endif
 	/*
 	 * Reassign the child from INIT to the new parent.
 	 */
@@ -1294,7 +1314,7 @@
 	}
 
 	if (PVP(v)->pvp_oppid == ppid) {
-		PVPOP_RMV_FROM_ORIGINALCHILD_LIST(vp, v);
+		(void) PVPOP_RMV_FROM_ORIGINALCHILD_LIST(vp, v);
 		PVP(v)->pvp_oppid = 0;
 	}
 #ifdef CONFIG_VPROC_ND
@@ -3086,7 +3106,11 @@
 			 * is implementation-defined: we do (if you don't want
 			 * it, just use SIG_IGN instead).
 			 */
+#ifdef VPROC_SIGNAL_LOCK
+			*sigp = PVP(p)->pvp_pproc->exit_signal = -1;
+#else
 			*sigp = -1;
+#endif
 			if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN)
 				sig = 0;
 		}
@@ -3100,11 +3124,7 @@
 					      pinfo,
 					      (pinfo ? 0 : VSIG_INTERNAL),
 					      NULL);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
 		if (*sigp == -1)
-#else
-		else if (*sigp == -1)
-#endif
 			dpvproc_nocldwait_async_queue(p, v);
 		VPROC_WAIT_EVENT_BROADCAST(p);
 		break;
@@ -3134,25 +3154,16 @@
 		VPROC_UNLOCK_FLAG(v, "pvpop_report_state");
 #ifdef VPROC_CONTINUE
 #ifdef VPROC_CONTINUE_SIGCHLD
-		/* Optional SIGCHLD for SIGCONT	*/
-		/* Avoid livelock with pid 0 */
 		if (p->vp_pid != v->vp_pid) {
-#ifndef VPROC_NOTIFY_PARENT_CLDSTOP__SA_HANDLER_SIGINFO
-#if 0
-			procinfo_t _pinfo;
-
-			/* FIXME: when child is remote */
-			pproc_pinfo(PVP(v)->pvp_pproc, &_pinfo);
-			_pinfo.pi_code = CLD_CONTINUED;
-			_pinfo.pi_status = SIGCONT;
-
-			error = PVPOP_SIGPROC(p, SIGCHLD, 0, &_pinfo,
+#ifdef VPROC_NOTIFY_PARENT_CLDSTOP__SA_HANDLER_SIGINFO
+			WARN_ON(!pinfo);
+			pinfo->pi_code = CLD_CONTINUED;
+			pinfo->pi_status = SIGCONT;
+			/* Optional SIGCHLD for SIGCONT */
+			error = PVPOP_SIGPROC(p, SIGCHLD, 0, pinfo,
 					      VSIG_CHILD_STOP, NULL);
-#endif
 #else
-			error = PVPOP_SIGPROC(p, sig, 0, pinfo,
-					(pinfo ? 0 : VSIG_INTERNAL) |
-							VSIG_CHILD_STOP, NULL);
+#warning optional SIGCHLD for SIGCONT not implemented
 #endif
 		}
 #endif /* VPROC_CONTINUE_SIGCHLD */
@@ -3253,36 +3264,26 @@
 	 * Perform operation locally.
 	 */
 skip_remote:
-	if (!(PVP(v)->pvp_flag&grpflags) && grpflags != 0) {
+	if (!(pvp->pvp_flag & grpflags) && grpflags != 0) {
 		VPROC_RELEASE_MOVEMENT(v, "pvpop_setctty");
 		return(-ESRCH);
 	}
 
-	if (pgid > 0  && (PVP(v)->pvp_flag & PV_SESSIONLEADER) &&
+	if (pgid > 0  && (pvp->pvp_flag & PV_SESSIONLEADER) &&
 						(flags & VCTTY_CLEARCTTY)) {
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-#ifdef VPROC_RW_LOCK
-		VPROC_LOCK_SHARED(v, "pvpop_setctty");
-#else
-		VPROC_LOCK_EXCL(v, "pvpop_setctty");
-#endif
 		PVPOP_SIGPROC(v, SIGHUP, SIGCONT, 0, VSIG_INTERNAL, NULL);
+#ifdef VPROC_HOLD_ZERO_GET_TASK
 		if (PV_IS_ALIVE(pvp)) {
-			/* read_lock(&tasklist_lock); */
-			PVP(v)->pvp_pproc->signal->tty_old_pgrp = pgid;
-			/* read_unlock(&tasklist_lock); */
+			lock_kernel(); /* SSI_XXX: Linux tty under BKL */
+			read_lock(&tasklist_lock);
+			pvp->pvp_pproc->signal->tty_old_pgrp = pgid;
+			read_unlock(&tasklist_lock);
+			unlock_kernel();
 		}
-#ifdef VPROC_RW_LOCK
-		VPROC_UNLOCK_SHARED(v, "pvpop_setctty");
-#else
-		VPROC_UNLOCK_EXCL(v, "pvpop_setctty");
-#endif
 #else
-		PVPOP_SIGPROC(v, SIGHUP, SIGCONT, 0, VSIG_INTERNAL, NULL);
 		if (PVP(v)->pvp_pproc != NULL)
 			PVP(v)->pvp_pproc->signal->tty_old_pgrp = pgid;
 #endif
-
 	}
 
 	/*
@@ -3359,26 +3360,10 @@
 	if (flags & VCTTY_CLEARFGPGRP) {
 		pvp->pvp_flag &= ~PV_FGPGRP;
 	}
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-	VPROC_UNLOCK_FLAG(v, "pvpop_setctty");
-#ifdef VPROC_RW_LOCK
-	VPROC_LOCK_SHARED(v, "pvpop_setctty");
-#else
-	VPROC_LOCK_EXCL(v, "pvpop_setctty");
-#endif
-	if (PV_IS_ALIVE(pvp))
-		pproc_setctty(pvp->pvp_pproc,cttydev,cttynode,flags);
-#ifdef VPROC_RW_LOCK
-	VPROC_UNLOCK_SHARED(v, "pvpop_setctty");
-#else
-	VPROC_UNLOCK_EXCL(v, "pvpop_setctty");
-#endif
-#else
 	if (pvp->pvp_pproc != NULL) {
 		pproc_setctty(pvp->pvp_pproc,cttydev,cttynode,flags);
 	}
 	VPROC_UNLOCK_FLAG(v, "pvpop_setctty");
-#endif
 
 	if (do_me_as_pgrp_mem)
 		VPROC_UNLOCK_PGRP_LIST_SHARED(v, "pvpop_setctty");
@@ -3869,12 +3854,17 @@
 	 */
 
 	if (!held) {
+#ifdef VPROC_RMV_FROM_ORIGINALCHILD_LIST_CANT_FIND_CHILD_FIX
+		WARN_ON(VPROC_LOCK_EXCL_HELD(vc));
+		VPROC_LOCK_EXCL(vp, "pvpop_add_originalchild(parent)");
+#else
 		if (!(TRY_VPROC_LOCK_EXCL(vp, 
 					"pvpop_add_originalchild(parent)"))) {
 			VPROC_RELEASE_MOVEMENT(vp, 
 					"pvpop_add_originalchild_list");
 			return -EAGAIN;
 		}
+#endif
 	}
 	VPROC_HOLD(vc, "pvpop_add_to_originalchild_list");
 	VPROC_LOCK_ND_LIST_EXCL(vp, "pvpop_add_to_originalchild_list");
@@ -3996,12 +3986,17 @@
 	for(w = PVP(v)->pvp_head_oclist; w; w = vc) {
 		VPROC_HOLD(w, "pvpop_reassign_original_parent");
 		vc = PVP(w)->pvp_oclist;
-		PVPOP_RMV_FROM_ORIGINALCHILD_LIST(v, w);
+		(void) PVPOP_RMV_FROM_ORIGINALCHILD_LIST(v, w);
+#ifdef VPROC_RMV_FROM_ORIGINALCHILD_LIST_CANT_FIND_CHILD_FIX
+		usevp = (newvp == w) ? initvp : newvp;
+		(void) PVPOP_ADD_TO_ORIGINALCHILD_LIST(usevp, w);
+#else
 		usevp = newvp;
 		if (newvp == w)
 			usevp = initvp;
 		if (PVPOP_ADD_TO_ORIGINALCHILD_LIST(usevp, w) == -EAGAIN)
 			PVPOP_ADD_TO_ORIGINALCHILD_LIST(initvp, w);
+#endif
 		PVPOP_REASSIGN_CHILD(w, PV_ORIGP_EXIT);
 		VPROC_RELE(w, "pvpop_reassign_original_parent");
 	}
@@ -4125,7 +4120,6 @@
 	struct rpvpop_args rargs;
 	int ret, error;
 	int len;
-	struct task_struct *task;
 
 	/*
 	 * Make sure this operation is not being performed during process
@@ -4172,14 +4166,12 @@
 #ifdef VPROC_HOLD_ZERO_GET_TASK
 	if (!PV_IS_ALIVE(pvp))
 		goto out;
-	task = pvp->pvp_pproc;
 #else
-	task = pvp->pvp_pproc;
-	if (!task)
+	if (!pvp->pvp_pproc)
 		goto out;
 #endif
 
-	len = do_proc_info(task, type, (char *)*buffer);
+	len = do_proc_info(pvp->pvp_pproc, type, (char *)*buffer);
 	if (len > 0)
 		*buflen = len;
 
@@ -4336,13 +4328,14 @@
 	 */
 	task = pvp->pvp_pproc;
 #ifdef VPROC_HOLD_ZERO_GET_TASK
-	/* SSI_XXX: no vproc lock */
 	WARN_ON(!task);
+#ifdef SSI_SKIP
 	if (!PV_IS_ALIVE(pvp)) {
 		error = -ESRCH;
 		goto out;
 	}
 #endif
+#endif
 	if (mem)
 		error = do_ssi_mem(task, buffer, count, ppos, type);
 	else
@@ -4566,7 +4559,6 @@
 	struct rpvpop_args rargs;
 	int ret, error;
 	ssi_procstate_t pstate;
-	struct task_struct *task = NULL;
 	ics_userbuf_t ubuf;
 
 	/*
@@ -4600,25 +4592,17 @@
 	/*
 	 * Perform operation locally.
 	 */
-#ifdef VPROC_RW_LOCK
-	VPROC_LOCK_SHARED(v, "pvpop_procfs_write");
-#else
-	VPROC_LOCK_EXCL(v, "pvpop_procfs_write");
-#endif
 	error = -ESRCH;
 #ifdef VPROC_HOLD_ZERO_GET_TASK
-	if (!PV_IS_ALIVE(pvp)) {
+	if (pvp->pvp_flag & PV_EXITING)
+		goto out;
+#else
 #ifdef VPROC_RW_LOCK
-		VPROC_UNLOCK_SHARED(v, "pvpop_procfs_write");
+	VPROC_LOCK_SHARED(v, "pvpop_procfs_write");
 #else
-		VPROC_UNLOCK_EXCL(v, "pvpop_procfs_write");
+	VPROC_LOCK_EXCL(v, "pvpop_procfs_write");
 #endif
-		goto out;
-	}
-	task = pvp->pvp_pproc;
-#else
-	task = pvp->pvp_pproc;
-	if (!task) {
+	if (!pvp->pvp_pproc) {
 #ifdef VPROC_RW_LOCK
 		VPROC_UNLOCK_SHARED(v, "pvpop_procfs_write");
 #else
@@ -4626,14 +4610,15 @@
 #endif
 		goto out;
 	}
-#endif
+	/* SSI_XXX: wtf? */
 #ifdef VPROC_RW_LOCK
 	VPROC_UNLOCK_SHARED(v, "pvpop_procfs_write");
 #else
 	VPROC_UNLOCK_EXCL(v, "pvpop_procfs_write");
 #endif
+#endif /* !VPROC_HOLD_ZERO_GET_TASK */
 
-	error = do_ssi_write(task, buffer, count, ppos, type);
+	error = do_ssi_write(pvp->pvp_pproc, buffer, count, ppos, type);
 
 out:
 	VPROC_RELEASE_MOVEMENT(v, "pvpop_procfs_write");
@@ -4648,9 +4633,12 @@
 {
 	struct pvproc *pvp = PVP(v);
 	struct rpvpop_args rargs;
-	int ret, error, locked = 1;
-	ssi_procstate_t pstate;
+	int ret, error;
+#ifndef VPROC_HOLD_ZERO_GET_TASK
+	int locked = 1;
 	struct task_struct *task = NULL;
+#endif
+	ssi_procstate_t pstate;
 
 	/*
 	 * Make sure this operation is not being performed during process
@@ -4689,22 +4677,22 @@
 	/*
 	 * Perform operation locally.
 	 */
-#ifdef VPROC_RW_LOCK
-	VPROC_LOCK_SHARED(v, "pvpop_procfs_tid_list");
-#else
-	VPROC_LOCK_EXCL(v, "pvpop_procfs_tid_list");
-#endif
 	error = -ESRCH;
 #ifdef VPROC_HOLD_ZERO_GET_TASK
 	if (!PV_IS_ALIVE(pvp))
 		goto out;
-	task = pvp->pvp_pproc;
+
+	error = ssi_get_tid_list(pvp->pvp_pproc, index, *tids);
 #else
+#ifdef VPROC_RW_LOCK
+	VPROC_LOCK_SHARED(v, "pvpop_procfs_tid_list");
+#else
+	VPROC_LOCK_EXCL(v, "pvpop_procfs_tid_list");
+#endif
 	task = pvp->pvp_pproc;
 	if (!task)
 		goto out;
 	get_task_struct(task);
-#endif /* !VPROC_HOLD_ZERO_GET_TASK */
 #ifdef VPROC_RW_LOCK
 	VPROC_UNLOCK_SHARED(v, "pvpop_procfs_tid_list");
 #else
@@ -4713,12 +4701,12 @@
 	locked = 0;
 
 	error = ssi_get_tid_list(task, index, *tids);
+#endif /* !VPROC_HOLD_ZERO_GET_TASK */
 	if (error >= 0)
 		*len = error;
 
 #ifndef VPROC_HOLD_ZERO_GET_TASK
 	put_task_struct(task);
-#endif
 out:
 	if (locked)
 #ifdef VPROC_RW_LOCK
@@ -4726,6 +4714,9 @@
 #else
 		VPROC_UNLOCK_EXCL(v, "pvpop_procfs_tid_list");
 #endif
+#else
+out:
+#endif /* VPROC_HOLD_ZERO_GET_TASK */
 	VPROC_RELEASE_MOVEMENT(v, "pvpop_procfs_tid_list");
 	return(error);
 }

Index: nd_carelist.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/nd_carelist.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- nd_carelist.c	10 Oct 2008 08:10:32 -0000	1.6
+++ nd_carelist.c	3 Feb 2009 06:18:13 -0000	1.7
@@ -102,6 +102,9 @@
 	if (vchp->vch_caredatap)
 		vchp->vch_caredatap->vcd_prev = vcdp;
 
+#ifdef VPROC_ND_CARELIST_RACE_FIX
+	mb();
+#endif
 	vchp->vch_caredatap = vcdp;
 	vchp->vch_carecount++;
 }
@@ -120,6 +123,9 @@
 
 	vchp->vch_carecount--;
 
+#ifdef VPROC_ND_CARELIST_RACE_FIX
+	mb();
+#endif
 	vcdp->vcd_prev = NULL;
 	vcdp->vcd_next = NULL;
 }
@@ -250,6 +256,9 @@
 	if (vchp->vch_next)
 		vchp->vch_next->vch_prev = vchp->vch_prev;
 
+#ifdef VPROC_ND_CARELIST_RACE_FIX
+	mb();
+#endif
 	vchp->vch_prev = NULL;
 	vchp->vch_next = NULL;
 }
@@ -281,11 +290,18 @@
 	vproc_carehead_t *vchcurr, *vchtemp;
 
 	vchcurr = vchlistp;
+#ifdef VPROC_ND_CARELIST_RACE_FIX
+	while (vchcurr != NULL) {
+		vchtemp = vchcurr->vch_next;
+		vproc_carelist_release(vchcurr);
+		vchcurr = vchtemp;
+#else
 	while (vchcurr != NULL) {
 		vchtemp = vchcurr;
 		vchcurr = vchcurr->vch_next;
 
 		vproc_carelist_release(vchtemp);
+#endif
 	}
 }
 

Index: vp_debug.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/vp_debug.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- vp_debug.c	10 Oct 2008 08:10:32 -0000	1.13
+++ vp_debug.c	3 Feb 2009 06:18:13 -0000	1.14
@@ -217,7 +217,9 @@
 	printk("&rlim=0x%p\n", p->signal->rlim);
 	printk("used_math=%d\n", (int)tsk_used_math(p));
 	printk("comm=%s\n", p->comm);
+#ifdef SSI_NOTUSED
 	printk("locks=%u\n", p->locks);
+#endif
 	printk("link_count=%d\n", p->link_count);
 	printk("total_link_count=%d\n", p->total_link_count);
 	printk("sysvsem.undo_list=%p\n", p->sysvsem.undo_list);

Index: as_xscribe.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/as_xscribe.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- as_xscribe.c	10 Oct 2008 08:10:32 -0000	1.15
+++ as_xscribe.c	3 Feb 2009 06:18:13 -0000	1.16
@@ -578,7 +578,7 @@
 	struct mm_struct *mm;
 	struct vm_area_struct *vma;
 	struct task_struct *p;
-	struct vproc *v;
+	struct vproc *v = NULL;
 	struct pvproc *pvp;
 	as_vma_info *avip;
 	int reopen_op;
@@ -597,15 +597,8 @@
 	SSI_ASSERT(v);
 	pvp = PVP(v);
 	if (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);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(v, "ras_pull_vma_info(vprocptr v)");
-#endif
 	} else
 		p = NULL;
 	if (!p) {
@@ -657,6 +650,10 @@
  out_unlock:
 	up_read(&mm->mmap_sem);
  out:
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+	if (v)
+		VPROC_RELE(v, "ras_pull_vma_info");
+#endif
 	if (*error < 0 || !avap->ava_data.ava_data_len) {
 		for (i = avap->ava_data.ava_data_len; i-- > 0; ) {
 			avip = avap->ava_data.ava_data_val + i;
@@ -760,7 +757,7 @@
 	struct mm_struct *mm;
 	struct vm_area_struct *vma;
 	struct task_struct *p;
-	struct vproc *v;
+	struct vproc *v = NULL;
 	struct pvproc *pvp;
 	as_pg_info *apip;
 	int isfile;
@@ -785,15 +782,8 @@
 	SSI_ASSERT(v);
 	pvp = PVP(v);
 	if (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);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(v, "ras_pull_pg_info(vprocptr v)");
-#endif
 	} else
 		p = NULL;
 	if (!p) {
@@ -846,6 +836,10 @@
 	spin_unlock(&mm->page_table_lock);
 	up_read(&mm->mmap_sem);
  out:
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+	if (v)
+		VPROC_RELE(v, "ras_pull_pg_info");
+#endif
 	if (*error >= 0) {
 		for (i = *apipp_len; i > 0; i--) {
 			lock_page(apip->api_page);

Index: rvp_pvpops_server.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/rvp_pvpops_server.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- rvp_pvpops_server.c	10 Oct 2008 08:10:32 -0000	1.13
+++ rvp_pvpops_server.c	3 Feb 2009 06:18:13 -0000	1.14
@@ -99,9 +99,9 @@
 	_vp = LOCATE_VPROC_PID(_pid, id_string);
 #endif
 
-#define	RPVPOP_VPROC_RELE(vp)						\
-	if (vp)								\
-		VPROC_RELE(vp, id_string)
+#define	RPVPOP_VPROC_RELE(_vp)						\
+	if (_vp)							\
+		VPROC_RELE(_vp, id_string)
 
 
 int


------------------------------------------------------------------------------
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.