summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_descrip.c11
-rw-r--r--sys/kern/kern_event.c102
-rw-r--r--sys/kern/kern_fork.c3
-rw-r--r--sys/sys/eventvar.h10
-rw-r--r--sys/sys/filedesc.h7
-rw-r--r--sys/sys/proc.h4
6 files changed, 74 insertions, 63 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 4a0630cc38a..4d7b0a44016 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_descrip.c,v 1.164 2018/06/05 09:29:05 mpi Exp $ */
+/* $OpenBSD: kern_descrip.c,v 1.165 2018/06/17 08:22:02 anton Exp $ */
/* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */
/*
@@ -650,8 +650,7 @@ finishdup(struct proc *p, struct file *fp, int old, int new,
*retval = new;
if (oldfp != NULL) {
- if (new < fdp->fd_knlistsize)
- knote_fdclose(p, new);
+ knote_fdclose(p, new);
closef(oldfp, p);
}
@@ -686,8 +685,7 @@ fdrelease(struct proc *p, int fd)
FREF(fp);
*fpp = NULL;
fd_unused(fdp, fd);
- if (fd < fdp->fd_knlistsize)
- knote_fdclose(p, fd);
+ knote_fdclose(p, fd);
return (closef(fp, p));
}
@@ -999,7 +997,6 @@ fdinit(void)
newfdp->fd_fd.fd_nfiles = NDFILE;
newfdp->fd_fd.fd_himap = newfdp->fd_dhimap;
newfdp->fd_fd.fd_lomap = newfdp->fd_dlomap;
- newfdp->fd_fd.fd_knlistsize = -1;
newfdp->fd_fd.fd_freefile = 0;
newfdp->fd_fd.fd_lastfile = 0;
@@ -1129,8 +1126,6 @@ fdfree(struct proc *p)
vrele(fdp->fd_cdir);
if (fdp->fd_rdir)
vrele(fdp->fd_rdir);
- free(fdp->fd_knlist, M_TEMP, fdp->fd_knlistsize * sizeof(struct klist));
- hashfree(fdp->fd_knhash, KN_HASHSIZE, M_TEMP);
pool_put(&fdesc_pool, fdp);
}
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index ba10b9eafac..809ed1f03a2 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_event.c,v 1.92 2018/06/15 01:09:49 cheloha Exp $ */
+/* $OpenBSD: kern_event.c,v 1.93 2018/06/17 08:22:02 anton Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -80,8 +80,8 @@ struct fileops kqueueops = {
.fo_close = kqueue_close
};
-void knote_attach(struct knote *kn, struct filedesc *fdp);
-void knote_drop(struct knote *kn, struct proc *p, struct filedesc *fdp);
+void knote_attach(struct knote *kn);
+void knote_drop(struct knote *kn, struct proc *p);
void knote_enqueue(struct knote *kn);
void knote_dequeue(struct knote *kn);
#define knote_alloc() ((struct knote *)pool_get(&knote_pool, PR_WAITOK))
@@ -152,9 +152,13 @@ KQREF(struct kqueue *kq)
void
KQRELE(struct kqueue *kq)
{
- if (--kq->kq_refs == 0) {
- pool_put(&kqueue_pool, kq);
- }
+ if (--kq->kq_refs > 0)
+ return;
+
+ LIST_REMOVE(kq, kq_next);
+ free(kq->kq_knlist, M_TEMP, kq->kq_knlistsize * sizeof(struct klist));
+ hashfree(kq->kq_knhash, KN_HASHSIZE, M_TEMP);
+ pool_put(&kqueue_pool, kq);
}
void kqueue_init(void);
@@ -453,10 +457,9 @@ sys_kqueue(struct proc *p, void *v, register_t *retval)
fp->f_data = kq;
KQREF(kq);
*retval = fd;
- if (fdp->fd_knlistsize < 0)
- fdp->fd_knlistsize = 0; /* this process has a kq */
kq->kq_fdp = fdp;
FILE_SET_MATURE(fp, p);
+ LIST_INSERT_HEAD(&p->p_p->ps_kqlist, kq, kq_next);
return (0);
}
@@ -583,19 +586,19 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p)
if ((fp = fd_getfile(fdp, kev->ident)) == NULL)
return (EBADF);
- if (kev->ident < fdp->fd_knlistsize) {
- SLIST_FOREACH(kn, &fdp->fd_knlist[kev->ident], kn_link) {
+ if (kev->ident < kq->kq_knlistsize) {
+ SLIST_FOREACH(kn, &kq->kq_knlist[kev->ident], kn_link) {
if (kq == kn->kn_kq &&
kev->filter == kn->kn_filter)
break;
}
}
} else {
- if (fdp->fd_knhashmask != 0) {
+ if (kq->kq_knhashmask != 0) {
struct klist *list;
- list = &fdp->fd_knhash[
- KN_HASH((u_long)kev->ident, fdp->fd_knhashmask)];
+ list = &kq->kq_knhash[
+ KN_HASH((u_long)kev->ident, kq->kq_knhashmask)];
SLIST_FOREACH(kn, list, kn_link) {
if (kev->ident == kn->kn_id &&
kq == kn->kn_kq &&
@@ -637,9 +640,9 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p)
kev->data = 0;
kn->kn_kevent = *kev;
- knote_attach(kn, fdp);
+ knote_attach(kn);
if ((error = fops->f_attach(kn)) != 0) {
- knote_drop(kn, p, fdp);
+ knote_drop(kn, p);
goto done;
}
} else {
@@ -660,7 +663,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p)
} else if (kev->flags & EV_DELETE) {
kn->kn_fop->f_detach(kn);
- knote_drop(kn, p, p->p_fd);
+ knote_drop(kn, p);
goto done;
}
@@ -796,7 +799,7 @@ start:
kn->kn_status &= ~KN_QUEUED;
splx(s);
kn->kn_fop->f_detach(kn);
- knote_drop(kn, p, p->p_fd);
+ knote_drop(kn, p);
s = splhigh();
} else if (kn->kn_flags & (EV_CLEAR | EV_DISPATCH)) {
if (kn->kn_flags & EV_CLEAR) {
@@ -900,12 +903,11 @@ int
kqueue_close(struct file *fp, struct proc *p)
{
struct kqueue *kq = fp->f_data;
- struct filedesc *fdp = p->p_fd;
struct knote **knp, *kn, *kn0;
int i;
- for (i = 0; i < fdp->fd_knlistsize; i++) {
- knp = &SLIST_FIRST(&fdp->fd_knlist[i]);
+ for (i = 0; i < kq->kq_knlistsize; i++) {
+ knp = &SLIST_FIRST(&kq->kq_knlist[i]);
kn = *knp;
while (kn != NULL) {
kn0 = SLIST_NEXT(kn, kn_link);
@@ -920,9 +922,9 @@ kqueue_close(struct file *fp, struct proc *p)
kn = kn0;
}
}
- if (fdp->fd_knhashmask != 0) {
- for (i = 0; i < fdp->fd_knhashmask + 1; i++) {
- knp = &SLIST_FIRST(&fdp->fd_knhash[i]);
+ if (kq->kq_knhashmask != 0) {
+ for (i = 0; i < kq->kq_knhashmask + 1; i++) {
+ knp = &SLIST_FIRST(&kq->kq_knhash[i]);
kn = *knp;
while (kn != NULL) {
kn0 = SLIST_NEXT(kn, kn_link);
@@ -994,7 +996,7 @@ knote_remove(struct proc *p, struct klist *list)
while ((kn = SLIST_FIRST(list)) != NULL) {
kn->kn_fop->f_detach(kn);
- knote_drop(kn, p, p->p_fd);
+ knote_drop(kn, p);
}
}
@@ -1004,10 +1006,16 @@ knote_remove(struct proc *p, struct klist *list)
void
knote_fdclose(struct proc *p, int fd)
{
- struct filedesc *fdp = p->p_fd;
- struct klist *list = &fdp->fd_knlist[fd];
+ struct kqueue *kq;
+ struct klist *list;
+
+ LIST_FOREACH(kq, &p->p_p->ps_kqlist, kq_next) {
+ if (fd >= kq->kq_knlistsize)
+ continue;
- knote_remove(p, list);
+ list = &kq->kq_knlist[fd];
+ knote_remove(p, list);
+ }
}
/*
@@ -1026,35 +1034,36 @@ knote_processexit(struct proc *p)
}
void
-knote_attach(struct knote *kn, struct filedesc *fdp)
+knote_attach(struct knote *kn)
{
+ struct kqueue *kq = kn->kn_kq;
struct klist *list;
int size;
if (!kn->kn_fop->f_isfd) {
- if (fdp->fd_knhashmask == 0)
- fdp->fd_knhash = hashinit(KN_HASHSIZE, M_TEMP,
- M_WAITOK, &fdp->fd_knhashmask);
- list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)];
+ if (kq->kq_knhashmask == 0)
+ kq->kq_knhash = hashinit(KN_HASHSIZE, M_TEMP,
+ M_WAITOK, &kq->kq_knhashmask);
+ list = &kq->kq_knhash[KN_HASH(kn->kn_id, kq->kq_knhashmask)];
goto done;
}
- if (fdp->fd_knlistsize <= kn->kn_id) {
- size = fdp->fd_knlistsize;
+ if (kq->kq_knlistsize <= kn->kn_id) {
+ size = kq->kq_knlistsize;
while (size <= kn->kn_id)
size += KQEXTENT;
list = mallocarray(size, sizeof(struct klist), M_TEMP,
M_WAITOK);
- memcpy(list, fdp->fd_knlist,
- fdp->fd_knlistsize * sizeof(struct klist));
- memset(&list[fdp->fd_knlistsize], 0,
- (size - fdp->fd_knlistsize) * sizeof(struct klist));
- free(fdp->fd_knlist, M_TEMP,
- fdp->fd_knlistsize * sizeof(struct klist));
- fdp->fd_knlistsize = size;
- fdp->fd_knlist = list;
+ memcpy(list, kq->kq_knlist,
+ kq->kq_knlistsize * sizeof(struct klist));
+ memset(&list[kq->kq_knlistsize], 0,
+ (size - kq->kq_knlistsize) * sizeof(struct klist));
+ free(kq->kq_knlist, M_TEMP,
+ kq->kq_knlistsize * sizeof(struct klist));
+ kq->kq_knlistsize = size;
+ kq->kq_knlist = list;
}
- list = &fdp->fd_knlist[kn->kn_id];
+ list = &kq->kq_knlist[kn->kn_id];
done:
SLIST_INSERT_HEAD(list, kn, kn_link);
kn->kn_status = 0;
@@ -1065,14 +1074,15 @@ done:
* while calling FRELE and knote_free.
*/
void
-knote_drop(struct knote *kn, struct proc *p, struct filedesc *fdp)
+knote_drop(struct knote *kn, struct proc *p)
{
+ struct kqueue *kq = kn->kn_kq;
struct klist *list;
if (kn->kn_fop->f_isfd)
- list = &fdp->fd_knlist[kn->kn_id];
+ list = &kq->kq_knlist[kn->kn_id];
else
- list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)];
+ list = &kq->kq_knhash[KN_HASH(kn->kn_id, kq->kq_knhashmask)];
SLIST_REMOVE(list, kn, knote, kn_link);
if (kn->kn_status & KN_QUEUED)
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 8d90d91d11b..291be50d21c 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.202 2017/12/30 20:47:00 guenther Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.203 2018/06/17 08:22:02 anton Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -198,6 +198,7 @@ process_initialize(struct process *pr, struct proc *p)
KASSERT(p->p_ucred->cr_ref >= 2); /* new thread and new process */
LIST_INIT(&pr->ps_children);
+ LIST_INIT(&pr->ps_kqlist);
timeout_set(&pr->ps_realit_to, realitexpire, pr);
}
diff --git a/sys/sys/eventvar.h b/sys/sys/eventvar.h
index 6796a0ceef9..4a53d17f37b 100644
--- a/sys/sys/eventvar.h
+++ b/sys/sys/eventvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: eventvar.h,v 1.4 2017/10/11 08:01:10 mpi Exp $ */
+/* $OpenBSD: eventvar.h,v 1.5 2018/06/17 08:22:02 anton Exp $ */
/*-
* Copyright (c) 1999,2000 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -40,6 +40,14 @@ struct kqueue {
int kq_refs; /* number of references */
struct selinfo kq_sel;
struct filedesc *kq_fdp;
+
+ LIST_ENTRY(kqueue) kq_next;
+
+ int kq_knlistsize; /* size of knlist */
+ struct klist *kq_knlist; /* list of attached knotes */
+ u_long kq_knhashmask; /* size of knhash */
+ struct klist *kq_knhash; /* hash table for attached knotes */
+
int kq_state;
#define KQ_SEL 0x01
#define KQ_SLEEP 0x02
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index 9572afaa676..eab3ba7e885 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: filedesc.h,v 1.37 2018/06/05 09:29:05 mpi Exp $ */
+/* $OpenBSD: filedesc.h,v 1.38 2018/06/17 08:22:02 anton Exp $ */
/* $NetBSD: filedesc.h,v 1.14 1996/04/09 20:55:28 cgd Exp $ */
/*
@@ -73,11 +73,6 @@ struct filedesc {
/* held when writing to fd_ofiles, */
/* fd_ofileflags, or fd_{hi,lo}map */
- int fd_knlistsize; /* size of knlist */
- struct klist *fd_knlist; /* list of attached knotes */
- u_long fd_knhashmask; /* size of knhash */
- struct klist *fd_knhash; /* hash table for attached knotes */
-
int fd_flags; /* flags on the file descriptor table */
};
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 1c7ea4697e2..40f36d11ee7 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.248 2018/04/12 17:13:44 deraadt Exp $ */
+/* $OpenBSD: proc.h,v 1.249 2018/06/17 08:22:02 anton Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -168,6 +168,8 @@ struct process {
struct vmspace *ps_vmspace; /* Address space */
pid_t ps_pid; /* Process identifier. */
+ LIST_HEAD(, kqueue) ps_kqlist; /* kqueues attached to this process */
+
/* The following fields are all zeroed upon creation in process_new. */
#define ps_startzero ps_klist
struct klist ps_klist; /* knotes attached to this process */