[SSI] openssi/kernel/cluster/ssi/vproc dvp_async.c, 1.12, 1.13 dvp_pvpops.c, 1.42, 1.43 dvp_vpops.c, 1.42, 1.43 nd_carelist.c, 1.9, 1.10 nd_cleanup.c, 1.10, 1.11 vp_subr.c, 1.22, 1.23

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 sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv23888/cluster/ssi/vproc

Modified Files:
      Tag: OPENSSI-FC
	dvp_async.c dvp_pvpops.c dvp_vpops.c nd_carelist.c 
	nd_cleanup.c vp_subr.c 
Log Message:
VPROC:
- Fix select_bad_process() NULL p_vproc pointer dereference.
- Fix de_thread() related issues:
  - Fix de_thread() calling VPOP_RECLAIM_CHILD() while holding spin_lock(task->p
roc_lock). Code path might sleep.
  - Fix NULL p_vproc pointer dereference when thread group leader is exiting, ha
s PF_FORKNOEXEC flag, and has lost race with de_thread(). Affects exit_notify(),
 forget_original_parent(), and will_become_orphaned_pgrp(). When p_vproc is NULL
 the exiting process reaps itself.
  - Fix dpvproc_nocldwait_async_handler() NULL pointer dereference due to failed
 lookup for vproc of new parent when lost race with de_thread(). (#ifdef RELEASE
_TASK_LEADER_GONE__VPROC_FIX)
  - New PVPOP_SWITCH_PID() to switch VProc PID of process doing de_thread().
  - New PV_DETHREAD_REAP flag is set during de_thread() to indicate to child rea
per to reap thread group leader without delay.
  - Fix oops in do_notify_resume() path due to NULL pointer dereference. p_vproc
 is NULL after bad fork.

VPROC (#ifdef VPROC_RELEASE__REFCNT_RACE_FIX):
- Fix extra VPROC_RELE() on PVPOP_RMV_PGRP_LIST() -ESRCH error.
- Fix PVPOP_REAP() extra dpvproc_remove_pgrp_leader_member_care() on PVPOP_RMV_P
GRP_LIST() -EBUSY error; was typo in if-test.
- PVPOP_REAP() no longer does async PVPOP_RMV_PGRP_LIST(); now sync. Don't see h
ow reaping parent can hold PGRP LOCK in PVPOP_REAP() path.
- Fix exit_vproc() did not decrement vproc reference for process group leader on
 member node. This is in do_fork() error path.

VPROC (#ifdef VPROC_CONTINUE):
- Fix dpvproc_nocldwait_async_handler() deadlock on PVPOP_REAP() -EBUSY due to d
elay_group_leader(). PV_REAPER_RETRY flag is set and group leader is re-inserted
 into the queue so that the remaining threads in thread group can be reaped by t
his handler to remove the delay_group_leader() condition.
- Regression:
  - Fix pproc_reap() should succeed, but returns -EBUSY when process is a thread
 group leader in non-empty thread group and is already in EXIT_DEAD state.


Index: vp_subr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/vp_subr.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- vp_subr.c	17 Nov 2009 06:09:02 -0000	1.22
+++ vp_subr.c	17 Dec 2009 05:46:50 -0000	1.23
@@ -361,7 +361,7 @@
 #else
 #ifdef VPROC_LIST_SPINLOCK
 	if (!atomic_dec_and_lock(&v->vp_ref_cnt, &vproc_list_lock)) {
-		/* WARN_ON(atomic_read(&v->vp_ref_cnt) < 0); */
+		BUG_ON(atomic_read(&v->vp_ref_cnt) < 0);
 		return(ESUCCESS);
 	}
 #else

Index: dvp_async.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/dvp_async.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- dvp_async.c	27 Oct 2009 03:18:29 -0000	1.12
+++ dvp_async.c	17 Dec 2009 05:46:50 -0000	1.13
@@ -300,6 +300,16 @@
 	if (PVP(vp)->pvp_pproc)
 		tgid = PVP(vp)->pvp_pproc->tgid;
 
+#ifdef VPROC_CONTINUE
+	VPROC_LOCK_FLAG(vc, "dpvproc_nocldwait_async_handler");
+	if (PVP(vc)->pvp_flag & PV_REAPER_RETRY) {
+		VPROC_UNLOCK_FLAG(vc, "dpvproc_nocldwait_async_handler");
+		/* Already removed from child-sibling-list */
+		goto release_child;
+	}
+	VPROC_UNLOCK_FLAG(vc, "dpvproc_nocldwait_async_handler");
+#endif
+
 	error = PVPOP_RMV_CHILD_FROM_PARENT(vp, vc, FALSE);
 	if (error != 0) {
 		/*
@@ -330,15 +340,38 @@
 			goto out;
 		}
 #ifdef RELEASE_TASK_LEADER_GONE__VPROC_FIX
-		VPROC_RELEASE_MOVEMENT(vp, "dpvproc_nocldwait_async_handler");
+		{
+			struct vproc *tmp;
+			tmp = LOCATE_VPROC_PID(PVP(vc)->pvp_ppid,
+					      "temp nocldwait async (new parent)");
+#ifndef VPROC_RCU_LIST
+			BUG_ON(tmp == NULL);
 #endif
+			if (!tmp) {
+				/* de_thread() got to old thread group leader.
+				 * parent exited, still need to reap child.
+				 */
+				goto release_child;
+			}
+			VPROC_RELEASE_MOVEMENT(vp, "dpvproc_nocldwait_async_handler");
+			VPROC_RELE(vp, "temp nocldwait async (parent)");
+			VPROC_HOLD_MOVEMENT(tmp, "temp nocldwait async (new parent)");
+			vp = tmp;
+		}
+#if 0
+		VPROC_RELEASE_MOVEMENT(vp, "dpvproc_nocldwait_async_handler");
 		VPROC_RELE(vp, "temp nocldwait async (parent)");
 		vp = LOCATE_VPROC_PID(PVP(vc)->pvp_ppid,
 				      "temp nocldwait async (new parent)");
 		SSI_ASSERT(vp != NULL);
-#ifdef RELEASE_TASK_LEADER_GONE__VPROC_FIX
 		VPROC_HOLD_MOVEMENT(vp, "temp nocldwait async (new parent)");
 #endif
+#else /* RELEASE_TASK_LEADER_GONE__VPROC_FIX */
+		VPROC_RELE(vp, "temp nocldwait async (parent)");
+		vp = LOCATE_VPROC_PID(PVP(vc)->pvp_ppid,
+				      "temp nocldwait async (new parent)");
+		SSI_ASSERT(vp != NULL);
+#endif
 		error = PVPOP_RMV_CHILD_FROM_PARENT(vp, vc, FALSE);
 		if (error != 0) {
 #ifdef VPROC_DEBUG
@@ -388,8 +421,21 @@
 #ifdef VPROC_CONTINUE
 			if (error >= 0)
 				break;
+			if (error == -EBUSY) {
+				VPROC_LOCK_FLAG(vc, "dpvproc_nocldwait_async_handler");
+				if (!(PVP(vc)->pvp_flag & PV_REAPER_RETRY))
+					PVP(vc)->pvp_flag |= PV_REAPER_RETRY;
+				VPROC_UNLOCK_FLAG(vc, "dpvproc_nocldwait_async_handler");
+				idelay(HZ>>2);
+				dpvproc_nocldwait_async_queue(vp, vc);
+				goto out;
+			}
 			VPROC_REMOTE_RETRY_DELAY();
 		}
+
+		VPROC_LOCK_FLAG(vc, "dpvproc_nocldwait_async_handler");
+		PVP(vc)->pvp_flag |= PV_WAITED;
+		VPROC_UNLOCK_FLAG(vc, "dpvproc_nocldwait_async_handler");
 #else
 			if (error == -EAGAIN)
 				VPROC_REMOTE_RETRY_DELAY();
@@ -411,9 +457,11 @@
 		if (!IS_SYSPROC(PVP(vc)) && PVP(vp)->pvp_pproc)
 #endif
 			(void) pproc_add_pusage(PVP(vp)->pvp_pproc, &pu_loc);
+#ifdef CONFIG_VPROC_ND
 		if (PIDNODE(vp->vp_pid))
 			dpvproc_remove_parent_child_care(vp->vp_pid,
 							vc->vp_pid, TRUE);
+#endif
 #ifdef VPROC_RW_LOCK
 		VPROC_UNLOCK_SHARED(vp, "dpvproc_nocldwait_async_handler");
 #else

Index: nd_cleanup.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/nd_cleanup.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- nd_cleanup.c	27 Oct 2009 03:18:30 -0000	1.10
+++ nd_cleanup.c	17 Dec 2009 05:46:50 -0000	1.11
@@ -437,10 +437,10 @@
 	error = PVPOP_RMV_PGRP_LIST(plvp, pmvp, 0, 0);
 	if (error) {
 		SSI_ASSERT(error == -ESRCH);
-#ifdef DEBUG
+/* #ifdef DEBUG */
 		printk("vproc_pgrp_leader_lost_member: pgrp %d is gone!\n",
 			plvp->vp_pid); /* NSC_XXX */
-#endif
+/* #endif */
 		/*
 		 * NSC_XXX: Need to PVPSOP_REMOTE_VPROC_RELE() the
 		 *	      holds at the origin from which this

Index: dvp_vpops.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/dvp_vpops.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- dvp_vpops.c	18 Nov 2009 06:16:53 -0000	1.42
+++ dvp_vpops.c	17 Dec 2009 05:46:50 -0000	1.43
@@ -531,13 +531,20 @@
 		 * cleaned up.
 		 */
 		if (PVPOP_RMV_CHILD_FROM_PARENT(vp, vc, 0))
-			printk("failed to remove exiting child from parent\n");
+			printk(KERN_WARNING "%s: failed to remove"
+				" exiting child from parent\n", __FUNCTION__);
 
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+		vg = VPROCPTR_NOHOLD(PVP(vc)->pvp_pgid);
+#else
 		vg = VPROCPTR(PVP(vc)->pvp_pgid);
+#endif
 		if (PVPOP_RMV_PGRP_LIST(vg, vc, 0, 0))
-			printk("failed to remove exiting child from pgrp\n");
+			printk(KERN_WARNING "%s: failed to remove exiting child"
+					" from pgrp\n", __FUNCTION__);
 #ifdef VPROC_RELEASE__REFCNT_RACE_FIX
-		VPROC_RELE(vg, "exit_vproc(vprocptr vg)");
+		else
+			VPROC_RELE(vg, "exit_vproc(pgrp leader on member node)");
 #endif
 
 #ifndef VPROC_HOLD_ZERO_GET_TASK
@@ -550,6 +557,10 @@
 			dpvproc_remove_parent_child_care(vp->vp_pid,
 							 vc->vp_pid, TRUE);
 
+		VPROC_LOCK_FLAG(vc, "exit_vproc");
+		PVP(vc)->pvp_flag |= PV_WAITED;
+		VPROC_UNLOCK_FLAG(vc, "exit_vproc");
+
 		/* Release the holds for active and origin */
 		VPROC_RELE(vc, "exit_vproc(origin)");
 		VPROC_RELE(vc, "exit_vproc(active)");
@@ -1007,6 +1018,7 @@
 	for (vo = NULL, vc = pvp->pvp_head_childl;
 				vc != NULL;
 				vo = vc, vc = PVP(vc)->pvp_childl) {
+		pvc = PVP(vc);
 #endif /* !VPROC_PVP_CHILD_LL */
 #ifdef VPROC_DEBUG
 		if (vpoptrace)
@@ -1022,18 +1034,30 @@
 #endif /* VPROC_DEBUG */
 			/* we're waiting for a specific child */
 #ifdef DE_THREAD__OOPS_FIX
-			if (vc->vp_pid != pid ) {
-				/* SSI_XXX: potentially remote */
-				/* Will not be remote since entire
-				 * thread group migrates.
-				 */
+			if (switch_exec_pids)
+				switch_exec_pids = 0;
+
+			/* pproc PID could have been switched due to
+			 * de_thread()
+			 */
 #ifdef TASK_HOLD_VPROC
-				if ((PVP(vc)->pvp_flag & PV_IS_LOCAL) &&
-				    PVP(vc)->pvp_pproc && PVP(vc)->pvp_pproc->pid == pid)
+			VPROC_LOCK_FLAG(vc, "vpop_wait");
+			if ((pvc->pvp_flag & PV_IS_LOCAL) &&
+			    pvc->pvp_pproc->pid == pid) {
+				VPROC_UNLOCK_FLAG(vc, "vpop_wait");
+				/* switch_exec_pids() switched pids */
+				if (vc->vp_pid != pid)
+					switch_exec_pids = 1;
+			} else {
+				VPROC_UNLOCK_FLAG(vc, "vpop_wait");
+				if (vc->vp_pid != pid)
+					continue;
+			}
 #else
-				if (PVP(vc)->pvp_pproc &&
-				    PVP(vc)->pvp_pproc->pid == pid)
-#endif
+			if (vc->vp_pid != pid) {
+				/* SSI_XXX: potentially remote? */
+				if (pvc->pvp_pproc &&
+				    pvc->pvp_pproc->pid == pid)
 					/* switch_exec_pids() switched pids
 					 * with previous thread group leader.
 					 */
@@ -1041,14 +1065,12 @@
 				else
 					continue;
 			}
+#endif /* !TASK_HOLD_VPROC */
 #else
 			if (vc->vp_pid != pid )
 				continue;
-#endif
+#endif /* !DE_THREAD__OOPS_FIX */
 		}
-#ifndef VPROC_PVP_CHILD_LL
-		pvc = PVP(vc);
-#endif
 
 		VPROC_LOCK_FLAG(vc, "vpop_wait");
 #ifdef VPROC_DEBUG

Index: dvp_pvpops.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/dvp_pvpops.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- dvp_pvpops.c	18 Nov 2009 06:16:53 -0000	1.42
+++ dvp_pvpops.c	17 Dec 2009 05:46:50 -0000	1.43
@@ -320,14 +320,21 @@
 #else
 	VPROC_LOCK_EXCL(v, "pvpop_reap");
 #endif /* !VPROC_RW_LOCK */
-	if ((options & VPROC_WZOMBIE) && !(pvp->pvp_flag & PV_EXITING)) {
 #ifdef VPROC_CONTINUE
-		error = -EBUSY;
+	if (options & VPROC_WZOMBIE) {
+		if (!(pvp->pvp_flag & PV_EXITING)) {
+			error = -EBUSY;
+			goto out;
+		}
+		if (pvp->pvp_flag & PV_DETHREAD_REAP)
+			options |= VPROC_WDETHREAD;
+	}
 #else
+	if ((options & VPROC_WZOMBIE) && !(pvp->pvp_flag & PV_EXITING)) {
 		error = -EAGAIN;
-#endif
 		goto out;
 	}
+#endif /* !VPROC_CONTINUE */
 
 #ifdef VPROC_VPROC_WNOTHREAD__NOTUSED
 	/*
@@ -446,14 +453,21 @@
 			printk("pvpop_reap: resigning from pgrp %d\n",
 					pvp->pvp_pgid);
 #endif */
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+			ret = PVPOP_RMV_PGRP_LIST(g, v, 0, 0);
+#else
 			ret = PVPOP_RMV_PGRP_LIST(g, v, 0, 1);
+#endif
 #ifdef CONFIG_VPROC_ND
-			if (ret != EBUSY)
+			if (ret != -EBUSY)
 				dpvproc_remove_pgrp_leader_member_care(
 							       g->vp_pid,
 							       v->vp_pid,
 							       FALSE);
 #endif
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+			if (ret != -ESRCH)
+#endif
 			VPROC_RELE(g, "pvpop_reap(pgrp ldr on member node)");
 		}
 
@@ -1553,16 +1567,24 @@
 		if (pvp->pvp_pgid != 0) {
 #ifdef VPROC_RELEASE__REFCNT_RACE_FIX
 			struct vproc *og = VPROCPTR_NOHOLD(pvp->pvp_pgid);
+			ret = PVPOP_RMV_PGRP_LIST(og, v, pvp->pvp_ppid, 0);
 #else
 			register struct vproc *og = VPROCPTR(pvp->pvp_pgid);
-#endif
 			(void) PVPOP_RMV_PGRP_LIST(og, v, pvp->pvp_ppid, 0);
+#endif
 #ifdef CONFIG_VPROC_ND
 			dpvproc_remove_pgrp_leader_member_care(og->vp_pid,
 							       v->vp_pid,
 							       FALSE);
 #endif
-			VPROC_RELE(og, "dvpop_setpgid(old pgrp ldr on mem node)");
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+			//if (ret != -ESRCH)
+			if (ret)
+				printk(KERN_WARNING "%s: resign from current group err %d\n",
+					__FUNCTION__, ret);
+			else
+#endif
+			VPROC_RELE(og, "pvpop_setpgid(old pgrp ldr on mem node)");
 		}
 
 		/*
@@ -1735,14 +1757,18 @@
 	if (pvp->pvp_pgid != 0) {
 #ifdef VPROC_RELEASE__REFCNT_RACE_FIX
 		struct vproc *g = VPROCPTR_NOHOLD(pvp->pvp_pgid);
+		ret = PVPOP_RMV_PGRP_LIST(g, v, pvp->pvp_ppid, 0);
 #else
 		register struct vproc *g = VPROCPTR(pvp->pvp_pgid);
-#endif
 		PVPOP_RMV_PGRP_LIST(g, v, pvp->pvp_ppid, 0);
+#endif
 #ifdef CONFIG_VPROC_ND
 		dpvproc_remove_pgrp_leader_member_care(g->vp_pid, v->vp_pid,
 						       FALSE);
 #endif
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+		if (ret != -ESRCH)
+#endif
 		VPROC_RELE(g, "pvpop_setsid(old pgrp leader on member node)");
 	}
 
@@ -4897,3 +4923,160 @@
 	VPROC_RELEASE_MOVEMENT(vp, "pvpop_ptrace");
 	return 0;
 }
+
+/*
+ * NAME:	pvpop_switch_pid
+ *
+ * FUNCTION:	Resign from current process group, re-hash vproc,
+ *		and become its own process group leader.
+ *		Based on pvpop_setpgid().
+ *
+ *		Caller must ensure progress group is empty except for self.
+ *		Linux: Called from de_thread() after switch_exec_pids().
+ */
+void
+pvpop_switch_pid(
+	struct vproc *v,	/* vproc of target process */
+	pid_t pid)		/* new PID to assign target process */
+{
+	struct pvproc *pvp = PVP(v);
+	int ret;
+
+	WARN_ON(v->vp_pid == pid);
+
+	/*
+	 * Perform operation locally.
+	 */
+
+	VPROC_LOCK_EXCL(v, "pvpop_setpgid(process)");
+
+	/*
+	 * Process will become the pgrp leader.
+	 */
+	BUG_ON(pvp->pvp_flag & PV_PGRPLEADER);
+	BUG_ON(v->vp_pid == pvp->pvp_pgid);
+
+	/*
+	 * This operation may orphan the old pgrp or unorphan the new
+	 * pgrp or it may either orphan or unorphan the pgrps of
+	 * children of this process.
+	 */
+	SSI_ASSERT(pvp->pvp_jobc == 0);
+	pvproc_orphan_pgrp_check(v, v->vp_pid, pvp->pvp_sid, 0);
+
+	/* Resign from current group */
+	if (pvp->pvp_pgid != 0) {
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+		struct vproc *og = VPROCPTR_NOHOLD(pvp->pvp_pgid);
+		ret = PVPOP_RMV_PGRP_LIST(og, v, pvp->pvp_ppid, 0);
+#else
+		register struct vproc *og = VPROCPTR(pvp->pvp_pgid);
+		(void) PVPOP_RMV_PGRP_LIST(og, v, pvp->pvp_ppid, 0);
+#endif
+#ifdef CONFIG_VPROC_ND
+		dpvproc_remove_pgrp_leader_member_care(og->vp_pid,
+						       v->vp_pid,
+						       FALSE);
+#endif
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+		//if (ret != -ESRCH)
+		if (ret)
+			printk(KERN_WARNING "%s: resign from current group err %d\n",
+				__FUNCTION__, ret);
+		else
+#endif
+		VPROC_RELE(og, "pvpop_setpgid(old pgrp ldr on mem node)");
+	}
+
+	/*
+	 * Re-hash vproc (vproc takes on new pid).
+	 */
+	VPROC_LIST_LOCK();
+	list_del_rcu(&v->vp_list);
+	list_add_rcu(&v->vp_list, &vproc_hash[VPROCPIDHASH(pid)]);
+	VPROC_LIST_UNLOCK();
+	set_mb(v->vp_pid, pid);
+
+	/*
+	 * Assign vproc the new process group id.
+	 */
+	pvp->pvp_pgid = v->vp_pid;
+
+	/*
+	 * Create a pgrp
+	 */
+	VPROC_LOCK_PGRP_LIST_EXCL(v, "pvpop_setpgid");
+
+	/*
+	 * Add process to its own pgrp list - effectively, this
+	 * is an inline version of PVPOP_ADD_PGRP_LIST(v,v)
+	 */
+	SSI_ASSERT(pvp->pvp_head_pgrpl == NULL);
+	WARN_ON(pvp->pvp_pgrpl != NULL);
+	pvp->pvp_head_pgrpl = v;
+	pvp->pvp_pgrp_ldr_seqno = 0;
+	pvp->pvp_pgrp_mem_seqno = 0;
+	VPROC_HOLD(v, "pvpop_setpgid(member on leader node)");
+	VPROC_HOLD(v, "pvpop_setpgid(leader on leader node)");
+	VPROC_HOLD(v, "pvpop_setpgid(leader on member node)");
+
+	/*
+	 * This is the inline equivalent to performing
+	 * a PVPOP_ADJUST_JOB_CONROL_COUNT().  This is
+	 * not done by the pvproc_orphan_pgrp_check()
+	 * called above because we're creating a new
+	 * pgrp.
+	 */
+	if (pvp->pvp_pp_sid == pvp->pvp_sid)
+		pvp->pvp_jobc++;
+
+	VPROC_LOCK_FLAG(v, "pvpop_setpgid");
+	pvp->pvp_flag |=  PV_PGRPLEADER;
+	VPROC_UNLOCK_FLAG(v, "pvpop_setpgid");
+
+	/*
+	 * Place a hold on the pgrp leader's origin node vproc.
+	 * Also mark the vproc as a pgrp origin.  The caredata
+	 * updates are piggybacked on the origin update.
+	 */
+	do {
+		ret = PVPSOP_UPDATE_ORIGIN(VPROC_ORIGIN_NODE(v),
+					   v->vp_pid,
+					   PV_PGRP_ORIGIN,
+					   PV_ADD);
+		if (ret == -EREMOTE)
+			VPROC_REMOTE_RETRY_DELAY();
+	} while(ret == -EREMOTE);
+
+#ifdef CONFIG_VPROC_ND
+	dpvproc_add_pgrp_member_leader_care(PVP(v)->pvp_sid,
+					    v->vp_pid,
+					    v->vp_pid);
+#endif
+
+	VPROC_UNLOCK_PGRP_LIST_EXCL(v, "pvpop_setpgid");
+
+	if (pvp->pvp_sid) {
+		struct vproc *vs;
+		/*
+		 * Add new pgrp to session list.  Note that
+		 * the LOCATE holds the session vproc on
+		 * the node of the new pgrp leader.
+		 */
+		vs = LOCATE_VPROC_PID(pvp->pvp_sid, "perm sid");
+		PVPOP_ADD_SESSION_LIST(vs, v);
+#ifdef CONFIG_VPROC_ND
+		dpvproc_add_session_leader_member_care(
+					vs->vp_pid, v->vp_pid);
+#endif
+	}
+
+	/* keep physical proc updated */
+	pproc_setattr(pvp->pvp_pproc,
+		      0,0,0,
+		      &pvp->pvp_pgid,
+		      0,
+		      0);
+
+	VPROC_UNLOCK_EXCL(v, "pvpop_setpgid(process)");
+}

Index: nd_carelist.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/nd_carelist.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- nd_carelist.c	27 Oct 2009 03:18:30 -0000	1.9
+++ nd_carelist.c	17 Dec 2009 05:46:50 -0000	1.10
@@ -126,6 +126,9 @@
 	vproc_caredata_t *src_vcdp)
 {
 	*dest_vcdp = *src_vcdp;
+#ifdef VPROC_ND_CARELIST_RACE_FIX
+	wmb();
+#endif
 	dest_vcdp->vcd_next = NULL;
 	dest_vcdp->vcd_prev = NULL;
 }
@@ -171,6 +174,9 @@
 	if (vchp->vch_caredatap)
 		vchp->vch_caredatap->vcd_prev = vcdp;
 
+#ifdef VPROC_ND_CARELIST_RACE_FIX
+	wmb();
+#endif
 	vchp->vch_caredatap = vcdp;
 	vchp->vch_carecount++;
 }
@@ -193,7 +199,7 @@
 	vchp->vch_carecount--;
 
 #ifdef VPROC_ND_CARELIST_RACE_FIX
-	rmb();
+	mb();
 #endif
 	vcdp->vcd_prev = NULL;
 	vcdp->vcd_next = NULL;
@@ -366,7 +372,7 @@
 		vchp->vch_next->vch_prev = vchp->vch_prev;
 
 #ifdef VPROC_ND_CARELIST_RACE_FIX
-	rmb();
+	mb();
 #endif
 	vchp->vch_prev = NULL;
 	vchp->vch_next = NULL;


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev
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.