[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