> Date: Mon, 9 Oct 2017 11:48:56 +0200
> From: Martin Pieuchot <[email protected]>
>
> This is the first step to allow kqueue_scan() to be executed in
> parallel. I'm currently focusing on data structure ownership with
> regard to sleep. I don't plan to get rid of the KERNEL_LOCK() for
> the moment. I don't think it makes sense unless we can unlock the
> kevent(2) syscall.
>
> The diff below move 'struct kevent' storage to the stack. This is
> the simplest way to make it mp-safe.
>
> This has been tested as part of a larger diff by many.
>
> Ok?
How big (in bytes) are the arrays you're putting on the stack?
> Index: kern/kern_event.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_event.c,v
> retrieving revision 1.79
> diff -u -p -r1.79 kern_event.c
> --- kern/kern_event.c 31 May 2017 14:52:05 -0000 1.79
> +++ kern/kern_event.c 9 Oct 2017 09:02:48 -0000
> @@ -476,6 +476,7 @@ sys_kevent(struct proc *p, void *v, regi
> struct file *fp;
> struct timespec ts;
> int i, n, nerrors, error;
> + struct kevent kev[KQ_NEVENTS];
>
> if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL ||
> (fp->f_type != DTYPE_KQUEUE))
> @@ -500,16 +501,16 @@ sys_kevent(struct proc *p, void *v, regi
> while (SCARG(uap, nchanges) > 0) {
> n = SCARG(uap, nchanges) > KQ_NEVENTS ?
> KQ_NEVENTS : SCARG(uap, nchanges);
> - error = copyin(SCARG(uap, changelist), kq->kq_kev,
> + error = copyin(SCARG(uap, changelist), kev,
> n * sizeof(struct kevent));
> if (error)
> goto done;
> #ifdef KTRACE
> if (KTRPOINT(p, KTR_STRUCT))
> - ktrevent(p, kq->kq_kev, n);
> + ktrevent(p, kev, n);
> #endif
> for (i = 0; i < n; i++) {
> - kevp = &kq->kq_kev[i];
> + kevp = &kev[i];
> kevp->flags &= ~EV_SYSFLAGS;
> error = kqueue_register(kq, kevp, p);
> if (error || (kevp->flags & EV_RECEIPT)) {
> @@ -691,6 +692,7 @@ kqueue_scan(struct kqueue *kq, int maxev
> struct timeval atv, rtv, ttv;
> struct knote *kn, marker;
> int s, count, timeout, nkev = 0, error = 0;
> + struct kevent kev[KQ_NEVENTS];
>
> count = maxevents;
> if (count == 0)
> @@ -737,7 +739,7 @@ start:
> goto done;
> }
>
> - kevp = kq->kq_kev;
> + kevp = &kev[0];
> s = splhigh();
> if (kq->kq_count == 0) {
> if (timeout < 0) {
> @@ -805,13 +807,13 @@ start:
> splx(s);
> #ifdef KTRACE
> if (KTRPOINT(p, KTR_STRUCT))
> - ktrevent(p, kq->kq_kev, nkev);
> + ktrevent(p, kev, nkev);
> #endif
> - error = copyout(kq->kq_kev, ulistp,
> + error = copyout(kev, ulistp,
> sizeof(struct kevent) * nkev);
> ulistp += nkev;
> nkev = 0;
> - kevp = kq->kq_kev;
> + kevp = &kev[0];
> s = splhigh();
> if (error)
> break;
> @@ -823,9 +825,9 @@ done:
> if (nkev != 0) {
> #ifdef KTRACE
> if (KTRPOINT(p, KTR_STRUCT))
> - ktrevent(p, kq->kq_kev, nkev);
> + ktrevent(p, kev, nkev);
> #endif
> - error = copyout(kq->kq_kev, ulistp,
> + error = copyout(kev, ulistp,
> sizeof(struct kevent) * nkev);
> }
> *retval = maxevents - count;
> Index: sys/eventvar.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/eventvar.h,v
> retrieving revision 1.3
> diff -u -p -r1.3 eventvar.h
> --- sys/eventvar.h 25 Mar 2012 20:33:52 -0000 1.3
> +++ sys/eventvar.h 9 Oct 2017 09:02:48 -0000
> @@ -44,7 +44,6 @@ struct kqueue {
> #define KQ_SEL 0x01
> #define KQ_SLEEP 0x02
> #define KQ_DYING 0x04
> - struct kevent kq_kev[KQ_NEVENTS];
> };
>
> #endif /* !_SYS_EVENTVAR_H_ */
>
>