> Date: Mon, 7 Dec 2020 14:18:41 -0300
> From: Martin Pieuchot <[email protected]>
>
> Diff below adds a per-thread kqueue that will be initialized during the
> first select(2) or poll(2) syscall and freed upon exit.
>
> Along with this queue a per-thread serial number is used to check the
> integrity of events enqueued during a given syscall. This could also
> later be used to perform lazy removal of events.
>
> Ok?
See below...
> Index: kern/kern_event.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_event.c,v
> retrieving revision 1.146
> diff -u -p -r1.146 kern_event.c
> --- kern/kern_event.c 7 Dec 2020 11:15:50 -0000 1.146
> +++ kern/kern_event.c 7 Dec 2020 17:00:13 -0000
> @@ -57,6 +57,7 @@
> #include <sys/timeout.h>
> #include <sys/wait.h>
>
> +struct kqueue *kqueue_alloc(struct filedesc *);
> void kqueue_terminate(struct proc *p, struct kqueue *);
> void kqueue_free(struct kqueue *);
> void kqueue_init(void);
> @@ -504,6 +505,31 @@ const struct filterops dead_filtops = {
> .f_event = filt_dead,
> };
>
> +void
> +kqpoll_init(void)
> +{
> + struct proc *p = curproc;
> +
> + if (p->p_kq != NULL)
> + return;
> +
> + p->p_kq = kqueue_alloc(p->p_fd);
> + p->p_kq_serial = arc4random();
Using a random number as a serial number is odd, as there could be
duplicates. Of course a true serial number will wrap at some point
which can lead to duplicates if it wraps and you have long-lived
processes.
Is there a reason why you can't use p_tid?
And how is this to be used? This diff doesn't actually use it...
> +}
> +
> +void
> +kqpoll_exit(void)
> +{
> + struct proc *p = curproc;
> +
> + if (p->p_kq == NULL)
> + return;
> +
> + kqueue_terminate(p, p->p_kq);
> + kqueue_free(p->p_kq);
> + p->p_kq = NULL;
> +}
> +
> struct kqueue *
> kqueue_alloc(struct filedesc *fdp)
> {
> @@ -1144,7 +1170,7 @@ kqueue_stat(struct file *fp, struct stat
> }
>
> void
> -kqueue_terminate(struct proc *p, struct kqueue *kq)
> +kqueue_purge(struct proc *p, struct kqueue *kq)
> {
> int i;
>
> @@ -1156,6 +1182,12 @@ kqueue_terminate(struct proc *p, struct
> for (i = 0; i < kq->kq_knhashmask + 1; i++)
> knote_remove(p, &kq->kq_knhash[i]);
> }
> +}
> +
> +void
> +kqueue_terminate(struct proc *p, struct kqueue *kq)
> +{
> + kqueue_purge(p, kq);
> kq->kq_state |= KQ_DYING;
> kqueue_wakeup(kq);
>
> Index: kern/kern_exit.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_exit.c,v
> retrieving revision 1.191
> diff -u -p -r1.191 kern_exit.c
> --- kern/kern_exit.c 16 Nov 2020 18:37:06 -0000 1.191
> +++ kern/kern_exit.c 7 Dec 2020 17:03:50 -0000
> @@ -184,6 +184,8 @@ exit1(struct proc *p, int xexit, int xsi
> if ((p->p_flag & P_THREAD) == 0)
> pr->ps_siglist = 0;
>
> + kqpoll_exit();
> +
> #if NKCOV > 0
> kcov_exit(p);
> #endif
> Index: sys/event.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/event.h,v
> retrieving revision 1.48
> diff -u -p -r1.48 event.h
> --- sys/event.h 7 Dec 2020 11:15:50 -0000 1.48
> +++ sys/event.h 7 Dec 2020 17:01:10 -0000
> @@ -215,6 +215,8 @@ struct timespec;
> extern const struct filterops sig_filtops;
> extern const struct filterops dead_filtops;
>
> +extern void kqpoll_init(void);
> +extern void kqpoll_exit(void);
> extern void knote(struct klist *list, long hint);
> extern void knote_activate(struct knote *);
> extern void knote_remove(struct proc *p, struct knlist *list);
> @@ -226,6 +228,7 @@ extern int kqueue_scan(struct kqueue_sca
> struct timespec *, struct proc *, int *);
> extern void kqueue_scan_setup(struct kqueue_scan_state *, struct kqueue *);
> extern void kqueue_scan_finish(struct kqueue_scan_state *);
> +extern void kqueue_purge(struct proc *, struct kqueue *);
> extern int filt_seltrue(struct knote *kn, long hint);
> extern int seltrue_kqfilter(dev_t, struct knote *);
> extern void klist_insert(struct klist *, struct knote *);
> Index: sys/proc.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/proc.h,v
> retrieving revision 1.301
> diff -u -p -r1.301 proc.h
> --- sys/proc.h 10 Nov 2020 17:26:54 -0000 1.301
> +++ sys/proc.h 7 Dec 2020 17:03:17 -0000
> @@ -320,6 +320,7 @@ struct process {
>
> struct kcov_dev;
> struct lock_list_entry;
> +struct kqueue;
>
> struct p_inentry {
> u_long ie_serial;
> @@ -382,6 +383,8 @@ struct proc {
> struct plimit *p_limit; /* [l] read ref. of p_p->ps_limit */
> struct kcov_dev *p_kd; /* kcov device handle */
> struct lock_list_entry *p_sleeplocks; /* WITNESS lock tracking */
> + struct kqueue *p_kq; /* [o] select/poll queue of evts */
> + unsigned long p_kq_serial; /* [o] to check against enqueued evts */
>
> int p_siglist; /* [a] Signals arrived & not delivered*/
>
>
>