summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2007-07-25 23:11:54 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2007-07-25 23:11:54 +0000
commit070039b1c8ca03061ac4202b16fd7b3e290f5c02 (patch)
treef019791fc2b31cd7da6831063764dce783a8677e /sys/kern
parent2a06794e0449288c91c5fbccd8dfe13c4cacf9d9 (diff)
Back out the tracking of procs in struct selinfo. There's one serious
bug in the code, but as soon as I try to fix it, it seems to trigger some other bugs. Instead of trying to figure out what's going on while everyone suffers, it's better to back out and figure out the bugs outside the tree.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c4
-rw-r--r--sys/kern/kern_fork.c4
-rw-r--r--sys/kern/sys_generic.c56
3 files changed, 22 insertions, 42 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index e6f95b17957..44d61a422d2 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.142 2007/06/01 19:25:09 deraadt Exp $ */
+/* $OpenBSD: init_main.c,v 1.143 2007/07/25 23:11:52 art Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -293,8 +293,6 @@ main(void *framep)
/* Create the file descriptor table. */
p->p_fd = fdinit(NULL);
- TAILQ_INIT(&p->p_selects);
-
/* Create the limits structures. */
p->p_p->ps_limit = &limit0;
for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index d4eb5fcc449..d54932106d7 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.91 2007/05/16 17:27:30 art Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.92 2007/07/25 23:11:52 art Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -280,8 +280,6 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
crhold(p1->p_ucred);
}
- TAILQ_INIT(&p2->p_selects);
-
/* bump references to the text vnode (for procfs) */
p2->p_textvp = p1->p_textvp;
if (p2->p_textvp)
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index a79c121c00c..f68f5251a7d 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_generic.c,v 1.56 2007/03/24 16:01:22 art Exp $ */
+/* $OpenBSD: sys_generic.c,v 1.57 2007/07/25 23:11:52 art Exp $ */
/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
/*
@@ -66,8 +66,6 @@ int selscan(struct proc *, fd_set *, fd_set *, int, int, register_t *);
int seltrue(dev_t, int, struct proc *);
void pollscan(struct proc *, struct pollfd *, u_int, register_t *);
-void sel_clean_proclist(struct proc *);
-
/*
* Read system call.
*/
@@ -710,7 +708,6 @@ retry:
if (error == 0)
goto retry;
done:
- sel_clean_proclist(p);
atomic_clearbits_int(&p->p_flag, P_SELECT);
/* select is not restarted after signals... */
if (error == ERESTART)
@@ -784,12 +781,17 @@ seltrue(dev_t dev, int events, struct proc *p)
void
selrecord(struct proc *selector, struct selinfo *sip)
{
- if (sip->si_selproc == NULL) {
- sip->si_selproc = selector;
- TAILQ_INSERT_TAIL(&selector->p_selects, sip, si_list);
- } else if (sip->si_selproc != selector) {
+ struct proc *p;
+ pid_t mypid;
+
+ mypid = selector->p_pid;
+ if (sip->si_selpid == mypid)
+ return;
+ if (sip->si_selpid && (p = pfind(sip->si_selpid)) &&
+ p->p_wchan == (caddr_t)&selwait)
sip->si_flags |= SI_COLL;
- }
+ else
+ sip->si_selpid = mypid;
}
/*
@@ -801,42 +803,25 @@ selwakeup(struct selinfo *sip)
struct proc *p;
int s;
+ if (sip->si_selpid == 0)
+ return;
if (sip->si_flags & SI_COLL) {
nselcoll++;
sip->si_flags &= ~SI_COLL;
wakeup(&selwait);
}
-
- /*
- * We check the process once before locking.
- * Then we wake the process and clean up its
- * selects list.
- */
- if (sip->si_selproc == NULL)
- return;
-
- SCHED_LOCK(s);
- if ((p = sip->si_selproc) != NULL) {
- if (p->p_wchan != NULL) {
+ p = pfind(sip->si_selpid);
+ sip->si_selpid = 0;
+ if (p != NULL) {
+ SCHED_LOCK(s);
+ if (p->p_wchan == (caddr_t)&selwait) {
if (p->p_stat == SSLEEP)
setrunnable(p);
else
unsleep(p);
- } else {
+ } else if (p->p_flag & P_SELECT)
atomic_clearbits_int(&p->p_flag, P_SELECT);
- }
- }
- SCHED_UNLOCK(s);
-}
-
-void
-sel_clean_proclist(struct proc *p)
-{
- struct selinfo *sip;
-
- while ((sip = TAILQ_FIRST(&p->p_selects)) != NULL) {
- sip->si_selproc = NULL;
- TAILQ_REMOVE(&p->p_selects, sip, si_list);
+ SCHED_UNLOCK(s);
}
}
@@ -947,7 +932,6 @@ retry:
goto retry;
done:
- sel_clean_proclist(p);
atomic_clearbits_int(&p->p_flag, P_SELECT);
/*
* NOTE: poll(2) is not restarted after a signal and EWOULDBLOCK is