[SSI] openssi/kernel/kernel exit.c, 1.20, 1.21 pid.c, 1.7, 1.8 ptrace.c, 1.8, 1.9 sched.c, 1.10, 1.11 sys.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/kernel
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv16224/kernel/kernel
Modified Files:
Tag: OPENSSI-FC
exit.c pid.c ptrace.c sched.c sys.c
Log Message:
Bug fixes and enhancements. See ChangeLog.
Index: sched.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/kernel/sched.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- sched.c 7 Aug 2007 03:06:15 -0000 1.10
+++ sched.c 27 Oct 2009 03:18:30 -0000 1.11
@@ -53,6 +53,11 @@
#include <linux/mosix.h>
#include <cluster/ssi/mosixll/defs.h>
#endif /* CONFIG_MOSIX_LL */
+#ifdef VPROC
+#ifdef TASK_HOLD_VPROC
+#include <linux/dpvproc.h>
+#endif
+#endif /* VPROC */
/*
* Convert user-nice values [ -20 ... 0 ... 19 ]
@@ -1334,21 +1339,30 @@
{
unsigned long flags;
runqueue_t *rq;
+#ifdef VPROC
+ task_t *parent = current;
+#ifdef TASK_HOLD_VPROC
+ if (!CMP_PARENT_TO_TASK(p, current)) {
+ parent = find_task_by_pid(GET_PPID(p));
+ if (!parent)
+ return;
+ }
+#else
+ /* SSI_XXX: will use current instead of parent for now */
+#endif
/*
* If the child was a (relative-) CPU hog then decrease
* the sleep_avg of the parent as well.
*/
-#ifdef VPROC
- /* SSI_XXX: will use current instead of parent for now */
- rq = task_rq_lock(current, &flags);
+ rq = task_rq_lock(parent, &flags);
if (p->first_time_slice) {
- current->time_slice += p->time_slice;
- if (unlikely(current->time_slice > task_timeslice(p)))
- current->time_slice = task_timeslice(p);
+ parent->time_slice += p->time_slice;
+ if (unlikely(parent->time_slice > task_timeslice(p)))
+ parent->time_slice = task_timeslice(p);
}
- if (p->sleep_avg < current->sleep_avg)
- current->sleep_avg = current->sleep_avg /
+ if (p->sleep_avg < parent->sleep_avg)
+ parent->sleep_avg = parent->sleep_avg /
(EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg /
(EXIT_WEIGHT + 1);
#else
@@ -2866,9 +2880,11 @@
rq->nr_switches++;
rq->curr = next;
++*switch_count;
+#ifdef SSI_SKIP
#ifdef CONFIG_MOSIX_LL
active_cpu_list[cpu] += (next->pid != 0) - (prev->pid != 0);
#endif
+#endif
prepare_arch_switch(rq, next);
prev = context_switch(rq, prev, next);
Index: exit.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/kernel/exit.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- exit.c 3 Feb 2009 06:18:14 -0000 1.20
+++ exit.c 27 Oct 2009 03:18:30 -0000 1.21
@@ -33,9 +33,10 @@
#include <asm/mmu_context.h>
#ifdef CONFIG_VPROC
-#include <linux/vproc.h>
#ifdef VPROC_CONTINUE
#include <linux/dpvproc.h>
+#else
+#include <linux/vproc.h>
#endif
#endif
@@ -138,7 +139,7 @@
(void)VPOP_REPORT_STATE(vl, sig, NULL, VPROC_ZOMBIE, 0);
VPROC_RELE(vl, "release_task(leader)");
}
-#endif
+#endif /* CONFIG_VPROC */
release_thread(p);
put_task_struct(p);
@@ -243,7 +244,7 @@
*/
if (ignored_task) {
v = ignored_task->p_vproc;
-
+ BUG_ON(!VP_HASHED(v));
(void) VPOP_ADJUST_JOB_CONTROL_COUNT(v);
return 0;
}
@@ -843,6 +844,9 @@
*/
INIT_LIST_HEAD(&ptrace_dead);
+#ifdef VPROC
+ /* SSI: forget_original_parent() releases and does not reacquire tasklist_lock */
+#endif
forget_original_parent(tsk, &ptrace_dead);
#ifndef VPROC
BUG_ON(!list_empty(&tsk->children));
@@ -1633,11 +1637,21 @@
int __user *stat_addr, struct rusage __user *ru)
{
#ifdef CONFIG_VPROC
- int retval;
- int vopts, vrtn;
struct pusage_dev pusage;
pid_t vretval;
+ int retval, vopts, vrtn;
task_t *tsk = current;
+#ifdef VPROC_VPROC_WNOTHREAD
+ int flag;
+ task_t *next;
+#ifdef TASK_HOLD_VPROC
+ struct vproc *vp;
+#endif
+#ifdef VPROC_VPROC_WNOTHREAD__SNAPSHOT
+ unsigned int count = 0, i = 0;
+ task_t **threads = NULL;
+#endif
+#endif /* VPROC_VPROC_WNOTHREAD */
#ifdef VPROC_DEBUG
extern int vpoptrace;
@@ -1680,34 +1694,197 @@
if (options & __WNOTHREAD)
vopts |= VPROC_WNOTHREAD;
- for (;;) {
-#endif
+repeat:
+ /*
+ * We will set this flag if we see any child that might later
+ * match our criteria, even if we are not able to reap it yet.
+ */
+ flag = 0;
+#ifdef VPROC_VPROC_WNOTHREAD__SNAPSHOT
+ if (options & __WNOTHREAD)
+ /* Don't wait on children of other threads in this group */
+ goto wnothread;
+
+ if (threads) {
+ /* Clean up previous iteration */
+ while (++i < count)
+ put_task_struct(threads[i]);
+ }
+
+ /* Generate array of pointers to threads in this group */
+ i = 0;
+ next = tsk = current;
+ read_lock(&tasklist_lock);
+ while_each_thread(tsk, next) i++;
+ read_unlock(&tasklist_lock);
+
+ if (i > count) {
+ /* Found more threads than previous attempt */
+ if (threads)
+ kfree(threads);
+ threads = kmalloc_nofail(sizeof(*threads) * i);
+ }
+ count = i;
+
+ if (count) {
+ i = 0;
+ next = tsk;
+ read_lock(&tasklist_lock);
+ while_each_thread(tsk, next) {
+ get_task_struct(next);
+ threads[i++] = next;
+ if (i == count)
+ break;
+ }
+ read_unlock(&tasklist_lock);
+ if (i < count)
+ count = i; /* found less threads */
+ }
+
+ i = 0;
+wnothread:
+ SSI_ASSERT(tsk == current);
+ get_task_struct(tsk);
+ do {
+#ifdef TASK_HOLD_VPROC
+ vp = tsk->p_vproc;
+
+ if (!VPROC_HOLD_AND_CHECK(vp, "do_wait")) {
+ put_task_struct(tsk);
+ goto next_thread;
+ }
+
+ vrtn = VPOP_WAIT(vp, pid, vopts, stat_addr, &pusage, &vretval);
+ VPROC_RELE(vp, "do_wait");
+#else
vrtn = VPOP_WAIT(tsk->p_vproc,
pid,
vopts,
stat_addr,
&pusage,
&vretval);
+#endif
+ put_task_struct(tsk);
- if (vrtn == ESUCCESS) {
- retval = vretval;
-#ifdef VPROC_VPROC_WNOTHREAD
+ retval = vretval;
+ if (vrtn == ESUCCESS && retval)
+ goto end;
+ if (vretval == -EAGAIN)
+ goto repeat;
+ if (vrtn == -EBUSY)
+ flag = 1;
+#ifdef TASK_HOLD_VPROC
+next_thread:
+#endif
+ if (!threads) /* Also true for __WNOTHREAD */
break;
+ tsk = threads[i];
+ } while (i++ < count);
+#else /* !VPROC_VPROC_WNOTHREAD__SNAPSHOT */
+ next = tsk = current;
+ get_task_struct(tsk);
+ get_task_struct(next);
+ do {
+ task_t *tmp;
+#ifdef TASK_HOLD_VPROC
+ vp = tsk->p_vproc;
+
+ if (!VPROC_HOLD_AND_CHECK(vp, "do_wait"))
+ goto next_thread;
+
+ vrtn = VPOP_WAIT(vp, pid, vopts, stat_addr, &pusage, &vretval);
+ VPROC_RELE(vp, "do_wait");
+#else
+ vrtn = VPOP_WAIT(tsk->p_vproc,
+ pid,
+ vopts,
+ stat_addr,
+ &pusage,
+ &vretval);
#endif
- } else
- retval = vrtn;
-#ifdef VPROC_VPROC_WNOTHREAD
+ retval = vretval;
+ if (vrtn == ESUCCESS && retval) {
+ put_task_struct(next);
+ put_task_struct(tsk);
+ goto end;
+ } else if (vrtn == -EBUSY)
+ flag = 1;
+ if (vretval == -EAGAIN) {
+ put_task_struct(next);
+ put_task_struct(tsk);
+ goto repeat;
+ }
if (options & __WNOTHREAD)
break;
+#ifdef TASK_HOLD_VPROC
+next_thread:
+#endif
+ tmp = tsk;
+
read_lock(&tasklist_lock);
- tsk = next_thread(tsk);
+ /* Re-check for possible dead task_struct. */
+ if (pid_alive(next)) {
+ /* Assumes no thread gets inserted before "next"
+ * while we are outside tasklist_lock.
+ */
+ tsk = next;
+ } else {
+ put_task_struct(next);
+ if (pid_alive(tsk))
+ tsk = next_thread(tsk);
+ else
+ tsk = next_thread(current);
+ get_task_struct(tsk);
+ }
if (tsk->signal != current->signal)
BUG();
+
+ next = next_thread(tsk);
+ get_task_struct(next);
read_unlock(&tasklist_lock);
- if (tsk == current)
- break;
+
+ put_task_struct(tmp); /* old tsk */
+ /* BUG_ON(tsk == tmp && tsk != current); */
+ } while (tsk != current);
+ put_task_struct(tsk);
+ put_task_struct(next);
+#endif /* !VPROC_VPROC_WNOTHREAD__SNAPSHOT */
+ if (flag) {
+ int intr;
+
+ retval = 0;
+ if (options & WNOHANG)
+ goto end;
+ retval = -ERESTARTSYS;
+ VPROC_WAIT_EVENT_WAIT(current->p_vproc, &intr);
+ if (intr)
+ goto end;
+ goto repeat;
+ }
+ retval = -ECHILD;
+end:
+#ifdef VPROC_VPROC_WNOTHREAD__SNAPSHOT
+ if (threads) {
+ /* Clean up remaining threads array */
+ while (++i < count)
+ put_task_struct(threads[i]);
+
+ kfree(threads);
}
#endif
+#else /* !VPROC_VPROC_WNOTHREAD */
+ vrtn = VPOP_WAIT(tsk->p_vproc,
+ pid,
+ vopts,
+ stat_addr,
+ &pusage,
+ &vretval);
+
+ if (vrtn == ESUCCESS) {
+ retval = vretval;
+ } else
+ retval = vrtn;
+#endif /* !VPROC_VPROC_WNOTHREAD */
#else /* !VPROC */
DECLARE_WAITQUEUE(wait, current);
struct task_struct *tsk;
@@ -2076,10 +2253,9 @@
if (retval == 0)
read_unlock(&tasklist_lock);
#ifndef VPROC_VPROC_WNOTHREAD
- if (retval == -EAGAIN) {
+ if (retval == -EAGAIN)
VPOP_REPORT_STATE(cp->p_vproc, cp->exit_signal,
NULL, VPROC_ZOMBIE, 0);
- }
#endif
break;
}
@@ -2091,7 +2267,7 @@
if (retval == 0)
read_unlock(&tasklist_lock);
break;
-#else
+#else /* !VPROC_CONTINUE */
case TASK_TRACED:
case TASK_STOPPED:
if (!cp->exit_code)
Index: sys.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/kernel/sys.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- sys.c 10 Oct 2008 08:10:33 -0000 1.14
+++ sys.c 27 Oct 2009 03:18:30 -0000 1.15
@@ -1353,6 +1353,9 @@
if (!thread_group_leader(current))
return -EINVAL;
+#ifdef PPROC_SETCTTY_SIGLOCK
+ lock_kernel(); /* for process_group() below */
+#endif
/*
* VPOP_SETSID will take care of
* seting the leader flag (in pvproc)
@@ -1361,9 +1364,11 @@
*/
err = VPOP_SETSID(current->p_vproc);
if (err == ESUCCESS)
- return process_group(current);
- else
- return err;
+ err = process_group(current);
+#ifdef PPROC_SETCTTY_SIGLOCK
+ unlock_kernel();
+#endif
+ return err;
}
#else
asmlinkage long sys_setsid(void)
Index: ptrace.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/kernel/ptrace.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- ptrace.c 10 Oct 2008 08:10:33 -0000 1.8
+++ ptrace.c 27 Oct 2009 03:18:30 -0000 1.9
@@ -39,14 +39,14 @@
{
#ifdef CONFIG_VPROC
int error = 0;
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+#if defined(VPROC_RELEASE__REFCNT_RACE_FIX) && !defined(TASK_HOLD_VPROC)
struct vproc *vc = NULL;
#endif
if (child->ppid == ppid)
return;
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+#if defined(VPROC_RELEASE__REFCNT_RACE_FIX) && !defined(TASK_HOLD_VPROC)
vc = LOCATE_VPROC_PID_ORIGIN(child->pid, "do__ptrace_link(child)");
SSI_ASSERT(vc);
error = VPOP_RECLAIM_CHILD(vc, ppid, 0, 0);
@@ -56,7 +56,7 @@
#endif
if (error != 0)
printk("__ptrace_link: vpop_reclaim_failed %d\n", error);
-#else
+#else /* !CONFIG_VPROC */
if (!list_empty(&child->ptrace_list))
BUG();
if (child->parent == new_parent)
Index: pid.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/kernel/pid.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- pid.c 3 Feb 2009 06:18:14 -0000 1.7
+++ pid.c 27 Oct 2009 03:18:30 -0000 1.8
@@ -93,12 +93,11 @@
* between LAST_DAEMON_PID and PID_MAX. It takes advantage of
* pid caching.
*/
-DEFINE_SPINLOCK(lastpid_lock);
-
int ssi_get_pid(void)
{
pid_t start_pid = RESERVED_PIDS;
pid_t try_pid;
+static DEFINE_SPINLOCK(lastpid_lock);
/* Handle proc 1 */
if (!(current->pid)) {
@@ -299,16 +298,34 @@
__detach_pid(thread, PIDTYPE_TGID);
leader->pid = leader->tgid = thread->pid;
- mb();
thread->pid = thread->tgid;
#ifdef VPROC
/* SSI_XXX: bad refcnt after switching vproc pids.
* Also have to mangle origin ?
*/
+#ifdef DE_THREAD__OOPS_FIX
+ /* VPOP_WAIT() pid > 0 is switch_exec_pids() aware */
+#endif
+ /* Need to update pvp_pgid and pvp_sid ? */
+ /* task->pid is being used to get to vproc - eg. setpgid call */
+#ifdef VPROC_RCU_LIST
+ /* Re-hash vproc */
+ SSI_ASSERT(leader->p_vproc);
+ SSI_ASSERT(thread->p_vproc);
+
+ VPROC_LIST_LOCK();
+ list_del_rcu(&thread->p_vproc->vp_list);
+ thread->p_vproc->vp_pid = thread->pid;
+ list_add_rcu(&thread->p_vproc->vp_list, &vproc_hash[VPROCPIDHASH(thread->pid)]);
+
+ list_del_rcu(&leader->p_vproc->vp_list);
+ leader->p_vproc->vp_pid = leader->pid;
+ list_add_rcu(&leader->p_vproc->vp_list, &vproc_hash[VPROCPIDHASH(leader->pid)]);
+ VPROC_LIST_UNLOCK();
+#endif
leader->epid = thread->epid;
- mb();
thread->epid = thread->pid;
-#endif
+#endif /* VPROC */
attach_pid(thread, PIDTYPE_PID, thread->pid);
attach_pid(thread, PIDTYPE_TGID, thread->tgid);
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference