> Date: Mon, 9 Oct 2017 11:48:56 +0200 > From: Martin Pieuchot <m...@openbsd.org> > > 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_ */ > >