> 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*/
>  
> 
> 

Reply via email to