Small refactoring needed to manage per-thread kqueues. Such kqueue are not associated to a file descriptor, that's why the functions below take a "struct kqueue *" as argument.
ok? Index: kern/kern_event.c =================================================================== RCS file: /cvs/src/sys/kern/kern_event.c,v retrieving revision 1.132 diff -u -p -r1.132 kern_event.c --- kern/kern_event.c 17 May 2020 10:53:14 -0000 1.132 +++ kern/kern_event.c 25 May 2020 11:24:03 -0000 @@ -57,6 +57,8 @@ #include <sys/timeout.h> #include <sys/wait.h> +void kqueue_terminate(struct proc *p, struct kqueue *); +void kqueue_free(struct kqueue *); void kqueue_init(void); void KQREF(struct kqueue *); void KQRELE(struct kqueue *); @@ -181,8 +183,13 @@ KQRELE(struct kqueue *kq) fdpunlock(fdp); } - free(kq->kq_knlist, M_KEVENT, kq->kq_knlistsize * - sizeof(struct knlist)); + kqueue_free(kq); +} + +void +kqueue_free(struct kqueue *kq) +{ + free(kq->kq_knlist, M_KEVENT, kq->kq_knlistsize * sizeof(struct klist)); hashfree(kq->kq_knhash, KN_HASHSIZE, M_KEVENT); pool_put(&kqueue_pool, kq); } @@ -492,13 +499,10 @@ static const struct filterops dead_filto .f_event = filt_dead, }; -int -sys_kqueue(struct proc *p, void *v, register_t *retval) +struct kqueue * +kqueue_alloc(struct filedesc *fdp) { - struct filedesc *fdp = p->p_fd; struct kqueue *kq; - struct file *fp; - int fd, error; kq = pool_get(&kqueue_pool, PR_WAITOK | PR_ZERO); kq->kq_refs = 1; @@ -506,6 +510,19 @@ sys_kqueue(struct proc *p, void *v, regi TAILQ_INIT(&kq->kq_head); task_set(&kq->kq_task, kqueue_task, kq); + return (kq); +} + +int +sys_kqueue(struct proc *p, void *v, register_t *retval) +{ + struct filedesc *fdp = p->p_fd; + struct kqueue *kq; + struct file *fp; + int fd, error; + + kq = kqueue_alloc(fdp); + fdplock(fdp); error = falloc(p, &fp, &fd); if (error) @@ -1115,13 +1132,12 @@ kqueue_stat(struct file *fp, struct stat return (0); } -int -kqueue_close(struct file *fp, struct proc *p) +void +kqueue_terminate(struct proc *p, struct kqueue *kq) { - struct kqueue *kq = fp->f_data; int i; - KERNEL_LOCK(); + KERNEL_ASSERT_LOCKED(); for (i = 0; i < kq->kq_knlistsize; i++) knote_remove(p, &kq->kq_knlist[i]); @@ -1129,13 +1145,22 @@ kqueue_close(struct file *fp, struct pro for (i = 0; i < kq->kq_knhashmask + 1; i++) knote_remove(p, &kq->kq_knhash[i]); } - fp->f_data = NULL; - kq->kq_state |= KQ_DYING; kqueue_wakeup(kq); KASSERT(klist_empty(&kq->kq_sel.si_note)); task_del(systq, &kq->kq_task); + +} + +int +kqueue_close(struct file *fp, struct proc *p) +{ + struct kqueue *kq = fp->f_data; + + KERNEL_LOCK(); + kqueue_terminate(p, kq); + fp->f_data = NULL; KQRELE(kq);