diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2007-03-24 16:01:23 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2007-03-24 16:01:23 +0000 |
commit | b85e9ba20c14a428d67fc578018fd8a539c89f7b (patch) | |
tree | b40dafa9a5122b8fb1353291f58602e22cbd30a1 /sys | |
parent | bb009c4c0bea668c35c72a9601e752153bc19d8a (diff) |
Kill the horrible hack of storing the pid in struct selinfo.
Instead, keep the proc pointer in it and put the selinfo on a list
in struct proc in selrecord. Then clean up the list when leaving
sys_select and sys_poll.
miod@ ok, testing by many, including Bobs spamd boxes.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/bktr/bktr_core.c | 10 | ||||
-rw-r--r-- | sys/dev/wscons/wsdisplay.c | 4 | ||||
-rw-r--r-- | sys/kern/init_main.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 4 | ||||
-rw-r--r-- | sys/kern/sys_generic.c | 56 | ||||
-rw-r--r-- | sys/net/bpf.c | 4 | ||||
-rw-r--r-- | sys/sys/proc.h | 4 | ||||
-rw-r--r-- | sys/sys/selinfo.h | 9 |
8 files changed, 55 insertions, 40 deletions
diff --git a/sys/dev/pci/bktr/bktr_core.c b/sys/dev/pci/bktr/bktr_core.c index c6eaa5bf9dc..23c4f680ebf 100644 --- a/sys/dev/pci/bktr/bktr_core.c +++ b/sys/dev/pci/bktr/bktr_core.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bktr_core.c,v 1.21 2007/02/11 20:29:22 miod Exp $ */ +/* $OpenBSD: bktr_core.c,v 1.22 2007/03/24 16:01:21 art Exp $ */ /* $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.114 2000/10/31 13:09:56 roger Exp $ */ /* @@ -810,13 +810,7 @@ common_bktr_intr( void *arg ) } /* If someone has a select() on /dev/vbi, inform them */ -#ifndef __OpenBSD__ - if (bktr->vbi_select.si_pid) { -#else - if (bktr->vbi_select.si_selpid) { -#endif - selwakeup(&bktr->vbi_select); - } + selwakeup(&bktr->vbi_select); } diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c index 8b78a22f0a0..68a3e0fc352 100644 --- a/sys/dev/wscons/wsdisplay.c +++ b/sys/dev/wscons/wsdisplay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsdisplay.c,v 1.77 2007/03/07 06:23:04 miod Exp $ */ +/* $OpenBSD: wsdisplay.c,v 1.78 2007/03/24 16:01:22 art Exp $ */ /* $NetBSD: wsdisplay.c,v 1.82 2005/02/27 00:27:52 perry Exp $ */ /* @@ -1402,7 +1402,7 @@ wsdisplaystart(struct tty *tp) splx(s); return; } - if (tp->t_outq.c_cc == 0 && tp->t_wsel.si_selpid == 0) + if (tp->t_outq.c_cc == 0 && tp->t_wsel.si_selproc == NULL) goto low; if ((scr = sc->sc_scr[WSDISPLAYSCREEN(tp->t_dev)]) == NULL) { diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index e41810455d8..291aa2e5a6a 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.136 2007/03/19 14:33:28 dlg Exp $ */ +/* $OpenBSD: init_main.c,v 1.137 2007/03/24 16:01:22 art Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -296,6 +296,8 @@ main(void *framep) /* Create the file descriptor table. */ p->p_fd = fdinit(NULL); + TAILQ_INIT(&p->p_selects); + /* Create the limits structures. */ p->p_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 d19608d9cbc..da8d0df31c4 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.87 2007/03/15 10:22:30 art Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.88 2007/03/24 16:01:22 art Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -246,6 +246,8 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize, p2->p_cred->p_refcnt = 1; 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 31cbafefff7..a79c121c00c 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_generic.c,v 1.55 2007/03/15 10:22:30 art Exp $ */ +/* $OpenBSD: sys_generic.c,v 1.56 2007/03/24 16:01:22 art Exp $ */ /* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */ /* @@ -66,6 +66,8 @@ 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. */ @@ -708,6 +710,7 @@ 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) @@ -781,17 +784,12 @@ seltrue(dev_t dev, int events, struct proc *p) void selrecord(struct proc *selector, struct selinfo *sip) { - 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) + if (sip->si_selproc == NULL) { + sip->si_selproc = selector; + TAILQ_INSERT_TAIL(&selector->p_selects, sip, si_list); + } else if (sip->si_selproc != selector) { sip->si_flags |= SI_COLL; - else - sip->si_selpid = mypid; + } } /* @@ -803,25 +801,42 @@ 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); } - p = pfind(sip->si_selpid); - sip->si_selpid = 0; - if (p != NULL) { - SCHED_LOCK(s); - if (p->p_wchan == (caddr_t)&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) { if (p->p_stat == SSLEEP) setrunnable(p); else unsleep(p); - } else if (p->p_flag & P_SELECT) + } else { atomic_clearbits_int(&p->p_flag, P_SELECT); - SCHED_UNLOCK(s); + } + } + 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); } } @@ -932,6 +947,7 @@ 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 diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 4c18bec6b24..0b3e79cd67e 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bpf.c,v 1.64 2007/03/04 23:36:34 canacar Exp $ */ +/* $OpenBSD: bpf.c,v 1.65 2007/03/24 16:01:22 art Exp $ */ /* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */ /* @@ -496,8 +496,6 @@ bpf_wakeup(struct bpf_d *d) d->bd_siguid, d->bd_sigeuid); selwakeup(&d->bd_sel); - /* XXX */ - d->bd_sel.si_selpid = 0; KNOTE(&d->bd_sel.si_note, 0); } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 7fb12a40c21..f956d2be875 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.91 2007/03/21 09:09:52 art Exp $ */ +/* $OpenBSD: proc.h,v 1.92 2007/03/24 16:01:22 art Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -211,6 +211,8 @@ struct proc { sigset_t p_sigdivert; /* Signals to be diverted to thread. */ + TAILQ_HEAD(,selinfo) p_selects; /* selinfos we're selecting on */ + /* End area that is zeroed on creation. */ #define p_endzero p_startcopy diff --git a/sys/sys/selinfo.h b/sys/sys/selinfo.h index 497c2da9d19..535b48deb42 100644 --- a/sys/sys/selinfo.h +++ b/sys/sys/selinfo.h @@ -1,4 +1,4 @@ -/* $OpenBSD: selinfo.h,v 1.1 2005/11/21 18:16:46 millert Exp $ */ +/* $OpenBSD: selinfo.h,v 1.2 2007/03/24 16:01:22 art Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,9 +41,10 @@ * notified when I/O becomes possible. */ struct selinfo { - pid_t si_selpid; /* process to be notified */ - struct klist si_note; /* kernel note list */ - short si_flags; /* see below */ + struct proc *si_selproc; + TAILQ_ENTRY(selinfo) si_list; /* list of selinfo for a process */ + struct klist si_note; /* kernel note list */ + short si_flags; /* see below */ }; #define SI_COLL 0x0001 /* collision occurred */ |