[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